• Leaflet 加载高德地图


    cover

    前言

    在前面的文章中,我们学习了如何使用 Leaflet 创建一个基本的地图。在本文中,我们将学习如何在 Leaflet 中加载高德地图,并结合实际应用构建地图点击事件。

    一、介绍

    高德地图是一款由高德软件提供的数字地图服务,在国内使用较为广泛。高德地图提供了丰富的地图数据和 API 接口,支持 Web、移动端等多种平台。本文中,我们将高德地图的wms服务加入leaflet地图对象,并构建点击事件输出高德坐标和WGS-84坐标;

    二、内容

    1.在 Leaflet 中加载高德地图

    地图初始化教程看上一篇文章

    在 Leaflet 中,我们可以使用 L.tileLayer() 方法加载高德地图。以下是一个加载高德地图的例子:

    // 使用高德的WMS服务
    var layer = L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
        subdomains: ['1', '2', '3', '4'],
        minZoom: 1, // 最小放缩级别
        maxZoom: 19 // 最大放缩级别
    });
    map.addLayer(layer);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果想要加载影像图层,则修改wms服务url:

    var layer = L.tileLayer('http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
        subdomains: ['1', '2', '3', '4'],
        minZoom: 1,
        maxZoom: 19
    })
    map.addLayer(layer);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    subdomains 是一个可选参数,用于指定瓦片服务器的子域名。在这个例子中,高德地图提供了四个子域名用于加载瓦片图层,分别是 webrd01.is.autonavi.com、webrd02.is.autonavi.com、webrd03.is.autonavi.com 和 webrd04.is.autonavi.com。
    通过使用多个子域名,可以提高地图瓦片的加载速度,因为浏览器对于同一域名下的并行连接有限制。由于每个子域名都可以被视为不同的域名,因此使用多个子域名可以提高浏览器对瓦片的并行下载数量,从而提高地图加载速度

    在这个例子中,我们使用了高德地图的 WMS 服务,通过 L.tileLayer() 方法创建了一个瓦片图层,并将其添加到地图容器中。

    2.构建点击事件

    我们这里构建一个地图点击事件,点击哪里则视图飞行至指定位置并放大至指定视图级别:

    map.on("click", (evt) => {
        console.log(evt);
        map.flyTo(evt.latlng, 13); //参数1是中心点经纬度,参数2是缩放级别
    });
    
    • 1
    • 2
    • 3
    • 4

    3.坐标转换

    当然我们点击事件得到的坐标的坐标系是高德的火星坐标系,而非通用的wgs84坐标系,因此我们需要进行坐标转换;
    因为高德官方只提供了其他坐标系转高德坐标系的API,我们这里想要将高德坐标转换为WGS84坐标需要自定义转换函数,代码如下:

    //定义一些常量
    const PI = 3.1415926535897932384626;
    const a = 6378245.0;  //长半轴
    const ee = 0.00669342162296594323; //扁率
    
    /**
     * GCJ02 转换为 WGS84
     * @param lng
     * @param lat
     * @returns {*[]}
     */
    function gcj02towgs84 (lng, lat) {
      lat = +lat
      lng = +lng
      if (out_of_china(lng, lat)) {
        return [lng, lat]
      } else {
        let dlat = transformlat(lng - 105.0, lat - 35.0)
        let dlng = transformlng(lng - 105.0, lat - 35.0)
        let radlat = lat / 180.0 * PI
        let magic = Math.sin(radlat)
        magic = 1 - ee * magic * magic
        let sqrtmagic = Math.sqrt(magic)
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
        let mglat = lat + dlat
        let mglng = lng + dlng
        return [lng * 2 - mglng, lat * 2 - mglat]
      }
    }
    
    /**
     * 判断是否在国内,不在国内则不做偏移
     * @param lng
     * @param lat
     * @returns {boolean}
     */
    function out_of_china (lng, lat) {
      lat = +lat
      lng = +lng
      // 纬度3.86~53.55,经度73.66~135.05
      return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
    }
    
    function transformlat (lng, lat) {
      lat = +lat
      lng = +lng
      let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
      ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
      ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
      ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
      return ret
    }
    
    function transformlng (lng, lat) {
      lat = +lat
      lng = +lng
      let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
      ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
      ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
      ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
      return ret
    }
    
    let coords = gcj02towgs84(evt.latlng.lng, evt.latlng.lat); // 将高德坐标转化为wgs84坐标
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    4.完整代码

    以下是一个完整的在 Leaflet 中加载高德地图的示例代码:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Leaflet 加载高德地图title>
        <script src="https://lib.baomitu.com/leaflet/1.9.2/leaflet.js">script>
        <link rel="stylesheet" href="https://lib.baomitu.com/leaflet/1.9.2/leaflet.css">
        <style>
            * {
                margin: 0;
                padding: 0
            }
            #map {
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                cursor: pointer;
            }
        style>
    head>
    <body>
        <div id="map">div>
        <script>
            //定义一些常量
            const PI = 3.1415926535897932384626;
            const a = 6378245.0;  //长半轴
            const ee = 0.00669342162296594323; //扁率
    
            /**
             * GCJ02 转换为 WGS84
             * @param lng
             * @param lat
             * @returns {*[]}
             */
            function gcj02towgs84 (lng, lat) {
              lat = +lat
              lng = +lng
              if (out_of_china(lng, lat)) {
                return [lng, lat]
              } else {
                let dlat = transformlat(lng - 105.0, lat - 35.0)
                let dlng = transformlng(lng - 105.0, lat - 35.0)
                let radlat = lat / 180.0 * PI
                let magic = Math.sin(radlat)
                magic = 1 - ee * magic * magic
                let sqrtmagic = Math.sqrt(magic)
                dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
                dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
                let mglat = lat + dlat
                let mglng = lng + dlng
                return [lng * 2 - mglng, lat * 2 - mglat]
              }
            }
    
            /**
             * 判断是否在国内,不在国内则不做偏移
             * @param lng
             * @param lat
             * @returns {boolean}
             */
            function out_of_china (lng, lat) {
              lat = +lat
              lng = +lng
              // 纬度3.86~53.55,经度73.66~135.05
              return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
            }
    
            function transformlat (lng, lat) {
              lat = +lat
              lng = +lng
              let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
              ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
              ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
              ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
              return ret
            }
    
            function transformlng (lng, lat) {
              lat = +lat
              lng = +lng
              let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
              ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
              ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
              ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
              return ret
            }
    
            var map = L.map("map").setView([31.5, 121.5], 10);
            //使用高德的WMS服务
            var layer = L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
                subdomains: ['1', '2', '3', '4'],
                minZoom: 1,
                maxZoom: 19
            })
            map.addLayer(layer);
            map.on("click", (evt) => {
                console.log("高德坐标:",evt.latlng.lat,evt.latlng.lng);
                let coords = gcj02towgs84(evt.latlng.lng, evt.latlng.lat);
                console.log("wgs-84坐标:",coords[1],coords[0]);
                map.flyTo(evt.latlng, 13); //参数1是中心点经纬度,参数2是缩放级别
            });
        script>
    body>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109

    实现效果如下:
    高德底图矢量
    高德影像

    三、总结

    在本文中,我们学习了如何在 Leaflet 中加载高德地图,并构建了地图点击事件和坐标转换函数。通过实际案例,我们了解了如何在 leaflet 中使用高德地图的矢量和影像底图,并结合相关API进行项目开发。

    文章参考

    项目地址


    如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.

  • 相关阅读:
    【学习笔记】[AGC064C] Erase and Divide Game
    Java虚拟机启动整体流程和基础学习(内容很多,不可快餐阅读),推理+源码论证
    Ubuntu20.04.4 LTS正确安装方案及问题解决
    中国人民大学与加拿大女王大学金融硕士——不忘初心,点燃梦想之火
    算法数据结构体系学习 第十一节
    Nacos的作用及用法
    坚持100天学习打卡Day1
    【39】MESI协议:如何让多核CPU的高速缓存保持一致?
    文字转语音的软件哪个最好?分享几个宝藏软件给你们
    一、CSS背景样式[背景样式、盒子阴影]
  • 原文地址:https://blog.csdn.net/qq_45590504/article/details/136437182