美文网首页地图
百度地图API(3):判断地图上的点是否在 圆形 多边形 区域内

百度地图API(3):判断地图上的点是否在 圆形 多边形 区域内

作者: 回忆不死我们不散 | 来源:发表于2020-03-28 14:20 被阅读0次

    **首先提供一个百度地图API官方的GeoUtils.js **

    直接调用即可

      /**
       * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、
       * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。 
       * 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,
       * 基于Baidu Map API 1.2。
       *
       * @author Baidu Map Api Group 
       * @version 1.2
       */
    
     /** 
      * @namespace BMap的所有library类均放在BMapLib命名空间下
      */
     var BMapLib = window.BMapLib = BMapLib || {};
     (function() { 
    
         /**
          * 地球半径
          */
         var EARTHRADIUS = 6370996.81; 
    
         /** 
          * @exports GeoUtils as BMapLib.GeoUtils 
          */
         var GeoUtils =
         /**
          * GeoUtils类,静态类,勿需实例化即可使用
          * @class GeoUtils类的<b>入口</b>。
          * 该类提供的都是静态方法,勿需实例化即可使用。     
          */
         BMapLib.GeoUtils = function(){
    
         }
    
         /**
          * 判断点是否在矩形内
          * @param {Point} point 点对象
          * @param {Bounds} bounds 矩形边界对象
          * @returns {Boolean} 点在矩形内返回true,否则返回false
          */
         GeoUtils.isPointInRect = function(point, bounds){
             //检查类型是否正确
             if (!(point instanceof BMap.Point) || 
                 !(bounds instanceof BMap.Bounds)) {
                 return false;
             }
             var sw = bounds.getSouthWest(); //西南脚点
             var ne = bounds.getNorthEast(); //东北脚点
             return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);
         }
    
         /**
          * 判断点是否在圆形内
          * @param {Point} point 点对象
          * @param {Circle} circle 圆形对象
          * @returns {Boolean} 点在圆形内返回true,否则返回false
          */
         GeoUtils.isPointInCircle = function(point, circle){
         
             //检查类型是否正确
             if (!(point instanceof BMap.Point) || 
                 !(circle instanceof BMap.Circle)) {
                 return false;
             }
             //point与圆心距离小于圆形半径,则点在圆内,否则在圆外
             var c = circle.getCenter();
             var r = circle.getRadius();
    
             var dis = GeoUtils.getDistance(point, c);
             if(dis <= r){
                 return true;
             } else {
                 return false;
             }
         }
    
         /**
          * 判断点是否在折线上
          * @param {Point} point 点对象
          * @param {Polyline} polyline 折线对象
          * @returns {Boolean} 点在折线上返回true,否则返回false
          */
         GeoUtils.isPointOnPolyline = function(point, polyline){
             //检查类型
             if(!(point instanceof BMap.Point) ||
                 !(polyline instanceof BMap.Polyline)){
                 return false;
             }
    
             //首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false
             var lineBounds = polyline.getBounds();
             if(!this.isPointInRect(point, lineBounds)){
                 return false;
             }
    
             //判断点是否在线段上,设点为Q,线段为P1P2 ,
             //判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内
             var pts = polyline.getPath();
             for(var i = 0; i < pts.length - 1; i++){
                var curPt = pts[i];
                var nextPt = pts[i + 1];
                //首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内
                if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&
                    point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)){
                    //判断点是否在直线上公式
                    var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) - 
                        (nextPt.lng - point.lng) * (curPt.lat - point.lat);                
                    if(precision < 2e-10 && precision > -2e-10){//实质判断是否接近0
                        return true;
                    }                
                }
            }
    
            return false;
        }
    
        /**
         * 判断点是否多边形内
         * @param {Point} point 点对象
         * @param {Polyline} polygon 多边形对象
         * @returns {Boolean} 点在多边形内返回true,否则返回false
         */
        GeoUtils.isPointInPolygon = function(point, polygon){
    
    
            //检查类型
            if(!(point instanceof BMap.Point) ||
                !(polygon instanceof BMap.Polygon)){
    
                return false;
            }
    
            //首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false
    
            var polygonBounds = polygon.getBounds();
            if(!this.isPointInRect(point, polygonBounds)){
                return false;
            }
            var pts = polygon.getPath();//获取多边形点
    
    
            //下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改
            //基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
            //在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
    
            var N = pts.length;
            var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
            var intersectCount = 0;//cross points count of x 
            var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
            var p1, p2;//neighbour bound vertices
            var p = point; //测试点
    
    
            p1 = pts[0];//left vertex        
            for(var i = 1; i <= N; ++i){//check all rays            
                if(p.equals(p1)){
                    return boundOrVertex;//p is an vertex
                }
    
                p2 = pts[i % N];//right vertex            
                if(p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)){//ray is outside of our interests                
                    p1 = p2; 
                    continue;//next ray left point
                }
    
                if(p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)){//ray is crossing over by the algorithm (common part of)
                    if(p.lng <= Math.max(p1.lng, p2.lng)){//x is before of ray                    
                        if(p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)){//overlies on a horizontal ray
                            return boundOrVertex;
                        }
    
                        if(p1.lng == p2.lng){//ray is vertical                        
                            if(p1.lng == p.lng){//overlies on a vertical ray
                                return boundOrVertex;
                            }else{//before ray
                                ++intersectCount;
                            } 
                        }else{//cross point on the left side                        
                            var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng;//cross point of lng                        
                            if(Math.abs(p.lng - xinters) < precision){//overlies on a ray
                                return boundOrVertex;
                            }
    
                            if(p.lng < xinters){//before ray
                                ++intersectCount;
                            } 
                        }
                    }
                }else{//special case when ray is crossing through the vertex                
                    if(p.lat == p2.lat && p.lng <= p2.lng){//p crossing over p2                    
                        var p3 = pts[(i+1) % N]; //next vertex                    
                        if(p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)){//p.lat lies between p1.lat & p3.lat
                            ++intersectCount;
                        }else{
                            intersectCount += 2;
                        }
                    }
                }            
                p1 = p2;//next ray left point
            }
            if(intersectCount % 2 == 0){//偶数在多边形外
                return false;
            } else { //奇数在多边形内
                return true;
            }            
        }
    
        /**
         * 将度转化为弧度
         * @param {degree} Number 度     
         * @returns {Number} 弧度
         */
        GeoUtils.degreeToRad =  function(degree){
            return Math.PI * degree/180;    
        }
    
        /**
         * 将弧度转化为度
         * @param {radian} Number 弧度     
         * @returns {Number} 度
         */
        GeoUtils.radToDegree = function(rad){
            return (180 * rad) / Math.PI;       
        }
    
        /**
         * 将v值限定在a,b之间,纬度使用
         */
        function _getRange(v, a, b){
            if(a != null){
              v = Math.max(v, a);
            }
            if(b != null){
              v = Math.min(v, b);
            }
            return v;
        }
    
        /**
         * 将v值限定在a,b之间,经度使用
         */
        function _getLoop(v, a, b){
            while( v > b){
              v -= b - a
            }
            while(v < a){
              v += b - a
            }
            return v;
        }
    
        /**
         * 计算两点之间的距离,两点坐标必须为经纬度
         * @param {point1} Point 点对象
         * @param {point2} Point 点对象
         * @returns {Number} 两点之间距离,单位为米
         */
        GeoUtils.getDistance = function(point1, point2){
            //判断类型
            if(!(point1 instanceof BMap.Point) ||
                !(point2 instanceof BMap.Point)){
                return 0;
            }
    
            point1.lng = _getLoop(point1.lng, -180, 180);
            point1.lat = _getRange(point1.lat, -74, 74);
            point2.lng = _getLoop(point2.lng, -180, 180);
            point2.lat = _getRange(point2.lat, -74, 74);
    
            var x1, x2, y1, y2;
            x1 = GeoUtils.degreeToRad(point1.lng);
            y1 = GeoUtils.degreeToRad(point1.lat);
            x2 = GeoUtils.degreeToRad(point2.lng);
            y2 = GeoUtils.degreeToRad(point2.lat);
    
            return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));    
        }
    
        /**
         * 计算折线或者点数组的长度
         * @param {Polyline|Array<Point>} polyline 折线对象或者点数组
         * @returns {Number} 折线或点数组对应的长度
         */
        GeoUtils.getPolylineDistance = function(polyline){
            //检查类型
            if(polyline instanceof BMap.Polyline || 
                polyline instanceof Array){
                //将polyline统一为数组
                var pts;
                if(polyline instanceof BMap.Polyline){
                    pts = polyline.getPath();
                } else {
                    pts = polyline;
                }
    
                if(pts.length < 2){//小于2个点,返回0
                    return 0;
                }
    
                //遍历所有线段将其相加,计算整条线段的长度
                var totalDis = 0;
                for(var i =0; i < pts.length - 1; i++){
                    var curPt = pts[i];
                    var nextPt = pts[i + 1]
                    var dis = GeoUtils.getDistance(curPt, nextPt);
                    totalDis += dis;
                }
    
                return totalDis;
    
            } else {
                return 0;
            }
        }
    
        /**
         * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积
         * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数组
         * @returns {Number} 多边形面或点数组构成图形的面积
         */
        GeoUtils.getPolygonArea = function(polygon){
            //检查类型
            if(!(polygon instanceof BMap.Polygon) &&
                !(polygon instanceof Array)){
                return 0;
            }
            var pts;
            if(polygon instanceof BMap.Polygon){
                pts = polygon.getPath();
            }else{
                pts = polygon;    
            }
    
            if(pts.length < 3){//小于3个顶点,不能构建面
                return 0;
            }
    
            var totalArea = 0;//初始化总面积
            var LowX = 0.0;
            var LowY = 0.0;
            var MiddleX = 0.0;
            var MiddleY = 0.0;
            var HighX = 0.0;
            var HighY = 0.0;
            var AM = 0.0;
            var BM = 0.0;
            var CM = 0.0;
            var AL = 0.0;
            var BL = 0.0;
            var CL = 0.0;
            var AH = 0.0;
            var BH = 0.0;
            var CH = 0.0;
            var CoefficientL = 0.0;
            var CoefficientH = 0.0;
            var ALtangent = 0.0;
            var BLtangent = 0.0;
            var CLtangent = 0.0;
            var AHtangent = 0.0;
            var BHtangent = 0.0;
            var CHtangent = 0.0;
            var ANormalLine = 0.0;
            var BNormalLine = 0.0;
            var CNormalLine = 0.0;
            var OrientationValue = 0.0;
            var AngleCos = 0.0;
            var Sum1 = 0.0;
            var Sum2 = 0.0;
            var Count2 = 0;
            var Count1 = 0;
            var Sum = 0.0;
            var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径 
            var Count = pts.length;        
            for (var i = 0; i < Count; i++) {
                if (i == 0) {
                    LowX = pts[Count - 1].lng * Math.PI / 180;
                    LowY = pts[Count - 1].lat * Math.PI / 180;
                    MiddleX = pts[0].lng * Math.PI / 180;
                    MiddleY = pts[0].lat * Math.PI / 180;
                    HighX = pts[1].lng * Math.PI / 180;
                    HighY = pts[1].lat * Math.PI / 180;
                }
                else if (i == Count - 1) {
                    LowX = pts[Count - 2].lng * Math.PI / 180;
                    LowY = pts[Count - 2].lat * Math.PI / 180;
                    MiddleX = pts[Count - 1].lng * Math.PI / 180;
                    MiddleY = pts[Count - 1].lat * Math.PI / 180;
                    HighX = pts[0].lng * Math.PI / 180;
                    HighY = pts[0].lat * Math.PI / 180;
                }
                else {
                    LowX = pts[i - 1].lng * Math.PI / 180;
                    LowY = pts[i - 1].lat * Math.PI / 180;
                    MiddleX = pts[i].lng * Math.PI / 180;
                    MiddleY = pts[i].lat * Math.PI / 180;
                    HighX = pts[i + 1].lng * Math.PI / 180;
                    HighY = pts[i + 1].lat * Math.PI / 180;
                }
                AM = Math.cos(MiddleY) * Math.cos(MiddleX);
                BM = Math.cos(MiddleY) * Math.sin(MiddleX);
                CM = Math.sin(MiddleY);
                AL = Math.cos(LowY) * Math.cos(LowX);
                BL = Math.cos(LowY) * Math.sin(LowX);
                CL = Math.sin(LowY);
                AH = Math.cos(HighY) * Math.cos(HighX);
                BH = Math.cos(HighY) * Math.sin(HighX);
                CH = Math.sin(HighY);
                CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
                CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);
                ALtangent = CoefficientL * AL - AM;
                BLtangent = CoefficientL * BL - BM;
                CLtangent = CoefficientL * CL - CM;
                AHtangent = CoefficientH * AH - AM;
                BHtangent = CoefficientH * BH - BM;
                CHtangent = CoefficientH * CH - CM;
                AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));
                AngleCos = Math.acos(AngleCos);            
                ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
                BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
                CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;
                if (AM != 0)
                    OrientationValue = ANormalLine / AM;
                else if (BM != 0)
                    OrientationValue = BNormalLine / BM;
                else
                    OrientationValue = CNormalLine / CM;
                if (OrientationValue > 0) {
                    Sum1 += AngleCos;
                    Count1++;
                }
                else {
                    Sum2 += AngleCos;
                    Count2++;
                }
            }        
            var tempSum1, tempSum2;
            tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);
            tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;
            if (Sum1 > Sum2) {
                if ((tempSum1 - (Count - 2) * Math.PI) < 1)
                    Sum = tempSum1;
                else
                    Sum = tempSum2;
            }
            else {
                if ((tempSum2 - (Count - 2) * Math.PI) < 1)
                    Sum = tempSum2;
                else
                    Sum = tempSum1;
            }
            totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;
    
            return totalArea; //返回总面积
        }
    
    })();//闭包结束
    

    使用方法核心代码:

    //创建一个圆(坐标自己填)
    var circle = new BMap.Circle(new BMap.Point(112.595384,26.904631),1000,{fillColor:"blue", strokeWeight: 1 ,fillOpacity: 0.3, strokeOpacity: 0.3});
    //创建一个点(坐标自己填)
     var point = new BMap.Point(112.595384,26.904631);    // 创建点坐标  
    //判断点是否在圆形区域内
    if(BMapLib.GeoUtils.isPointInCircle(point,circle)){
      alert("该point 在 circle内");
    }else
    {
       alert("该point 不在 circle内");
    }
    

    编码中遇到的问题:

    要注意Point和Circle 都必须是:BMap.Point和BMap.Bounds对象

    Tip:

    1. 官方js链接: http://api.map.baidu.com/library/GeoUtils/1.2/docs/symbols/src/BMapLib_GeoUtils.js.html
    2. 演示地址:圆形:http://www.ltbetter.com:8080/BMap/MapTest5.html
      多边形:http://www.ltbetter.com:8080/BMap/MapTest6.html
    3. 多边形,矩形类似,官方api都有相应的方法

    源代码 圆形:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
    body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZwQAeZO1fncN63zUmuYeGU7CLU0mpfdk"></script>
    <script type="text/javascript" src="GeoUtil.js"></script>
    
    
    <title>圆形区域判断</title>
    </head>
    <body>
    <div id="allmap"></div>
    </body>
    </html>
    <script type="text/javascript">
    //创建地图
    var map = new BMap.Map("allmap");  
    //创建一个圆
    var circle = new BMap.Circle(new BMap.Point(112.595384,26.904631),1000,{fillColor:"blue", strokeWeight: 1 ,fillOpacity: 0.3, strokeOpacity: 0.3});
    
     var point2s = [  
          new BMap.Point(112.586149,26.913201),  
          new BMap.Point(112.58464,26.909432),  
          new BMap.Point(112.585143,26.899219),  
          new BMap.Point(112.600953,26.898832),  
          new BMap.Point(112.607421,26.900572),  
          new BMap.Point(112.606631,26.904825),  
          new BMap.Point(112.606523,26.909142),  
          new BMap.Point(112.59772,26.909399),
          ];
    //创建标注点并添加到地图中
    function addMarker(points) {
        //循环建立标注点
        for(var i=0, pointsLen = points.length; i<pointsLen; i++) {
            var marker = new BMap.Marker(points[i]); //将点转化成标注点
            map.addOverlay(marker);  //将标注点添加到地图上
            //添加监听事件
            (function() {
                var thePoint = points[i];
                marker.addEventListener("click",
                    function() {
                    showInfo(this,thePoint);
                });
             })();  
        }
    }
    
    function showInfo(thisMarker,point) {
    
        //判断点是否在
        if(BMapLib.GeoUtils.isPointInCircle(point,circle)){
          var infoWindow = new BMap.InfoWindow("在圆形区域内");
          thisMarker.openInfoWindow(infoWindow); //图片加载完后重绘infoWindow
      }else
      {
         var infoWindow = new BMap.InfoWindow("不在圆形区域内");
          thisMarker.openInfoWindow(infoWindow); //图片加载完后重绘infoWindow
      }
    }
    
    
    function initialize() {  
        alert("点击标注点可以显示是否在区域内");
      // 百度地图API功能  
      map.addControl(new BMap.NavigationControl());               // 添加平移缩放控件  
      map.addControl(new BMap.ScaleControl());                    // 添加比例尺控件  
      map.addControl(new BMap.OverviewMapControl());              //添加缩略地图控件  
      map.enableScrollWheelZoom();                            //启用滚轮放大缩小  
      map.addControl(new BMap.MapTypeControl());          //添加地图类型控件  
    
        var point = new BMap.Point(112.595384,26.904631);    // 创建点坐标  
            map.centerAndZoom(point,15);                      // 初始化地图,设置中心点坐标和地图级别。  
            addMarker(point2s); 
      map.addOverlay(circle);
    }  
    
    initialize();
    
    </script>
    

    源代码 多边形

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
    body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZwQAeZO1fncN63zUmuYeGU7CLU0mpfdk"></script>
    <script type="text/javascript" src="GeoUtil.js"></script>
    
    
    <title>圆形区域判断</title>
    </head>
    <body>
    <div id="allmap"></div>
    </body>
    </html>
    <script type="text/javascript">
    //创建地图
    var map = new BMap.Map("allmap");  
    //创建一个多边形
    
    //创建多边形  
    var polygon2 = new BMap.Polygon([  
          new BMap.Point(112.579325,26.915291),  
          new BMap.Point(112.584967,26.899086),  
          new BMap.Point(112.608287,26.898023),  
          new BMap.Point(112.605035,26.90764),  
          new BMap.Point(112.602825,26.914356),  
          new BMap.Point(112.588254,26.909862),  
          ], {strokeColor:"#f50704",fillColor:"#cfcfcf", strokeWeight:5, strokeOpacity:0,fillOpacity:0,});  
    
     var point2s = [  
          new BMap.Point(112.586149,26.913201),  
          new BMap.Point(112.58464,26.909432),  
          new BMap.Point(112.585143,26.899219),  
          new BMap.Point(112.600953,26.898832),  
          new BMap.Point(112.607421,26.900572),  
          new BMap.Point(112.606631,26.904825),  
          new BMap.Point(112.606523,26.909142),  
          new BMap.Point(112.59772,26.909399),
          ];
    //创建标注点并添加到地图中
    function addMarker(points) {
        //循环建立标注点
        for(var i=0, pointsLen = points.length; i<pointsLen; i++) {
            var marker = new BMap.Marker(points[i]); //将点转化成标注点
            map.addOverlay(marker);  //将标注点添加到地图上
            //添加监听事件
            (function() {
                var thePoint = points[i];
                marker.addEventListener("click",
                    function() {
                    showInfo(this,thePoint);
                });
             })();  
        }
    }
    
    function showInfo(thisMarker,point) {
    
        //判断点是否在
        if(BMapLib.GeoUtils.isPointInPolygon(point,polygon2)){
          var infoWindow = new BMap.InfoWindow("在区域内");
          thisMarker.openInfoWindow(infoWindow); //图片加载完后重绘infoWindow
      }else
      {
         var infoWindow = new BMap.InfoWindow("不在区域内");
          thisMarker.openInfoWindow(infoWindow); //图片加载完后重绘infoWindow
      }
    }
    
    
    function initialize() {  
        alert("点击标注点可以显示是否在区域内");
      // 百度地图API功能  
      map.addControl(new BMap.NavigationControl());               // 添加平移缩放控件  
      map.addControl(new BMap.ScaleControl());                    // 添加比例尺控件  
      map.addControl(new BMap.OverviewMapControl());              //添加缩略地图控件  
      map.enableScrollWheelZoom();                            //启用滚轮放大缩小  
      map.addControl(new BMap.MapTypeControl());          //添加地图类型控件  
    
        var point = new BMap.Point(112.595384,26.904631);    // 创建点坐标  
            map.centerAndZoom(point,15);                      // 初始化地图,设置中心点坐标和地图级别。  
            addMarker(point2s); 
      map.addOverlay(polygon2);
    }  
    
    initialize();
    
    </script>
    

    转载自:https://www.jianshu.com/p/f808064addf2

    百度api: http://api.map.baidu.com/library/DrawingManager/1.4/docs/symbols/BMapLib.DrawingManager.html#constructor
    http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a3b14

    修改鼠标绘制点线面的工具https://www.cnblogs.com/ertingbo/p/8004297.html

    //实例化鼠标绘制工具
    var drawingManager = new BMapLib.DrawingManager(map, {
        isOpen: false, //是否开启绘制模式
        enableDrawingTool: true, //是否显示工具栏
        drawingToolOptions: {
            anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
            offset: new BMap.Size(20, 20), //偏离值
            /!* drawingModes : [BMAP_DRAWING_MARKER, BMAP_DRAWING_CIRCLE],*!/
            drawingModes : [BMAP_DRAWING_RECTANGLE,BMAP_DRAWING_CIRCLE], //设置只显示画矩形、圆的模式
    
            drawingTypes : [
                 BMAP_DRAWING_MARKER,//点的样式
                 BMAP_DRAWING_CIRCLE,//圆的样式
                 BMAP_DRAWING_POLYLINE,//线的样式
                 BMAP_DRAWING_POLYGON,//多边形的样式
                 BMAP_DRAWING_RECTANGLE //矩形的样式
             ]
        },
        circleOptions: styleOptions, //圆的样式
        polylineOptions: styleOptions, //线的样式
        polygonOptions: styleOptions, //多边形的样式
        rectangleOptions: styleOptions //矩形的样式
    });
    

    veu案例

    <script type="text/javascript" src="./static/js/GeoUtil.js"></script>
    官方js链接: [http://api.map.baidu.com/library/GeoUtils/1.2/docs/symbols/src/BMapLib_GeoUtils.js.html]

    <script type="text/javascript" src="//api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script>
    <link rel="stylesheet" href="//api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" />

    <template>
      <div class="center">
        <div id="allmap"></div>
      </div>
    </template>
    
    <script>
    export default {
      name: "HelloWorld",
      data() {
        return {
          meat_map:'',//地图event
          overlays:[],//画出的矩形的框
          polygon2 : [],//矩形点位
          polygon3:"",//矩形点位组成的百度数据
          //点位经纬度
          point2s : [
            new BMap.Point(120.80793,30.69376),  
            new BMap.Point(120.814326,30.701212),  
            new BMap.Point(120.8006,30.690033),  
            new BMap.Point(120.795498,30.700281),  
            new BMap.Point(120.78867,30.696306),  
            new BMap.Point(120.805559,30.706801),  
            new BMap.Point(120.8006,30.70705),  
            new BMap.Point(120.814182,30.710465),
            ],
        };
      },
      methods: {
        //创建标注点并添加到地图中
        addMarker(points) {
            //循环建立标注点
            for(var i=0, pointsLen = points.length; i<pointsLen; i++) {
                var marker = new BMap.Marker(points[i]); //将点转化成标注点
                this.meat_map.addOverlay(marker);  //将标注点添加到地图上
            }
        },
        // pand(){
        //   //循环建立标注点
        //     for(var i=0, pointsLen = point2s.length; i<pointsLen; i++) {
        //         var thePoint = point2s[i];
        //         showInfo(thePoint);
        //     }
        // },
        showInfo(point) {
            //判断点是否在
            //console.log(this.polygon3,point)
          if(BMapLib.GeoUtils.isPointInPolygon(point,this.polygon3)){
            console.log(BMapLib.GeoUtils.isPointInPolygon(point,this.polygon3))
            console.log(point)
          }
        },
        //删除矩形框函数
        clearAll() {
          for(var i = 0; i < this.overlays.length; i++){
                this.meat_map.removeOverlay(this.overlays[i]);
            }
            this.overlays.length = 0   
        }
      },
      mounted() {
        //创建地图
        var map = this.meat_map = new BMap.Map("allmap");
        map.centerAndZoom(new BMap.Point(120.815837, 30.678005), 12);
        map.enableScrollWheelZoom();
        map.setMapStyleV2({
          styleId: "6f85aada1205ac9f3d1dc2af3e290a9b"
        });
        //创建多边形
        //实例化鼠标绘制工具
        var overlaycomplete = (e)=>{
          this.clearAll()
          this.overlays.push(e.overlay);
          //console.log(e.overlay.Wn,"矩形点位")
          for (let i in e.overlay.Wn) {
              this.polygon2.push(new BMap.Point(e.overlay.Wn[i].lng, e.overlay.Wn[i].lat));
          }
          this.polygon3 = new BMap.Polygon(this.polygon2)
          // console.log(polygon2,polygon3,"polygon2polygon2polygon2polygon2")
          //循环建立标注点
          for(var i=0, pointsLen = this.point2s.length; i<pointsLen; i++) {
              var thePoint = this.point2s[i];
              this.showInfo(thePoint);
          }
        }
        var styleOptions = {
            strokeColor:"red",    //边线颜色。
            fillColor:"red",      //填充颜色。当参数为空时,圆形将没有填充效果。
            strokeWeight: 3,       //边线的宽度,以像素为单位。
            strokeOpacity: 0.8,    //边线透明度,取值范围0 - 1。
            fillOpacity: 0.6,      //填充的透明度,取值范围0 - 1。
            strokeStyle: 'solid' //边线的样式,solid或dashed。
        }
        var drawingManager = new BMapLib.DrawingManager(map, {
            isOpen: false, //是否开启绘制模式
            enableDrawingTool: true, //是否显示工具栏
            drawingToolOptions: {
                anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
                offset: new BMap.Size(5, 5), //偏离值
                drawingModes : [BMAP_DRAWING_RECTANGLE],
            },
            circleOptions: styleOptions, //圆的样式
            polylineOptions: styleOptions, //线的样式
            polygonOptions: styleOptions, //多边形的样式
            rectangleOptions: styleOptions //矩形的样式
        });  
        //添加鼠标绘制工具监听事件,用于获取绘制结果
        drawingManager.addEventListener('overlaycomplete', overlaycomplete);
        //创建地图点位
        this.addMarker(this.point2s); //创建点位
      }
    };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style  lang="scss" scoped>
    @import "../../static/styles/mixin.scss";
    .center {
      width: 815px;
      height: 750px;
      border-width: 2px;
      border-color: rgb(14, 71, 143);
      border-style: dashed;
      box-sizing: border-box;
    
      & > div {
        height: 100%;
        width: 100%;
      }
    }
    </style>
    

    相关文章

      网友评论

        本文标题:百度地图API(3):判断地图上的点是否在 圆形 多边形 区域内

        本文链接:https://www.haomeiwen.com/subject/zanjuhtx.html