O2O地图应用之判断用户订单地址是否在服务范围内
O2O地图应用之判断用户订单地址是否在服务范围内
需求分析
在o2o项目中,经常要用到在用户下单时判断用户所填地址的坐标点是否在服务范围内的情况,这里参考网上的实现方式,用C#来实现,经测试后有效,特此记录。
代码
public class MapHelper
{
/// <summary>
/// 判断一个坐标点在多边形坐标点的内部还是外部
/// </summary>
/// <param name="point">要判断的坐标点</param>
/// <param name="pts">多边形坐标点集合</param>
/// <returns></returns>
public static bool IsPointInPolygon(Point point, List<Point> pts)
{
int N = pts.Count;
//如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
bool boundOrVertex = true;
//经过点的次数
int intersectCount = 0;
double precision = 2e-10;
Point p1, p2;
Point p = point;//当前点
p1 = pts[0];
for (int i = 1; i <= N; i++)
{
//如果点在多边形上
if (p.Equals(p1))
{
return boundOrVertex;
}
p2 = pts[(i % N)];
if (p.Lng<Math.Min(p1.Lng,p2.Lng)||p.Lng>Math.Max(p1.Lng,p2.Lng))
{
p1 = p2;
continue;
}
if (p.Lng>Math.Min(p1.Lng,p2.Lng)&&p.Lng<Math.Max(p1.Lng,p2.Lng))
{
if (p.Lat<=Math.Max(p1.Lat,p2.Lat))
{
if (p1.Lng==p2.Lng&&p.Lat>=Math.Min(p1.Lat,p2.Lat))
{
return boundOrVertex;
}
if (p1.Lat==p2.Lat)
{
if (p1.Lat==p.Lat)
{
return boundOrVertex;
}
else
{
intersectCount++;
}
}
else
{
double xinters = (p.Lng - p1.Lng) * (p2.Lat - p1.Lat) / (p2.Lng - p1.Lng) + p1.Lat;
if (Math.Abs(p.Lat-xinters)<precision)
{
return boundOrVertex;
}
if (p.Lat<xinters)
{
intersectCount++;
}
}
}
}
else
{
if (p.Lng==p2.Lng&&p.Lat<=p2.Lat)
{
Point p3 = pts[(i+1)%N];
if (p.Lng>=Math.Min(p1.Lng,p3.Lng)&&p.Lng<=Math.Max(p1.Lng,p3.Lng))
{
intersectCount++;
}
else
{
intersectCount += 2;
}
}
}
p1 = p2;
}
if (intersectCount%2==0)
{
//偶数在多边形外
return false;
}
else
{
//奇数在多边形内
return true;
}
}
}
public class Point
{
/// <summary>
/// 经度
/// </summary>
public double Lng { get; set; }
/// <summary>
/// 纬度
/// </summary>
public double Lat { get; set; }
}
测试
这里我用高德地图标出了北京五环范围的坐标点集合,然后随意选择一个坐标点来进行判断:
坐标点可以用这个工具来获取:高德地图API
五环范围:
- 香泉桥 116.222208,39.992436
- 箭亭桥 116.327147,40.02046
- 上清桥 116.353948,40.02299
- 顾家庄桥 116.44128,40.020526
- 东北五环 116.48441,40.013624
- 平房桥 116.541101,39.942393
- 东南五环 116.549202,39.851595
- 旧宫新桥 116.43082,39.785968
- 狼垈东桥 116.296044,39.777442
- 宛平桥 116.225062,39.845517
- 衙门口桥 116.211308,39.894396
- 西五环 116.212595,39.944705
随机坐标:
- 林萃桥地铁站 116.37297,40.021857
- 望京西园四区 116.47086,39.99648
- 观音禅寺 116.533811,39.880533
- 俏狐国际 116.299713,39.772619
- 芳园里小区 116.416336,39.78394
- 润枫锦尚小区 116.429039,39.790535
class Program
{
static void Main(string[] args)
{
var Plist = new List<Point> {
new Point {Lng=116.222208,Lat= 39.992436},
new Point {Lng=116.327147,Lat= 40.02046},
new Point {Lng=116.353948,Lat= 40.02299},
new Point {Lng=116.44128,Lat= 40.020526},
new Point {Lng=116.48441,Lat=40.013624 },
new Point {Lng=116.541101,Lat= 39.942393},
new Point {Lng=116.549202,Lat= 39.851595},
new Point {Lng=116.43082,Lat=39.785968},
new Point {Lng=116.296044,Lat=39.777442 },
new Point {Lng=116.225062,Lat=39.845517 },
new Point {Lng=116.211308,Lat= 39.894396},
new Point {Lng=116.212595,Lat=39.944705}
};
//var p = new Point { Lng = 116.37297, Lat = 40.021857 };
//林萃桥地铁站 内
//var p = new Point { Lng = 116.47086, Lat = 39.99648 };
//望京西园四区 内
//var p = new Point { Lng = 116.533811, Lat = 39.880533 };
//观音禅寺 内
//var p = new Point { Lng = 116.299713, Lat = 39.772619 };
//俏狐国际 外
//var p = new Point { Lng = 116.416336, Lat = 39.78394 };
//芳园里小区 外
var p = new Point { Lng = 116.429039, Lat = 39.790535 };
//润枫锦尚小区 内
bool isin = MapHelper.IsPointInPolygon(p, Plist);
if (isin)
{
Console.WriteLine("随机点在五环范围内,可以派单");
}
else
{
Console.WriteLine("随机点不在五环范围内");
}
Console.ReadKey();
}
}
总结
- 北京的五环范围毕竟不是一个规则的多边形,可以尽量选择有标志性的坐标点来规范多边形
- 参考自:百度地图——判断用户是否在配送范围内解决方案 - aheizi - 博客园
O2O地图应用之判断用户订单地址是否在服务范围内的更多相关文章
- 判断一个IP地址是否是本局域网内地址
// /// <summary> /// 判断一个IP地址是否是本局域网内地址,是返回true 否则返回false, /// </summa ...
- 百度地图WEB端判断用户是否在网格范围内
在pc端设置商家的配送范围,用户在下单时,根据用户设置的配送地点判断是否在可配送范围内,并给用户相应的提示. 下面说下我的实现思路: 1.用百度地图在PC端设置配送范围,可拖拽选择 2.根据用户设置的 ...
- 判断IP地址是否在指定范围内的方法
比如给定一个ip段:127.0.0.1 ~ 127.0.0.255,我们想判断一个给定的ip地址是否在此段内,可以先将ip地址转换成整数,然后整数比较大小就很容易了. 例如: 127.0.0.1 = ...
- PHP中获取内网用户MAC地址(WINDOWS/linux)的实现代码
做一个内网根据MAC地址自动登录的应用,在WINDOW 2003可以正常使用,函数如下 复制代码 代码如下: function ce_getmac() { if(PHP_OS == 'WINNT' ...
- Android 判断用户2G/3G/4G移动数据网络
Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...
- C#判断用户是否使用微信浏览器,并据此来显示真实内容或二维码
平时我们看一些网页的时候会发现这样的功能:有的页面只能在微信里访问,如果在电脑上访问就只显示当前地址的二维码.这个用C#怎么实现呢?我们结合代码来看看. 首先,我们需要先判断用户使用的是什么浏览器,这 ...
- JavaScript 判断用户输入的邮箱及手机格式是否正确
JavaScript判断用户输入的邮箱格式是否正确.判断用户输入的手机号格式是否正确,下面有个不错的示例,感兴趣的朋友可以参考下. 复制代码代码如下: /* * 功能:判断用户输入的邮箱格式是否正确 ...
- c语言判断用户是否输入-非阻塞函数kbhit
一.基础研究 要从地址读取数据,肯定是要定义一个指针变量p,用它来实现变换地址和取值的功能.另外程序是当两个条件中的某一个出现时才停止,所以应该用while~do循环语句循环输出n和d,并用while ...
- 【百度地图API】让用户选择起点和终点的驾车导航
原文:[百度地图API]让用户选择起点和终点的驾车导航 摘要: 如果用户搜索“从机场到火车站”,使用驾车导航DrivingRoute会默认显示一条结果.但同一个城市可能有多个机场和火车站,那么,如何用 ...
随机推荐
- tomcat提供文件下载
引用两篇博客:http://blog.csdn.net/yuan882696yan/article/details/26680253 http://www.cnblogs.com/shenliang1 ...
- javascript之观码说理
前一阶段看到大神在网上贴出的测试个人js理解的代码. 在此我在此借用大神的代码,进行自我复述,大神文章参见:http://www.imooc.com/article/1731 代码1: functio ...
- Virtualbox修改bios信息安装Windows XP OEM
转载 http://hi.baidu.com/guoyao11/item/631ad6eb4fb3d93887d9de11 具体方法有两个: 1.把下面的代码复制改后缀为BAT文件直接运行即可,以Le ...
- 第91讲:Akka第一个案例动手实战架构设计
我们来看一下Akka的一个简单的wordcount的案例架构设计 从图中我们可以看出,不同的行我们是交给不同的actor进行入理的,每行首先进行map操作,识别出每个单词,然后交给reduce步骤的a ...
- EasyCriteria 3.0 发布
EasyCriteria 3.0 发布了,这是一个全新的版本,进行了大量的重构.官方发行说明请看:http://uaihebert.com/?p=1898 EasyCriteria 是一个轻量级的框架 ...
- 20 个免费的 Bootstrap 的后台管理模板
之前 OSC 曾经发过多个后台管理界面模板的推荐,例如: 50 个漂亮的后台管理界面模板 25 个精美的后台管理界面模板和布局 分享 6 套超酷的后台管理员界面网站模板 30个优秀的后台管理界面设计案 ...
- Session为null无法访问
我们在一般处理程序中需要访问Session为null 无法访问和操作 处理方案: 1.导入命名空间 System.Web.SessionState 2.实现IRequiresSessionState ...
- Ora-01536:超出了表空间users的空间限量(转)
Ora-01536:超出了表空间users的空间限量(转) 正在开会,同事跑过来说数据库有问题,通讯程序不能入库,赶快获取一条insert into a values()语句后在toad工具中手动插入 ...
- .net 架构师/经理招聘,长期有效
岗位职责: 1.参与项目的需求分析和业务评审 2.负责项目的技术架构: 3.负责指导开发小组完成开发以及单元测试: 4.负责解决开发人员的技术问题,并对开发人员的代码进行Review. 任职要求: 1 ...
- kali Linux系列教程之BeFF安装与集成Metasploit
kali Linux系列教程之BeFF安装与集成Metasploit 文/玄魂 kali Linux系列教程之BeFF安装与集成Metasploit 1.1 apt-get安装方式 1.2 启动 1. ...