国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

百度地圖PC端判斷用戶是否在配送范圍內

2020-07-26 03:28:58
字體:
來源:轉載
供稿:網友

最近接了個項目,其中有項目需求是這樣的:

在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類型存在一個標簽里面,以待后續的表單提交操作。

二、判斷點是否在范圍內

去網上看了一下,判斷點是否在配送范圍內的方法很多,大概采用的是射線法。
 但是有一些方法沒有考慮全面,導致有的情況判斷不夠準確。
 在百度地圖的GeoUtils里面找到了“判斷點是否多邊形內”這個方法。
 因為我是需要在后端做判斷,然后直接把js轉化成了java,測試百發百中,欣喜!(后面附上測試方法)

 /** * 判斷點是否在多邊形內 * @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; //如果點位于多邊形的頂點或邊上,也算做點在多邊形內,直接返回true  int intersectCount = 0;//cross points count of x   double precision = 2e-10; //浮點類型計算時候與0比較時候的容差  Point2D.Double p1, p2;//neighbour bound vertices  Point2D.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 ray          return boundOrVertex;        }        if(p1.y == p2.y){//ray is vertical                      if(p1.y == p.y){//overlies on a vertical ray            return 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 ray            return 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(); //開啟縮放平滑  //初始化為多邊形1  polygon1();  //生成多邊形1  function 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);  }  //生成多邊形2  function 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很全,而且都配有demo,非常利于我們開發者。

以上內容是針對百度地圖PC端判斷用戶是否在配送范圍內的相關知識,希望對大家有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凤阳县| 郴州市| 驻马店市| 长垣县| 忻州市| 涟源市| 祁门县| 肥东县| 沁源县| 田东县| 盐亭县| 新源县| 文安县| 新晃| 施甸县| 金川县| 合水县| 南川市| 肥东县| 招远市| 黔东| 南城县| 随州市| 措美县| 杭锦后旗| 东安县| 湄潭县| 邵阳县| 大宁县| 慈溪市| 桃园县| 岱山县| 法库县| 平陆县| 北流市| 麦盖提县| 松阳县| 辽源市| 通河县| 江陵县| 江陵县|