Leaflet 加载高德地图

news2024/7/3 19:47:58

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);

如果想要加载影像图层,则修改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);

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是缩放级别
});

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坐标

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>

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

三、总结

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

文章参考

  • Leaflet 官方文档:https://leafletjs.com/reference.html

项目地址

  • Github地址
  • 拓展阅读

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1489650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在国内如何申请US,visa卡?

随着跨境与AI的发展大家对美国虚拟卡的需求也越来越多&#xff0c;比如说亚马逊、ebay、Etsy、ChatGPTPLUS、midjourney、POE等等软件以及海淘的需要&#xff0c;所以我们需要用到美国虚拟卡的场景就越来越多 如何获得一张US 虚拟信用卡&#xff1f; 方法很简单&#xff0c;点…

React-子传父

1.概念 说明&#xff1a;React中子组件向父组件传递数据通常涉及回调函数和状态提升等方法。 2.代码实现 2.1绑定事件 说明&#xff1a;父组件绑定自定义事件 <Son onGetSonMsg{getMsg}></Son> 2.2接受事件 说明&#xff1a;子组件接受父组件的自定义事件名称…

【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &#x1f680; 本…

【Pytorch入门】常见Transforms/ __call__方法

在Python中&#xff0c;__call__方法是一个特殊方法&#xff0c;用于使对象可以像函数一样被调用。当一个对象实现了__call__方法时&#xff0c;可以直接使用括号运算符将对象作为函数调用。 通过实现__call__方法&#xff0c;可以为对象提供函数式的行为&#xff0c;使其更加…

超全Chat GPT论文修改指令

文献综述指令润色修改指令论文选题指令论文大指令研究理论指令论文致谢指令参考文献指令论文润色整体逻辑论文整体优化提问指令 1&#xff0e;文献综述指令 请你帮我写一份关于&#xff08;研究主题&#xff09;的文献综述。我的论文选题方向是 XXXX &#xff0c;我已经找到了…

Vue.js 修饰符:精准控制组件行为

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

IDEA中Maven无法下载jar包问题解决

在项目中经常会遇到jar包无法下载的问题&#xff0c;可以根据以下几种方法进行排查。 1. 排查网络连接 网络连接失败&#xff0c;会导致远程访问Maven仓库失败&#xff0c;所以应确保网络连接正常。 2. 排查Maven的配置 Maven配置文件&#xff08;settings.xml&#xff09;…

《数字图像处理(MATLAB版)》相关算法代码及其分析(3)

目录 1 对边界进行子采样 1.1 输入参数检查 1.2 处理重复坐标 1.3 计算边界最大范围 1.4 确定网格线数量 1.5 构建网格位置向量 1.6 计算曼哈顿距离 1.7 整理输出结果 1.8 返回结果 2 改变图像的存储类别 2.1 函数输入 2.2 数据类型转换 2.3 错误处理 2.4 返回结…

LabVIEW高温摩擦磨损测试系统

LabVIEW高温摩擦磨损测试系统 介绍了一个基于LabVIEW的高温摩擦磨损测试系统的软件开发项目。该系统实现高温条件下材料摩擦磨损特性的自动化测试&#xff0c;通过精确控制和数据采集&#xff0c;为材料性能研究提供重要数据支持。 项目背景 随着材料科学的发展&#xff0c;…

视觉Transformers中的位置嵌入 - 研究与应用指南

视觉 Transformer 中位置嵌入背后的数学和代码简介。 自从 2017 年推出《Attention is All You Need》以来&#xff0c;Transformer 已成为自然语言处理 (NLP) 领域最先进的技术。 2021 年&#xff0c;An Image is Worth 16x16 Words 成功地将 Transformer 应用于计算机视觉任务…

小迪安全31WEB 攻防-通用漏洞文件上传js 验证mimeuser.ini语言特性

#知识点&#xff1a; 1、文件上传-前端验证 2、文件上传-黑白名单 3、文件上传-user.ini 妙用 4、文件上传-PHP 语言特性 #详细点&#xff1a; 检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c;二次渲染…

docker快照备份回滚

1. 安装系统 1.1 vm安装Ubuntu 参考:https://blog.csdn.net/u010308917/article/details/125157774 1.2 其他操作 添加自定义物理卷 –待补充– 1.2.1 查询可用物理卷 fdisk -l 输出如下 Disk /dev/loop0: 73.9 MiB, 77492224 bytes, 151352 sectors Units: sectors of …

Vue 项目重复点击菜单刷新当前页面

需求&#xff1a;“在当前页面点击当前页面对应的菜单时&#xff0c;也能刷新页面。” 由于 Vue 项目的路由机制是路由不变的情况下&#xff0c;对应的组件是不重新渲染的。所以重复点击菜单不会改变路由&#xff0c;然后页面就无法刷新了。 方案一 在vue项目中&#xff0c;…

英特尔/ARM/国产化EMS储能控制器解决方案

新型储能是建设新型电⼒系统、推动能源绿⾊低碳转型的重要装备基础和关键⽀撑技术&#xff0c;是实现碳达峰、碳中和⽬标的重要⽀撑。说到储能&#xff0c;大众首先想到的就是电池&#xff0c;其好坏关系到能量转换效率、系统寿命和安全等重要方面&#xff0c;但储能要想作为一…

[LeetBook]【学习日记】数组内乘积

题目 按规则计算统计结果 为了深入了解这些生物群体的生态特征&#xff0c;你们进行了大量的实地观察和数据采集。数组 arrayA 记录了各个生物群体数量数据&#xff0c;其中 arrayA[i] 表示第 i 个生物群体的数量。请返回一个数组 arrayB&#xff0c;该数组为基于数组 arrayA …

vue点击按钮同时下载多个文件

点击下载按钮根据需要的id调接口拿到返回需要下载的文件 再看返回的数据结构 数组中一个对象&#xff0c;就是一个文件&#xff0c;多个对象就是多个文件 下载函数 // 下载tableDownload(row) {getuploadInventoryDownload({ sysBatch: row.sysBatch, fileName: row.fileName…

STM32 TIM编码器接口

单片机学习&#xff01; 目录 文章目录 前言 一、编码器接口简介 1.1 编码器接口作用 1.2 编码器接口工作流程 1.3 编码器接口资源分布 1.4 编码器接口输入引脚 二、正交编码器 2.1 正交编码器功能 2.2 引脚作用 2.3 如何测量方向 2.4 正交信号优势 2.5 执行逻辑 三、编码器定时…

前端+php:实现提示框(自动消失)

效果 php部分&#xff1a;只展示插入过程 <?php//插入注册表中$sql_insert "INSERT INTO regist_user(userid,password,phone,email)VALUES (" . $_POST[UserID] . "," . CryptPass($_POST[Password]) . "," . $_POST[Phone] . ",&qu…

“而且,再加上”可以用哪个语法来表示,柯桥考级韩语学习

语法 --는/은/ㄴ 데다가 1.语法&#xff1a;는/은/ㄴ 데다가 2.表示&#xff1a;用于谓词词干和体词谓词形后, 表示在原有的状况上再加上其他情况。 3.添加&#xff1a; 4.例句&#xff1a; 当然&#xff0c;与这个语法含义相近的还有不少语法&#xff0c;有一部分是初级暂时…

【AI视野·今日NLP 自然语言处理论文速览 第八十期】Fri, 1 Mar 2024

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 1 Mar 2024 Totally 67 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Loose LIPS Sink Ships: Asking Questions in Battleship with Language-Informed Program Sampling Authors G…