百度地图实现电子围栏 画图

1,179 阅读2分钟

需求:实现自定义地图范围,可以编辑,新增,删除。同时可以操作多个范围。

image.png 右下角的按钮可以自定义

技术:百度地图+BMapGLLib,下面是文档链接

https://lbsyun.baidu.com/index.php?title=jspopularGL // 百度地图
https://github.com/huiyan-fe/BMapGLLib // BMapGLLib
https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html 
// 百度类api文档

具体实现代码:

引入api
<script type="text/javascript" 
        src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=你自己的ak">
    </script>
<link href="https://mapopen.bj.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.css" 
    rel="stylesheet">
<script 
src="https://mapopen.bj.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.js">
</script>

css部分

<style type="text/css">  
    html{height:100%}    
    body{height:100%;margin:0px;padding:0px}    
    #container{height:100%}    
    body,html{width:100%;height:100%;
        margin:0;font-family:"微软雅黑"}


    .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}
    .btn-info{color:#fff;
        background-color:#3bb4f2;
        border-color:#3bb4f2}
    .btn{display:inline-block;
        margin-bottom:0;
        font-weight:normal;
        text-align:center;
        vertical-align:middle;
        touch-action:manipulation;
        cursor:pointer;
        background-image:none;
        border:1px solid transparent;
        white-space:nowrap;padding:6px 12px;
        font-size:14px;line-height:1.42857143;
        border-radius:4px;-webkit-user-select:none;
        -moz-user-select:none;-ms-user-select:none;user-select:none}
        .btn-danger{color:#fff;background-color:#dd514c;border-color:#dd514c}
        #result{position:fixed;
            bottom:0;right:0;
            padding:10px;
            background:#fff;
            border-radius:5px;
            border:1px solid #ccc;
            box-shadow:5px 5px 5px #bbb;
            z-index:999;
        }
   
</style> 
<body>
    <div id="container"></div> 
    <div id="result">
        <input class="btn btn-sm btn-round btn-danger" type="button" value="保存" onclick="save()"/>
        <!-- <input class="btn btn-sm btn-round btn-danger" type="button" value="初始化" onclick="drawPolygon()"/> -->
        <input class="btn btn-sm btn-round btn-info" type="button" value="重置清除" onclick="clearAll()"/>
        <input class="btn btn-sm btn-round btn-info" type="button" value="开始编辑" onclick="onedit()"/>
        <input class="btn btn-sm btn-round btn-info" type="button" value="编辑完成" onclick="Canceledit()"/>
        <input class="btn btn-sm btn-round btn-info" type="button" value="清除" onclick="ONClear()"/>
    </div>
</body>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>

具体实现:

    let coordinatedata = []; // 二维数组  坐标点
    let polygonsdata = []; //存储初始化所有的多边形覆盖物
    let polygonsinx = 's'; // 当前所在编辑的覆盖物的索引
    let polygonsflag = ''; // 当前所在编辑的覆盖物
    var map = new BMapGL.Map("container");
    geofencedetail();
    // 接口请求
    function geofencedetail(){
               let url = '接口地址'
        fetch(url).then((res)=>{
            if(res.ok){
                return res.json();
            }
        }).then((res)=>{
            let {center_point, point} = res.data;
            var poi = new BMapGL.Point(center_point.lng, center_point.lat); // 设置中心点
            map.centerAndZoom(poi, 15);  // //设置中心点坐标和地图级别
            map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
            coordinatedata = point;
            if(point.length>0){
                point.forEach((val,inx)=>{
                   setTimeout(()=>{
                    drawPolygon(val);// 初始化地图
                   },inx*10)
                })
            }
        })
    }
    /* 开始编辑 */
    function onedit(){
        alert('请双击选择要编辑的区域,编辑完成后请先点击编辑完成按钮再保存');
            polygonsdata.forEach((val)=>{
               
                val.addEventListener('lineupdate', function (e) {
                overlaycomplete(e,polygonsinx)
            })
        })
         // 开始监听双击事件,我是使用双击事件来判断是不是要编辑的
        map.addEventListener('dblclick',ondblclicks);
    }
    function ondblclicks(e){
        if(polygonsdata.length>0){
                polygonsdata.forEach((val,inx)=>{
                    let CPts = val.getBounds();
                    let p = new BMapGL.Point(e.latlng.lng,e.latlng.lat);
                    if(CPts.containsPoint(p)){
                        val.enableEditing(); // 启用编辑
                        polygonsinx = inx;
                        polygonsflag = val;
                    }
                })
            }
    }
    /* 清除指定的一个覆盖物 */
    function ONClear(){
        if(polygonsflag){
            map.removeOverlay(polygonsflag);
            coordinatedata.splice(polygonsinx,1);
            polygonsdata.splice(polygonsinx,1);
            drawingManager.clearOverlayData(polygonsflag);
            Canceledit();
        }
    }
    /* 取消编辑 */
    function Canceledit(){
        map.removeEventListener('dblclick',ondblclicks); //移除双击事件
        polygonsdata.forEach((val)=>{
            val.disableEditing(); // 禁止编辑
        })
    }
    // 鼠标绘制完成回调方法   获取各个点的经纬度
    var overlays = [];
    var json_data = [];
    var styleOptions = {
        strokeColor:"black",    //边线颜色。
        fillColor:"hotpink",  //填充颜色。当参数为空时,圆形将没有填充效果。
        strokeWeight: 2,       //边线的宽度,以像素为单位。
        strokeOpacity: 0.8,       //边线透明度,取值范围0 - 1。
        fillOpacity: 0.6,      //填充的透明度,取值范围0 - 1。
        strokeStyle: 'solid' //边线的样式,solid或dashed。
    }
    //实例化鼠标绘制工具
    var drawingManager = new BMapGLLib.DrawingManager(map,{
        isOpen:false,
        enableDrawingTool: true, //是否显示工具栏
        drawingMode:BMAP_DRAWING_POLYGON,//绘制模式  多边形
        drawingToolOptions: {
            anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
            offset: new BMapGL.Size(5, 5), //偏离值
            drawingModes:[
                // BMAP_DRAWING_RECTANGLE,
                BMAP_DRAWING_POLYGON,
            ]
        },
        polygonOptions: styleOptions //多边形的样式
    });
    //添加鼠标绘制工具监听事件,用于获取绘制结果
    drawingManager.addEventListener('overlaycomplete', overlaycomplete);

    function overlaycomplete(e,inx){
        overlays.push(e.overlay);
        var path = e.overlay.getPath();//Array<Point> 返回多边型的点数组
        for(var i=0;i<path.length;i++){
            json_data.push({
                "lng":path[i].lng,
                "lat":path[i].lat
            }); //初始化 坐标点
        }
        if(json_data.length>0){
            if( typeof inx == 'number'){
              coordinatedata[inx]=json_data;
            }else{
              coordinatedata.push(json_data);
              polygonsdata.push(e.overlay);
            }
            json_data = [];
            
        }
    };
    // 清除
    function clearAll(){
        // 清除初始化的覆盖物
        var allOverlay = map.getOverlays();
        for(var i = 0; i < allOverlay.length; i++) {
            map.removeOverlay(allOverlay[i]);
            map.removeOverlay(allOverlay[i+1]);
        }
        // 清除lbs的覆盖物
        for(var i = 0; i < overlays.length; i++){
            map.removeOverlay(overlays[i]);
        }
        json_data = [];
        coordinatedata = [];
        polygonsdata = [];
        overlays.length = 0;   
    }
    $('.BMapLib_last').click(function() {
        clearAll();
    })
    // 初始化绘制
    function drawPolygon(datas){
        let point = datas;
        let polArry = [];
        point.forEach(item => {
            let p = new BMapGL.Point(item.lng,item.lat);
            polArry.push(p);
        });
  
        let polygon = new BMapGL.Polygon(polArry,{
            fillColor: 'blue',
            fillOpacity: 0.2
        });
        map.addOverlay(polygon);
        polygonsdata.push(polygon);
    }
    // 保存
    function save() {
        let url = `接口地址`
        let data = {
            point:coordinatedata
        }
        fetch(url,{
            method: 'Post',
            headers: {
            'Content-Type': 'application/json;charset=utf-8'
            }, 
            body: JSON.stringify(data)
        }).then((res)=>{
            json_data = [];
            console.log('res---',res)
        })
    }

欢迎大家一起学习交流 欢迎评论