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会默认显示一条结果.但同一个城市可能有多个机场和火车站,那么,如何用 ...
随机推荐
- 国内从事GIS行业的公司及其网址
www.esrichina-bj.cn esri中国北京http://www.lingtu.com/ 北京灵图软件技术有限公司(三维gis) http://www.spatialport.com.cn ...
- LightOJ1027 A Dangerous Maze(期望)
题目大概说你正在起点,面前有$n$个门,每个门有一个数字$x$,正数表示开这个门$x$分钟后会出去,负数表示开这个门$-x$分钟后会回到起点.选择门的概率是一样的且每次选择互不影响.问出去的时间期望是 ...
- SQL到NOSQL的思维转变
NOSQL系统一般都会宣传一个特性,那就是性能好,然后为什么呢?关系型数据库发展了这么多年,各种优化工作已经做得很深了,NOSQL系统一般都是吸收关系型数据库的技术,然后,到底是什么因素束缚了关系型数 ...
- [ASE][Daily Scrum]11.25
View Shilin Liu 修复现有的bug,子弹无法破坏射程内视野外的墙 Yiming Liao 无法看见从视野外到视野内的子弹 Server Songtao He 服务器处理子弹命中t ...
- Oracle必须死之奇怪的ORA-06502错误
作为熟练.Net码农以及非熟练Oracle用户很多时候Oracle总给我一种这货就是存心恶心我们的感觉. 虽然不得不承认Oracle是个很(an)好(gui)的产品,但是总有那么好几下被恶心到了.比如 ...
- 分享一下SQLSERVER技术交流QQ群里的群共享资源
分享一下SQLSERVER技术交流QQ群里的群共享资源 SQLSERVER技术交流QQ群已经开了一段时间了,人数已经有了100多号人, 而群里面很多SQLSERVER爱好者上传了他们宝贵的SQLSER ...
- 设计模式之美:Singleton(单件)
索引 意图 结构 参与者 适用性 缺点 效果 相关模式 实现 实现方式(一):使用 Static 变量初始化 Singleton. 实现方式(二):使用 Lazy Initialization 来实现 ...
- [MSSQL2012]LEAD函数
LEAD函数简单点说,就是把下一行的某列数据提取到当前行来显示,看示例更能解释清楚,先看测试用脚本 DECLARE @TestData TABLE( ID INT IDENTITY(1,1), ...
- 微软BI 之SSIS 系列 - 使用 Script Component Destination 和 ADO.NET 解析不规则文件并插入数据
开篇介绍 这一篇文章是 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧 的续篇,在上篇文章中介绍到了对于这种不规则文件输出的处理方式.比如下图中 ...
- IE11下Forms身份认证无法保存Cookie的问题
ASP.NET中使用Forms身份认证常见的做法如下: 1. 网站根目录下的Web.config添加authentication节点 <authentication mode="For ...