需求:

在pc端设置商家的配送范围,用户在下单时,根据用户设置的配送地点判断是否在可配送范围内,并给用户相应的提示。

实现:

1.用百度地图在PC端设置配送范围,可拖拽选择
2.根据用户设置的配送地址判断是否在配送范围内

一、百度地图PC端获取范围

改动百度地图官网的demo,设置配送范围。
思路:获取多边形的顶点,以json的形式保存到数据库。
百度API关于多边形覆盖物

构造函数:
Polygon(points:Array<Point>[, opts:PolygonOptions]) 创建多边形覆盖物
方法:
setPath(path:Array<Point>)  none    设置多边型的点数组(自1.2新增)
getPath()   Array<Point>    返回多边型的点数组(自1.2新增)

实现

主要代码:

//设置配送范围
function setRange(_point, _ppoints){var polygon = new BMap.Polygon(_ppoints, {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5});  //创建多边形map.addOverlay(polygon);   //增加多边形polygon.enableEditing();   //允许编辑polygon.addEventListener("lineupdate",function(e){var rangeArr = polygon.getPath();$("#distributeRange").val(JSON.stringify(rangeArr));});
}

以上代码主要是监听lineupdate事件,每一次拖拽百度地图回调函数将返回的多边形的顶点,然后通过JSON.stringify方法转为string类型存在一个标签里面,以待后续的表单提交操作。

二、判断点是否在范围内

判断点是否在配送范围内的方法很多,这里采用射线法。
根据射线与多边形的交点的个数来判断是否在多边形内部。
talk is cheap show me the code:

