zoukankan      html  css  js  c++  java
  • 百度地图API开发的快速使用和添加大量坐标点的几种方法

    快速上手

    注意:本篇文章代码是基于 百度地图 JavaScript API v3.0 的条件下编写,GL版本可能稍有变化。

    地图嘛,很重要的一部分就是坐标经纬度了:
    经度: 英文 longitude 缩写 lng;纬度:英文 latitude 缩写 lat

    基本使用

    在使用百度地图的API之前,首先要有一个先密钥(ak)才能开始使用。没有的话可以免费申请
    1.引入js(该ak是mapv中示例的ak,需要测试的朋友可以使用)

    <script src="//api.map.baidu.com/api?v=3.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ"></script>
    

    或者使用npm

    $ npm install vue-baidu-map
    
    import BaiduMap from 'vue-baidu-map'
    Vue.use(BaiduMap, {
      ak: '你申请的key'
    })
    

    2.初始化地图

    <template>
      <div class="map-box" style="height:100%">
        <!-- 准备容器 -->
        <div class="baidu-map" id="baiduMap"></div>
      </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // base64自定义坐标图形
                bluePoint:
                    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAmCAYAAAClI5npAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAaJSURBVFhHrVdbTFRXFN1nHszo8CiIw0sBkRZR8IEPqFgq1aZYaRNt0h9N9KPpR1NrP2jaSKo1mtrETz/8ME0f/OhP04oQ2qatVEWtgtTCiCAgzsDwUJFhHJi5c+d07+uc6Z3LMDzsSnbOmX3OPWvtfc7dZy6D2WMuc3mwnRGzWVQ7R/zW+gWpljyqmGgCtETs/PnzptLS0uUWiyXLYDCko8/ybAhckiT1j42NdZ4+fdpx9OhRGX1aQRGFRBIwhfjAgQOG48ePr0XiCp1Ol4Q+I5oBTUcTEAHOuR9bnyzL9/r7+y/s37/f0djYSKTCBMKEaAWof1OfHTlyxFhdXb2f6Q3rXT5m/OEuz6jthpyOR2B1eWEhzuFJZnhaaAXn3lXQuTUTHi7Ug9/vly5XVVWdO3XqFAmbVsR0Aigy1tzcbC0sLHzXIxvX1tj40m9uwxr7OCRxYNrnFBgZlzekQt97a6H9jWwYYQHpUlNT04/l5eXjOKwWEVGA6FOr6+vry8rIyHhnIqBb8clFWFffDSs8EjM/mxIdiWbu3v0i2D7fDK1GkBpRRD2KcONQAC1MhF7pPgMRK3by5Enztm3bduBBW/3Rr7Cx9h4UTMosRpk1C0z6Wcydx7DYLYG8fZneEBcX9+D+/fvDNpstFLmAOEQhcrJdu3alI3net22QXd8D+b4AowM3J5CIH7sgv8kBaQkJCWVbtmyh7AkOgtIKAQKsoqJCn5ycvOypxFK/vg2rvXOIXIsRD8Rf6IElwAyrKisrU9ElyENQC1DUFRcXG00m00s/dUOa0w3xU3I2B8ic6W4MQlrPGCy0Wq0bcnNzlcMdNAXCEUJKSooxJiZmSfMQS56QYd7RC/SNQZLzKZjMZnMeFitBLjiZ9gzo9AjGWNLgOLf45bnvvRZUK/AwGnDZVJ/Pp86AIkK9BQomJycVITIH3fOkXyCANYNj4cCuPhAIKKRqaDPA3G43YFmVzAbw67CnjD4HjDou6xlwLNHeoIAwEVMyMDAwEMA6OpQdDy4jltSge95YtADGE83gw/3vw3tk2joQgsPhkL1er/2VpTBkMYI36J43chPh4dI4mHS5XHeHhoaC3v8gBJAyRR2WTT9WLdvmNLl/xSIYxuzNextMei6VpIEz2Sw5z549eyvoDoM2A3xkZCRgt9sfGVngcdVGaI3RgxQcmzOsC8G1Ow8c3omJXrzYnqIrFKjAlC1A8J07dzpxK66XZnDnh+vhLwPecsGxWcOk49IH6+BWlkXqra2t/a2mpoa2c0o26TISp1Ld6mJjY0c3bdqU/uoyE+scBVPXY7BOdw1roWM8sHcl3Koq5m0Ou/3PY8eOdfT29tKBFv+UQpkQtyEtrF6cXbp0yZ+amjqwZnXh0nyrkV3ph+RHkyw2OB4V5VnQ+eVWdktyP7l94sSJ33H/Peimq1hcxyITXC1A3dLWsIaGBm9BQcFw2caC1R4f8JYhSJ3pZlwSxx+dLIerWRY+XlPz/dnDhw8/RDdFHklAGLHaSBgZkRnwrdgZb818bV8dlF13wjKqbuifAjr1n26Cy++v5T19Pffq8/LyLqKbDrFIvxBALSGUATXE4kIMeDyewYrtW9NWppigEe93/G+4gPxqUNXE2tH98UbWLrmGm0pKSn7BqiqIxd4Twtopr6HGFNXnzp0bx9foSpHV/6D6ZbgWF8Mn0B8GfOXGDhZBWwKM3zlz5swfg4ODFLk6ajLRD0GbgYipxcrIsDa48M+KZX1m7As+DtLVfsjE6cp8KlbVm+HKm9lyx82bN34+dOiQAysfRU+EInqRdkJIRDQBoS2gFl8j3tXV5Xj7rcrMonST4ZoTEvrdLJEGK5eDrboE/hkeHGjat2/fzc7OToqeCNVGCIueEGkLRKs2isKPX0Ye/NhoiI0JeA5ugNuLF3BXXhJ3flUGLXqQn9TV1d1sbW31BecLYvU6BNEqiJhyhIiejESSUbaUFrNRmpK+ZMd3Nn1+kRVGi6zc3tFhq8VviGYcJ1IhQJv+MPJoUJMTMX2KmdDo9Mfm5OQk4HfD63g2vsA35LP29vZi9Meh0bci/fulufSMEE1rRYT2DKgx3UN8dHSUt7W1DSYmJtpaWlr+3rNnjx2FiKhFxKIvLCKmVYYQY6IVkWhNLC6I1MQEdX8KaIFoEOOiVadT+6wgUhOq+xExkwCCljCaAG0blZwwGwEC6rnTPacmnJGcMF8BM2FW5P8HSNRchGkA8C8q47x5NndS7gAAAABJRU5ErkJggvfhCGswx9rrFnP1jE1YDrlwePFofvSFACYc+EVrqiTU376zZXd0rmv2gXFqbfb9wBxrxBBLDrlNPof7EwIY3TypbV9FqN26u62zj0gf2ucW4uNR4DPH2hmLIZYccmNxN+DjxD3g5gkQYOwkzTIN+n29a+1969nyXU9RDJ851oghlhzPj5xujqmvYsAUxvXYvucyI8SYe+D+E0pbXZ3+SvpruwjX4/dJt67Y63cv1W3bPQUQ4CJiccC1Y98zeIAHu3kXEHC3t1t87ay/XH4VY1+Yz7ufNWK8cJPHuSMmOuBg5wSye3zvhNvqynEtHVvWZ/alDN63L+DRcKCd3X7ddt85hk+ZuHPHTAE+RWF8F+HGcaytrqjTLd6zytKRPXB2i517UTc24oWbuwczBQCmo0UBfs1/HKRpOlEsFo82C3MFAC8UfcY474gF3Y/z87BQQCwOCefv4c00L8LoZx5FzMNCASAWjP4sRBHRX4R7CgCzCjfTYqGDFgfzexMwjzyazzmivwgH6oAjhlLA7xHOuLl2MEj/AQToURVmBwjWAAAAAElFTkSuQmCC"
            }
        },
        methods: {
            init() {
                const map = new BMap.Map('baiduMap', {
                    // 地图是否可点击
                    enableMapClick: false,
                    // 坐标类型 3为gcj02坐标,5为bd0ll坐标,默认为5
                    // 如确认坐标正确,但是点出不来,或者位置错误。则确认下类型
                    coordsType: 5
                })
                // 一个点对象,包含坐标及名称
                const center = {
                    name: '温州市人民政府',
                    lng: '120.705832',
                    lat: '28.00032'
                }
                // 初始化地理坐标 存放地理坐标的对象
                const point = new BMap.Point(center.lng, center.lat)
                // 初始化地图 将点设置为地图的中心点 设置初始缩放等级
                map.centerAndZoom(point, 12)
    
                // 其它地图配置
                map.enableScrollWheelZoom(true)    // 开启鼠标滚轮缩放
                map.enableDragging()  // 拖拽
            }
        },
        mounted() {
            this.init()
        }
    }
    </script>
    

    如此就能看到一个百度地图了,但是除了地图啥都没有。
    image

    添加点(标记)

    在百度地图中添加的点又叫覆盖物,它可以添加很多的覆盖物:
    image
    添加覆盖物使用addOverlay()方法,下面写一个添加单个点的方法:

    makePoint(map, data) {
        // Point(lng: Number, lat: Number) 经度在前
        const MAPPoniter = new BMap.Point(data.lng, data.lat)
        // 创建图像标注实例 默认样式是个红点 可进行设置
        // 这里设置为data中的一base64蓝色点图片
        const blueIcon = new BMap.Icon(this.bluePoint, new BMap.Size(32, 38))
        const MAPMarker = new BMap.Marker(MAPPoniter, { icon: blueIcon })
    
        // 设置标签 内容 偏移量
        const label = new BMap.Label(data.name, {
            offset: new BMap.Size(-27, 32)
        })
        // 标签样式
        label.setStyle({
            border: 'none',
            background: '#ACACAC',
            fontSize: 20,
            fontWeight: 'bold',
            color: 'red'
        })
        // 设置标签
        MAPMarker.setLabel(label)
    
        // 设置 hover 时显示的点的名称
        MAPMarker.setTitle(data.name)
    
        // 点击事件监听
        MAPMarker.addEventListener('click', function (e) {
           console.log(e)
        })
    
        // 在地图中添加覆盖物
        map.addOverlay(MAPMarker)
    }
    

    一般设置setLabelsetTitle二选一吧,要直接显示出信息的时候就用setLabel
    init()中调用该方法:

    init(){
       ...
       this.makePoint(map, center)
    }
    

    image

    添加控件

    百度地图中还可添加一些辅助的控件,比如比例尺,缩放控件等。

    init(){
        // ......省略之前代码
        // 添加缩放控件
        const navigation = new BMap.NavigationControl({
            anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
            type: BMAP_NAVIGATION_CONTROL_SMALL
        })
        map.addControl(navigation)
    }
    

    注:因为eslint可能会提示BMAP_ANCHOR_BOTTOM_RIGHT需要使用字符串,但这些大写的常量配置不应使用字符串,否则会不生效。

    清除地图左下角的图标

    使用css即可让图标消失,但注意样式不要放在scoped中:

    <style lang="less" scoped>
    .baidu-map {
       100%;
      height: 100%;
    }
    </style>
    
    <style>
    .anchorBL a {
      display: none;
    }
    
    .anchorBL img {
      display: none;
    }
    
    .anchorBL span {
      display: none !important;
    }
    </style>
    

    image

    处理大量点的方法

    添加几个点,几十个点用上面的方法就完了。但是若是有上千上万个点也这么处理吗?虽然我们可以直接一个for循环,但是,这样做了的话就是添加点是时候浏览器会卡住一段时间。所以添加大量点的时候可以使用如下方法,各自有优缺点依情况选用吧。

    这里先定义下点的格式:

    [
      {
        "name": "温州张和堂医药连锁有限公司兴元店",
        "lng": "120.763505",
        "lat": "27.96839093"
      },
      {
        "name": "温州万康大药房有限公司",
        "lng": "120.7530476",
        "lat": "27.97953802"
      }
    ]
    

    点聚合

    点聚合的效果就是,将密集的多个点聚合在一起显示一个大点并标注数量,点击可以放大,详细见后面效果图。
    index.html中引入,百度地图相关的工具库:

    <script src="//api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
    <script src="//api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
    

    点聚合的方法实现:

    makePolyPoints(map, data) {
        const MAPMarkers = []
        map.clearOverlays()
        data.forEach(point => {
            const MAPMarker = new BMap.Marker(new BMap.Point(point.lng, point.lat))
            MAPMarker.setTitle(point.name)
            MAPMarkers.push(MAPMarker)
            // 可以在点对象上添加属性,点击的监听能获取该属性
            MAPMarker.zbbm = 'xxxxx'
            MAPMarker.addEventListener('click', function (e) {
                console.log('坐标编码:', e.target.zbbm)
            })
        })
        if (map.markerClusterer) {
            map.markerClusterer.clearMarkers()
        }
        // 使用点聚合
        map.markerClusterer = new BMapLib.MarkerClusterer(map, {
            markers: MAPMarkers
        })
    }
    

    init()调用即可使用,如需要要使用labe和自定义图标icon,与添加单个点的类似。
    image

    海量点

    海量点就是不把点聚合起来,而是全部显示出来。但使用这种方法的缺点是不能自定义点的图标,只能使用官方提供的预设图形作为点的图标

    使用海量点需要引入:

    <script src="//api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
    <script src="//api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
    

    海量点方法实现:

    makeCollectionPoints(map, data) {
        map.clearOverlays()
        // 判断是否支持使用 canvas (海量点)
        if (document.createElement('canvas').getContext) {
            // 坐标点数据数组
            var points = []
            for (var point of data) {
                points.push(new BMap.Point(point.lng, point.lat))
            }
            // 海量点的配置属性
            // 配置图标:大小 形状 颜色
            const options = {
                size: BMAP_POINT_SIZE_NORMAL,
                shape: BMAP_POINT_SHAPE_STAR,
                color: 'yellow'
            }
            // 初始化海量点
            const pointCollection = new BMap.PointCollection(points, options)
            pointCollection.addEventListener('click', function (e) {
                console.log(e)
            })
            map.addOverlay(pointCollection)
        } else {
            alert('浏览器不支持,请使用chrome、safari、IE8+以上浏览器')
        }
    }
    

    ShapeType预设图形:

    常量 描述
    BMAP_POINT_SHAPE_CIRCLE 圆形,为默认形状
    BMAP_POINT_SHAPE_STAR 星形
    BMAP_POINT_SHAPE_SQUARE 方形
    BMAP_POINT_SHAPE_RHOMBUS 星形
    BMAP_POINT_SHAPE_STAR 菱形
    BMAP_POINT_SHAPE_WATERDROP 水滴状,该类型无size和color属性

    其它具体参数配置参考:百度地图 javascript 3.0 api
    image

    使用mapv

    mapv是百度地图官方推出的地理信息可视化开源库,借助其也能进行大量坐标点的添加操作。

    官方API

    它是使用canvas在地图上添加了一层,能保证速度和自定义点图标,首先导入mapv的库$npm install mapv,或者:

    <script src="//mapv.baidu.com/build/mapv.min.js"></script>
    

    点的数据格式

    [
        {
            geometry: {
                type: 'Point',
                coordinates: [123, 23]
            },
            fillStyle: 'red',
            size: 30
        },
        {
            geometry: {
                type: 'Point',
                coordinates: [121, 33]
            },
            fillStyle: 'rgba(255, 255, 50, 0.5)',
            size: 90
        }
    ]
    

    配置项说明

    {
        zIndex: 1, // 层级
        size: 5, // 大小值
        fillStyle: 'rgba(200, 200, 50, 1)', // 填充颜色
        strokeStyle: 'rgba(0, 0, 255, 1)', // 描边颜色
        lineWidth: 4, // 描边宽度
        globalAlpha: 1, // 透明度
        globalCompositeOperation: 'lighter', // 颜色叠加方式
        shadowColor: 'rgba(255, 255, 255, 1)', // 投影颜色
        shadowBlur: 35,  // 投影模糊级数
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        lineCap: 'butt',
        lineJoin: 'miter',
        miterLimit: 10
    }
    

    mapv添加大量点的方法:

    makeMapvPoints(map, data) {
        if (document.createElement('canvas').getContext) {
            // 使用自定义坐标点图形
            var img = new Image()
            img.src = this.bluePoint
    
            // 创建mapv配置项
            const iconOpt = {
                draw: 'icon',
                 32,
                height: 38,
                methods: {
                    click: item => {
                        if (item) console.log(item)
                    }
                }
            }
    
            // 在图片加载后再创建图层才能自定义图标
            img.onload = function () {
                // 点坐标的数组
                const dataSet = []
                // 构建dataset格式数据
                data.forEach(point => {
                    const geometry = {}
                    geometry.type = 'Point'
                    geometry.coordinates = [point.lng, point.lat]
                    dataSet.push({
                        geometry,
                        icon: img,
                        tag: { name: point.name }
                    })
                })
    
                const mapSet = new mapv.DataSet(dataSet)
                // dataSet.set(data) // 修改数据
    
                // 叠加图层
                const mapvLayer = new mapv.baiduMapLayer(map, mapSet, iconOpt)
                // 显示图层
                mapvLayer.show()
                // mapvLayer.hide() // 隐藏图层
            }
        } else {
            alert('浏览器不支持,请使用chrome、safari、IE8+以上浏览器')
        }
    }
    

    注意:

    1. 在使用自定义图标icon时,必须设置widthheight或者size。否则坐标点的点击事件无法触发。
    2. 在使用点击事件回调时,要判断回调的参数是否为null。因为该事件总能触发(在有无坐标点击都能触发),无坐标点点击返回null,有则非空。
      image
      image

    补充

    地理坐标查询 - 拾取坐标系统

    地理坐标查询 - 拾取坐标系统

  • 相关阅读:
    Python 15 爬虫(一)
    Python 14 Mysql数据库(二)
    Python 13 JQuery&Bootstrp
    Python 12 CSS&JavaScript&DOOM
    Python 11 HTML
    Python 10 MySQL数据库(一)
    Python 9 Redis
    Python 8 协程
    Python 7 并发编程
    SNMP协议详解
  • 原文地址:https://www.cnblogs.com/flytree/p/15121173.html
Copyright © 2011-2022 走看看