百度地图JSAPI:电子围栏工具的开发和使用_百度


百度地图JSAPI:电子围栏工具的开发和使用_ci_02

引言

在现代地理信息系统(GIS)中,电子围栏作为一种重要的空间数据管理工具,广泛应用于各类应用场景,如区域监控、安防管理、物流管理等。本文旨在介绍如何利用百度地图JavaScript API(JSAPI)开发一款电子围栏工具,帮助用户轻松地在地图上绘制和管理电子围栏。

一、准备工作
注册百度开发者账号:首先,你需要在百度开发者平台注册一个账号,并创建一个应用以获取API Key。
引入百度地图JSAPI:在你的HTML文件中引入百度地图JSAPI和绘图工具库。

引入百度地图JS库

<!--百度地图开源库-->
    <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=qKTp***"></script>
    <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"/>

构建DOM容器

为了提供良好的用户体验,需要设计合理的界面布局。这里采用了一个包含地图渲染区和操作面板的基本HTML结构。

<div class="mainbox">
    <!--地图渲染区-->
    <div id="map" style="float:left;height: 100vh;width: 70%;"></div>
    <!--操作面板-->
    <div style="float:left;width: 28%;padding: 1%;">
        <form class="layui-form layui-form-pane">
            <div class="layui-card">
                <div class="layui-card-header layui-font-18 layui-font-red">操作说明</div>
                <div class="layui-card-body" style="height: auto;">
                    <p>1.单击选择地图上左侧画多边形工具;</p>
                    <p>2.地图上单击拾取坐标,大于等于3个坐标点时,双击即可完成电子围栏的拾取;</p>
                    <p class="layui-font-red">3.编辑时,请单击“清除围栏”,重新拾取坐标;</p>
                </div>
            </div>
            <div class="layui-card">
                <div class="layui-form-item">
                    <label class="layui-form-label">围栏名称</label>
                    <div class="layui-input-inline" style="width: 60%;">
                        <input type="text" placeholder="围栏名称" id="town_name" name="town_name" lay-verify="required" class="layui-input" value="红星乡">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label">经度坐标</label>
                    <div class="layui-input-inline" style="width: 60%;">
                        <input type="text" placeholder="经度坐标" id="poi_longitude" name="poi_longitude" class="layui-input" value="130.97030688845558" lay-verify="required">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label">纬度坐标</label>
                    <div class="layui-input-inline" style="width: 60%;">
                        <input type="text" placeholder="纬度坐标" id="poi_latitude" name="poi_latitude" class="layui-input" value="45.28260821161705" lay-verify="required">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label">电子围栏</label>
                    <div class="layui-input-inline" style="width: 60%;">
                        <textarea id="town_fence" name="town_fence" class="layui-textarea" placeholder="坐标集" lay-verify="required"></textarea>
                    </div>
                </div>

                <div class="layui-form-item" style="text-align: center;">
                    <input type="hidden" id="town_id" name="town_id" value="8">
                    <input class="layui-btn layui-btn-danger" type="button" value="清除围栏" onclick="clearAll()">
                    <button class="layui-btn" lay-filter="add" lay-submit="" type="submit">确定提交</button>
                </div>
            </div>
        </form>
    </div>
</div>

封装函数

清除边界

当用户需要重新绘制围栏时,可通过调用清除函数来移除现有围栏并清空相关数据输入框。

/*清除边界*/
    function clearAll() {
        map.clearOverlays();
        $("#town_fence").val(''); //清除表单;
    }

返回多边形中心点

通过计算多边形各顶点坐标的平均值来确定其中心位置,并更新至相应的表单字段。

/*
   * path,返回多边型的点数组,Array<Point>
   */
    function getCenterPoint(coordinates) {
        const lnglat = coordinates.split(';');
        const path = lnglat.map(lnglatStr => {
            const [lng, lat] = lnglatStr.split(',');
            return new BMap.Point(parseFloat(lng), parseFloat(lat));
        });

        var x = 0.0;
        var y = 0.0;
        for (var i = 0; i < path.length; i++) {
            x = x + parseFloat(path[i].lng);
            y = y + parseFloat(path[i].lat);
        }
        x = x / path.length;
        y = y / path.length;
        //console.log(x+','+y);
        $("#poi_longitude").val(x);
        $("#poi_latitude").val(y);
    }

加载电子围栏

根据存储的坐标数据加载已定义的电子围栏,并设置地图视图以显示该围栏区域。

//加载电子围栏
    function getFence(town_fence) {
        if (town_fence) {
            const lnglat = town_fence.split(';');

            // 创建点数组
            const pts = lnglat.map(lnglatStr => {
                const [lng, lat] = lnglatStr.split(',');
                return new BMap.Point(parseFloat(lng), parseFloat(lat));
            });

            // 创建多边形
            const ply = new BMap.Polygon(pts, {
                fillColor: 'blue',
                fillOpacity: 0.3,
                strokeColor: 'blue',
                strokeStyle: "dashed",
                strokeWeight: 1,
                strokeOpacity: 0.5
            });

            // 设置地图中心和缩放级别
            map.centerAndZoom(pts[0], 15);

            // 添加多边形到地图
            map.addOverlay(ply);

            // 启用编辑
            ply.enableEditing();

            // 移除已有的lineupdate事件监听器
            ply.removeEventListener('lineupdate', handleLineUpdate);

            // 添加lineupdate事件监听器
            ply.addEventListener('lineupdate', handleLineUpdate);

            function handleLineUpdate() {
                const points = this.getPath(); // 获取多边形的所有顶点
                const coordinates = points.map(point => `${point.lng},${point.lat}`).join(';'); // 使用分号连接各点
                //console.log(coordinates);
                getCenterPoint(coordinates);//获取中心点
                $("#town_fence").val(coordinates);
            }
        } else {
            console.log('未获取到围栏信息')
        }
    }

绘制模式

配置绘图工具以支持用户直接在地图上绘制多边形,并监听绘制完成事件以处理后续逻辑。

var overlays = [];
    var overlaycomplete = function (e) {
        overlays.push(e.overlay);
        var res = e.overlay;//e.drawingMode;
        //判断绘制模式;
        var path = res.getPath();//Array<Point> 返回多边型的点数组
        const coordinates = path.map(point => `${point.lng},${point.lat}`).join(';'); // 使用分号连接各点
        //console.log(coordinates);
        getCenterPoint(coordinates);//获取中心点
        $("#town_fence").val(coordinates);
    };

    //鼠标绘制工具
    var drawingManager = new BMapLib.DrawingManager(map, {
        isOpen: false, //是否开启绘制模式
        enableDrawingTool: true, //是否显示工具栏
        drawingMode: BMAP_DRAWING_POLYGON,//绘制模式
        drawingToolOptions: {
            drawingModes: [BMAP_DRAWING_POLYGON],//, BMAP_DRAWING_MARKER, BMAP_DRAWING_POLYLINE
            anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
            offset: new BMap.Size(5, 5), //偏离值
        },
        polygonOptions: {
            strokeColor: "red",    //边线颜色。
            fillColor: "red",      //填充颜色。当参数为空时,圆形将没有填充效果。
            strokeWeight: 3,       //边线的宽度,以像素为单位。
            strokeOpacity: 0.8,	   //边线透明度,取值范围0 - 1。
            fillOpacity: 0.6,      //填充的透明度,取值范围0 - 1。
            strokeStyle: 'solid' //边线的样式,solid或dashed。
        }, //多边形的样式
    });

    //添加鼠标绘制工具监听事件,用于获取绘制结果
    drawingManager.addEventListener('overlaycomplete', overlaycomplete);

@漏刻有时