Login
芋圆社区 > 编程 > 百度地图 > 鼠标绘制与框选点位

鼠标绘制与框选点位

981
0
2022-08-15
2022-08-16
Hey、小怪兽

  • • 实现百度地图的鼠标绘制和点位框选,需求:
  • - 要求可以在地图上圈选,矩形框选,多边形框选
  • - 要求框选后可以返回框选的点位
  • - 只能选择一个框选,框选后上一个框选图案清除(可选)
  • • 首先找到百度地图提供的接口,3.0的接口文档直接看鼠标绘制就可以了:
  • • 第一步:引入必要的文件
  • <!-- 百度地图申请的秘钥 -->
    <script type="text/javascript" src="//api.map.baidu.com/api?v=3.0&ak=密钥"></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元素和样式
  • <div id="allmap">
        <div id="map"></div>
    </div>
  • <style type="text/css">
        body,
        html {
            width: 100%;
            height: 100%;
            margin: 0;
        }
        #allmap {
            zoom: 1;
            overflow: hidden;
            position: relative;
            width: 100%;
            height: 100vh;
        }
        #map {
            height: 100%;
            transition: all 0.5s ease-in-out;
            -webkit-transition: all 0.5s ease-in-out;
        }
    </style>
  • • 第三步:初始化百度地图
  • // map就是上面的div的id
    var map = new BMap.Map("map");
    // 初始点位
    var poi = new BMap.Point(116.307852, 40.057031);
    map.centerAndZoom(poi, 16);
    // 启用滚轮放大缩小,默认禁用
    map.enableScrollWheelZoom();
  • • 最后一步:初始化绘制工具
  • 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,              // 是否显示工具栏
        circleOptions: styleOptions,          // 圆的样式
        polylineOptions: styleOptions,        // 线的样式
        polygonOptions: styleOptions,         // 多边形的样式
        rectangleOptions: styleOptions,       // 矩形的样式
    });
  • • 这样就完成了(前半段的最终代码放到博客最后,放这里有点占位置了):
  • • 接下去要实现框选后返回点位,先修改一下这个框选的按钮,随便写点按钮和样式:
  • <div id="boxSelection" class="boxSelection">
        <p onclick="boxSelection('circle')">圈选</p>
        <p onclick="boxSelection('rectangle')">矩形框选</p>
        <p onclick="boxSelection('polygon')">多边形选</p>
    </div>
  • /* 框选 */
    .boxSelection {
        user-select: none;
        position: absolute;
        top: 50px;
        right: 100px;
        width: 75px;
        overflow: auto;
        padding: 0 10px;
        background: #fff;
        border: 1px solid #f0f0f0;
        border-radius: 5px;
        box-shadow: 1px 1px 2px -1px;
    }
    
    .boxSelection p:hover {
        cursor: pointer;
        color: #0092ff;
    }
  • • 这样就得到了自己的按钮:
  • • 上面每个p标签都有带一个onclick方法,传个参数给boxSelection方法
  • • 稍微修改一下之前的方法:
  • var drawingManager = null;
    var styleOptions = {
        strokeColor: "red",          // 边线颜色
        fillColor: "red",            // 填充颜色。当参数为空时,圆形将没有填充效果
        strokeWeight: 3,             // 边线的宽度,以像素为单位
        strokeOpacity: 0.8,          // 边线透明度,取值范围0 - 1
        fillOpacity: 0.6,            // 填充的透明度,取值范围0 - 1
        strokeStyle: "solid",        // 边线的样式,solid或dashed
    };
    
    /** 创建框选 */
    function boxSelection(modeType) {
        // 绘制(圈选)对象 drawingManager
        drawingManager = new BMapLib.DrawingManager(map, {
            isOpen: false,                        // 是否开启绘制模式
            enableDrawingTool: true,              // 是否显示工具栏,注意这里改成false了
            circleOptions: styleOptions,          // 圆的样式
            polygonOptions: styleOptions,         // 多边形的样式
            rectangleOptions: styleOptions,       // 矩形的样式
        });
    
        /*
            设置当前的绘制模式:
                点:      BMAP_DRAWING_MARKER       "marker"
                圆:      BMAP_DRAWING_CIRCLE       "circle"
                线:      BMAP_DRAWING_POLYLINE     "polyline"
                多边形:  BMAP_DRAWING_POLYGON      "polygon"
                矩形:    BMAP_DRAWING_RECTANGLE    "rectangle"
        */
    
        if (modeType === "circle") {
            drawingManager.setDrawingMode(BMAP_DRAWING_CIRCLE);
        } else if (modeType === "rectangle") {
            drawingManager.setDrawingMode(BMAP_DRAWING_RECTANGLE);
        } else {
            drawingManager.setDrawingMode(BMAP_DRAWING_POLYGON);
        }
    }
  • • 创建几个点位来测试,一般来说这个点位是接口返回的:
  • // 创建点标记
    var marker1 = new BMap.Marker(new BMap.Point(116.404, 39.925));
    var marker2 = new BMap.Marker(new BMap.Point(116.404, 39.915));
    
    // 在地图上添加点标记
    map.addOverlay(marker1);
    map.addOverlay(marker2);
    
    // 存储点位
    var markerArr = new Array();
    markerArr.push(marker1);
    markerArr.push(marker2);
  • • 接着就可以写框选返回点位的方法了,在写方法前,先看看百度地图是否有提供给我们相应的方法
  • • 可以找到一个开源的叫GeoUtils.js的东西,先引入这个js文件(在百度上找找很多的,免费开源的):
  • <script type="text/javascript" src="GeoUtils_min.js"></script>
  • • 需要的方法就这三个:
  • • 圆形看起来比较复杂,所以先看圆形如何实现,可以看到这个方法需要的是一个point和circle,也就是点和圆形对象
  • • 圆形对象可以去3.0类参考看,需要的是一个中心点和半径,后面的opts是其他的选项不需要管:
  • • 框选可以设置个监听事件,等框选完毕后执行获取点位的方法,接着遍历点位,创建点位传给isPointInCircle方法就可以了:
  • //绘制完成事件
    drawingManager.addEventListener("overlaycomplete", function (e) {
        const _points = getPoints(e.overlay, modeType);
        console.log(_points);
    });
  • // 框选获取点位
    function getPoints(overlay, modeType) {
        // 获取刚才存储的点位
        let _points = markerArr;
        // 框选的点位
        let returnPints = new Array();
    
        // 边界点
        const path = overlay.getPath();
        // 获取圆形中心点
        const centerPoint = overlay.getCenter();
        // 获取边界随便一个点和中心点距离就是半径
        const radius = drawingManager._map.getDistance(centerPoint, path[0]);
        // 创建一个圆形的覆盖物
        const circleObj = new BMap.Circle(centerPoint, radius);
    
        _points.forEach((value) => {
            const _point = new BMap.Point(value.point.lng, value.point.lat);
            const result = BMapLib.GeoUtils.isPointInCircle(_point, circleObj);
            if (result) {
                returnPints.push(value);
            }
        });
    
        return returnPints;
    }
  • • 和圈选一样,矩形框选和多边形框选也是这样实现也是这样实现:
  • • 和圈选不同的是,多边形的创建并不是传中心点和半径,而是一个点数组,点数组就很好得到了:
  • // 多边形边界点 <数组>
    const BoundaryPoints = overlay.getPath();
  • • 最后一个矩形框选了,一看文档,巨复杂,其实不需要这样写,我觉得矩形是特殊的多边形,所以完全可以用多边形的方法,不需要另外写矩形的方法了
  • • 这样就可以获得点位啦:
  • • 注意,因为我的项目是只能选择一种框选并且框选绘制前之前的框选图案都会删除,所以可以这样写,如果需要保留之前的框选的数据需要自行修改
  • • 下面是两个完整代码,第一个是框选的完整代码,第二个是框选+返回点位的完整代码:
  • <!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 {
                    width: 100%;
                    height: 100%;
                    margin: 0;
                }
                #allmap {
                    zoom: 1;
                    overflow: hidden;
                    position: relative;
                    width: 100%;
                    height: 100vh;
                }
                #map {
                    height: 100%;
                    transition: all 0.5s ease-in-out;
                    -webkit-transition: all 0.5s ease-in-out;
                }
            </style>
    
            <!-- 百度地图申请的秘钥 -->
            <script src="//api.map.baidu.com/api?type=webgl&v=3.0&ak=密钥"></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" />
        </head>
        <body>
            <div id="allmap">
                <div id="map"></div>
            </div>
    
            <script type="text/javascript">
                // map就是上面的div的id
                var map = new BMap.Map("map");
                // 初始点位
                var poi = new BMap.Point(116.307852, 40.057031);
                map.centerAndZoom(poi, 16);
                // 启用滚轮放大缩小,默认禁用
                map.enableScrollWheelZoom();
    
                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,              // 是否显示工具栏
                    circleOptions: styleOptions,          // 圆的样式
                    polylineOptions: styleOptions,        // 线的样式
                    polygonOptions: styleOptions,         // 多边形的样式
                    rectangleOptions: styleOptions,       // 矩形的样式
                });
            </script>
        </body>
    </html>
    
  • <!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 {
                    width: 100%;
                    height: 100%;
                    margin: 0;
                    font-family: "微软雅黑";
                }
                #allmap {
                    zoom: 1;
                    overflow: hidden;
                    position: relative;
                    width: 100%;
                    height: 100vh;
                }
                #map {
                    height: 100%;
                    transition: all 0.5s ease-in-out;
                    -webkit-transition: all 0.5s ease-in-out;
                }
                /* 框选 */
                .boxSelection {
                    user-select: none;
                    position: absolute;
                    top: 50px;
                    right: 100px;
                    width: 75px;
                    overflow: auto;
                    padding: 0 10px;
                    background: #fff;
                    border: 1px solid #f0f0f0;
                    border-radius: 5px;
                    box-shadow: 1px 1px 2px -1px;
                }
    
                .boxSelection p:hover {
                    cursor: pointer;
                    color: #0092ff;
                }
            </style>
    
            <!-- 百度地图申请的秘钥 -->
            <script src="//api.map.baidu.com/api?type=webgl&v=3.0&ak=密钥"></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" />
            <!-- BMapLib.GeoUtils -->
            <script type="text/javascript" src="GeoUtils_min.js"></script>
        </head>
        <body>
            <div id="allmap">
                <div id="map"></div>
            </div>
            <div id="boxSelection" class="boxSelection">
                <p onclick="boxSelection('circle')">圈选</p>
                <p onclick="boxSelection('rectangle')">矩形框选</p>
                <p onclick="boxSelection('polygon')">多边形选</p>
            </div>
            <script type="text/javascript">
                // 百度地图API功能
                var map = new BMap.Map("map");
                var poi = new BMap.Point(116.404, 39.925);
                map.centerAndZoom(poi, 16);
                map.enableScrollWheelZoom();
    
                // 创建点标记
                var marker1 = new BMap.Marker(new BMap.Point(116.404, 39.925));
                var marker2 = new BMap.Marker(new BMap.Point(116.404, 39.915));
                // 在地图上添加点标记
                map.addOverlay(marker1);
                map.addOverlay(marker2);
                // 存储点位
                var markerArr = new Array();
                markerArr.push(marker1);
                markerArr.push(marker2);
    
                // 框选
                var drawingManager = null;
                // 框选样式
                var styleOptions = {
                    strokeColor: "red",     //边线颜色。
                    fillColor: "red",       //填充颜色。当参数为空时,圆形将没有填充效果。
                    strokeWeight: 3,        //边线的宽度,以像素为单位。
                    strokeOpacity: 0.8,     //边线透明度,取值范围0 - 1。
                    fillOpacity: 0.6,       //填充的透明度,取值范围0 - 1。
                    strokeStyle: "solid",   //边线的样式,solid或dashed。
                };
    
                /** 创建框选 */
                function boxSelection(modeType) {
                    // 绘制(圈选)对象 drawingManager
                    drawingManager = new BMapLib.DrawingManager(map, {
                        isOpen: true,
                        enableDrawingTool: false,
                        circleOptions: styleOptions,      // 圆的样式
                        polygonOptions: styleOptions,     // 多边形的样式
                        rectangleOptions: styleOptions,   // 矩形的样式
                    });
    
                    /*
                        设置当前的绘制模式:
                            点:      BMAP_DRAWING_MARKER       "marker"
                            圆:      BMAP_DRAWING_CIRCLE       "circle"
                            线:      BMAP_DRAWING_POLYLINE     "polyline"
                            多边形:  BMAP_DRAWING_POLYGON      "polygon"
                            矩形:    BMAP_DRAWING_RECTANGLE    "rectangle"
                    */
    
                    if (modeType === "circle") {
                        drawingManager.setDrawingMode(BMAP_DRAWING_CIRCLE);
                    } else if (modeType === "rectangle") {
                        drawingManager.setDrawingMode(BMAP_DRAWING_RECTANGLE);
                    } else {
                        drawingManager.setDrawingMode(BMAP_DRAWING_POLYGON);
                    }
    
                    //绘制完成事件
                    drawingManager.addEventListener("overlaycomplete", function (e) {
                        const _points = getPoints(e.overlay, modeType);
                        console.log("框选后返回的点:", _points);
                    });
                }
    
                // 框选获取点位
                function getPoints(overlay, modeType) {
                    // 获取刚才存储的点位
                    let _points = markerArr;
                    // 框选的点位
                    let returnPints = new Array();
    
                    // 只有2种情况 是圆形框选和多边形框选,矩形其实是特殊的多边形
                    if (modeType === "circle") {
                        // 边界点
                        const path = overlay.getPath();
                        // 获取圆形中心点
                        const centerPoint = overlay.getCenter();
                        // 获取边界随便一个点和中心点距离就是半径
                        const radius = drawingManager._map.getDistance(centerPoint, path[0]);
                        // 创建一个圆形的覆盖物
                        const circleObj = new BMap.Circle(centerPoint, radius);
    
                        _points.forEach((value) => {
                            const _point = new BMap.Point(value.point.lng, value.point.lat);
                            const result = BMapLib.GeoUtils.isPointInCircle(_point, circleObj);
                            if (result) {
                                returnPints.push(value);
                                // 改变图标, 俺的项目点位是Marker,框选后需要改变图标
                                // let icon = value.getIcon();
                                // icon.setImageUrl(icon.imageUrl.replace("blue", "green"));
                                // value.setIcon(icon);
                            }
                        });
                    } else {
                        // 多边形边界点 <数组>
                        const BoundaryPoints = overlay.getPath();
                        // 创建一个多边形覆盖物
                        const polygonObj = new BMap.Polygon(BoundaryPoints);
    
                        _points.forEach((value) => {
                            const _point = new BMap.Point(value.point.lng, value.point.lat);
                            const result = BMapLib.GeoUtils.isPointInPolygon(_point, polygonObj);
                            if (result) {
                                returnPints.push(value);
                            }
                        });
                    }
    
                    return returnPints;
                }
            </script>
        </body>
    </html>

上一篇:鼠标绘制与框选测面

下一篇:路况setTrafficOn的坑

Message Board
回复
回复内容不允许为空
留言字数要大于2,小于200!
提交成功,5s后刷新页面!
编程导航

鼠标绘制测面v2.0

鼠标绘制与框选测面

鼠标绘制与框选点位

路况setTrafficOn的坑

Copyright © 2020 芋圆社区

Powered by 浙ICP备2020039309号-1

此页面不支持夜间模式!

已进入夜间模式!

已进入普通模式!

搜索框不允许为空

签到成功!经验+5!芋圆币+2!

签到失败!今日已签到!

需要登录社区账号才可以进入!

复制成功
寄,页面未加载完成或页面无锚点