/*** 判断点是否在多边形内* @param point 检测点* @param pts   多边形的顶点* @return      点在多边形内返回true,否则返回false*/
public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){int N = pts.size();boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回trueint intersectCount = 0;//cross points count of x double precision = 2e-10; //浮点类型计算时候与0比较时候的容差Point2D.Double p1, p2;//neighbour bound verticesPoint2D.Double p = point; //当前点p1 = pts.get(0);//left vertex        for(int i = 1; i <= N; ++i){//check all rays            if(p.equals(p1)){return boundOrVertex;//p is an vertex}p2 = pts.get(i % N);//right vertex            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests                p1 = p2; continue;//next ray left point}if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of)if(p.y <= Math.max(p1.y, p2.y)){//x is before of ray                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal rayreturn boundOrVertex;}if(p1.y == p2.y){//ray is vertical                        if(p1.y == p.y){//overlies on a vertical rayreturn boundOrVertex;}else{//before ray++intersectCount;} }else{//cross point on the left side                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y                        if(Math.abs(p.y - xinters) < precision){//overlies on a rayreturn boundOrVertex;}if(p.y < xinters){//before ray++intersectCount;} }}}else{//special case when ray is crossing through the vertex                if(p.x == p2.x && p.y <= p2.y){//p crossing over p2                    Point2D.Double p3 = pts.get((i+1) % N); //next vertex                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x++intersectCount;}else{intersectCount += 2;}}}            p1 = p2;//next ray left point}if(intersectCount % 2 == 0){//偶数在多边形外return false;} else { //奇数在多边形内return true;}}

三、测试

主要是判断和这个方法的可行性。
为此写了个测试方法。
思路:获取一个多边形的顶点,然后随机点一个点
1.调用百度地图的方法,判断该点是否在范围内
2.根据百度地图获取的那个店的经纬度,自己程序判断是否在范围内
调用百度地图的方法:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>GeoUtils示例</title><script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script><script type="text/javascript" src="http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js"></script><style type="text/css">table {font-size: 14px;}</style>
</head><body><div style="float:left;width:600px;height:500px;border:1px solid gray" id="container"></div><div style="float:left;width:300px;height:500px;border:1px solid gray" id="control"><table style="width:100%;"><tr><td colspan="2">判断点是否在多边形内:</td></tr><tr><td><input type="button" value="多边形1" onclick="polygon1()" /></td></tr><tr><td><input type="button" value="多边形2" onclick="polygon2()" /></td></tr><tr><td>经度<input type="text" value="" id="lng"></td></tr><tr><td>纬度<input type="text" value="" id="lat"></td></tr><tr><td>结果:</td></tr><tr><td><p id="result" style="color:red"></p></td></tr><table></div>
</body></html>
<script type="text/javascript">var map = new BMap.Map("container");var pt = new BMap.Point(116.404, 39.915);var mkr = new BMap.Marker(pt);var ply;  //多边形map.centerAndZoom(pt, 16);map.enableScrollWheelZoom(); //开启滚动缩放map.enableContinuousZoom(); //开启缩放平滑//初始化为多边形1polygon1();//生成多边形1function polygon1() {var pts = [];var pt1 = new BMap.Point(116.395, 39.910);var pt2 = new BMap.Point(116.394, 39.914);var pt3 = new BMap.Point(116.403, 39.920);var pt4 = new BMap.Point(116.402, 39.914);var pt5 = new BMap.Point(116.410, 39.913);pts.push(pt1);pts.push(pt2);pts.push(pt3);pts.push(pt4);pts.push(pt5);ply = new BMap.Polygon(pts);//演示:将面添加到地图上map.clearOverlays();map.addOverlay(ply);}//生成多边形2function polygon2() {var pts = [];var pt1 = new BMap.Point(116.395, 39.910);var pt2 = new BMap.Point(116.394, 39.914);var pt3 = new BMap.Point(116.396, 39.919);var pt4 = new BMap.Point(116.406, 39.920);var pt5 = new BMap.Point(116.410, 39.913);pts.push(pt1);pts.push(pt2);pts.push(pt3);pts.push(pt4);pts.push(pt5);ply = new BMap.Polygon(pts);//演示:将多边形添加到地图上map.clearOverlays();map.addOverlay(ply);}map.addEventListener("click", function (e) {mkr.setPosition(e.point);map.addOverlay(mkr);//将点击的点的坐标显示在页面上document.getElementById("lng").value = e.point.lng;document.getElementById("lat").value = e.point.lat;InOrOutPolygon(e.point.lng, e.point.lat);});function InOrOutPolygon(lng, lat){var pt = new BMap.Point(lng, lat);var result = BMapLib.GeoUtils.isPointInPolygon(pt, ply);if (result == true) {document.getElementById("result").innerHTML = "点在多边形内";} else {document.getElementById("result").innerHTML = "点在多边形外";}}</script>

界面如下:

在页面上点击一个点后,获取了该点的坐标(用于自己的方法测试),并调用了InOrOutPolygon来判断了该店是否在此范围内。

后台的测试方法:

// 测试一个点是否在多边形内
public static void main(String[] args) {Point2D.Double point = new Point2D.Double(116.404072, 39.916605);List<Point2D.Double> pts = new ArrayList<Point2D.Double>();pts.add(new Point2D.Double(116.395, 39.910));pts.add(new Point2D.Double(116.394, 39.914));pts.add(new Point2D.Double(116.403, 39.920));pts.add(new Point2D.Double(116.402, 39.914));pts.add(new Point2D.Double(116.410, 39.913));if(IsPtInPoly(point, pts)){System.out.println("点在多边形内");}else{System.out.println("点在多边形外");}
}

经过测试,结果满意。
总结,实现的过程最重要是保存那些顶点,并根据那些保存的顶点(有一定的顺序),来判断一个点是否在这些顶点围成的多边形内。
在此赞一下百度地图,提供的API很全,很好用。

转载于:https://www.cnblogs.com/aheizi/p/5162992.html

百度地图——判断用户是否在配送范围内解决方案相关推荐

  1. 百度地图——判断一个点是否在一个区域内?

    由于目前的一个项目涉及离线地图,经过查找资料论证,最终还是决定采用百度地图.在项目过程中,遇到一个比较实际的问题:怎么判断地图上的一个点(经纬坐标下)在一个多边形区域内? 由于我采用的是百度地图Jav ...

  2. 百度地图 在用户输入的省市区范围内进行关键字智能提示搜索

    现在进行表单输入地址的时候分为省市区和详细地址,省市区用citypicker插件可以轻松完成,但是输入详细地址的时候要调用百度API进行关键字智能提示,那么问题来了,如何在用户输入的省市区内进行关键字 ...

  3. 百度地图让用户“私人定制“:一场语音定制背后的AI能力强势输出

    百度地图更新了. 对于一款互联网产品,尤其是国民级的移动应用,显然再正常不过.但如果细看此版本更新的主要功能,大概率还是会让你眼前一亮. 这不,在国庆节前夕,百度地图重磅推出"语音定制功能& ...

  4. Vue 移动端项目 百度地图 点击事件无效、不触发 解决方案

    解决百度地图 手机端 点击事件不触发 的一种方案 版权声明:本文为博主原创文章,转载请标明原文出处.  问题背景 我是半路接手的这个项目,该项目使用 Vue 开发的一款 手机端的页面.到手里时,使用百 ...

  5. 百度地图android兼容,Android百度地图SDK无法支持64位平台完美解决方案

    首先强调下,百度地图早已经处理了对64位平台的支持,而且现在很多手机都用64位处理器了,而且很多应用使用百度地图sdk都没有问题,那么问题就是我们没有使用好百度地图了. 最近开发项目时候遇到一个问题, ...

  6. 百度地图测距 java_java 百度地图判断两点距离1

    package baiduApi; /** * 类名称:PointToDistance * 类描述:两个百度经纬度坐标点,计算两点距离 * 创建人:钟志铖 * 创建时间:2014-9-7 上午10:1 ...

  7. 百度地图开发自定义信息窗口openInfoWindow样式的解决方案

    1.InfoWindow的样式,百度是没用提供直接使用的样式表的,目前都是热心网友在实际开发中自己的经验和实战总结: 2.百度提供了InfoBox富文本标签弹出框的接口,引入InfoBox.js,即可 ...

  8. 高德地图 判断打的点是否在圈内

    代码片 // An highlighted blockvar circle = new AMap.Circle({center: new AMap.LngLat(q, p),// 圆心位置radius ...

  9. 【百度地图API·javascriptapi】地图定位、创建自定义图标、获取用户点击位置

    引言 地图在网页上的应用远不止于展示,我们可以借助百度地图定位用户的当前位置,在地图上创建自定义的标记,或者在用户点击地图的时候,获取用户点击位置的经纬度. 定位 百度地图给用户提供了专门的定位api ...

最新文章

  1. 【漫画】以后在有面试官问你AVL树,你就把这篇文章扔给他。
  2. 嵌入式C语言查表法的项目应用
  3. Win7安装64位CentOS 6.4双系统详细过程
  4. 【Machine Learning】KNN学习算法与C语言实现
  5. OpenFOAM流固耦合问题-FsiFoam(foam-extend-4.0)运行tutorials的bug修复
  6. seqlist插入java_大话数据结构(五)(java程序)——顺序存储结构的插入与删除...
  7. c语言斐波那契数列_剑指Offer-10-I.斐波那契数列
  8. Linux彻底删除mysql
  9. 301与302页面重定向
  10. GitHub 的 Pull Request
  11. jmeter获取毫秒时间戳
  12. sqlyog注册码激活
  13. php生成mp4文件,PHP实现将视频转成MP4并获取视频预览图的方法
  14. 通过access口加vlan标签吗_如何理解:“Access端口加入的VLAN必须已经存在并且不能是VLAN 1;Hybrid端口加入的VLAN必须已经存在;Trun...
  15. UML在软件工程中的使用 建模—类图
  16. JAVA中GUI在Button中设置中文乱码问题
  17. Ac质量问题相关答疑
  18. 复制微信号并跳转到微信界面
  19. excel取消密码_取消excel工作簿的保护(无密码)
  20. 记录女士出差一周必备物品清单用哪个便签比较好

热门文章

  1. 二叉树的应用 表达式处理_【每日编程208期】2018年408应用题41题
  2. RTP发送和接收(有图为证)
  3. 数据结构迷宫代码_数据结构课程设计——迷宫求解(二)
  4. 软件开发技术文档_你知道,直播软件开发需要做的准备工作有哪些?
  5. 我的内核学习笔记9:Intel内部看门狗iTCO_wdt驱动
  6. [学习备忘录]编译gdb及gdbserver
  7. 【java】java 定时任务线程池 ScheduledThreadPoolExecutor 源码阅读
  8. 【java】String 类型真是不可变的吗
  9. 【Flink】Flink CancellationException null DefaultExecutionGraphCache LeaderRetrievalHandler
  10. 【算法】剑指 Offer 46. 把数字翻译成字符串