文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Uniapp】高德地图的接入、定位、自定义标点与信息窗体使用

2023-08-30 12:27

关注

一、前言

因为公司的业务需求,需要实现一个接入高德地图的数据大屏,并根据坐标实现地图标点渲染,自定义信息窗体,点击定位等功能。查阅高德地图官方文档时发现使用的是原生 JavaScript ,且网上 uniapp 接入使用的教程较少,我自己摸索之后解决了不少问题,欢迎大佬补充纠正。

二、准备工作

1、参考博客以及相关地址

高德开发平台:平台地址

注册参考博客:博客地址

2、注册高德开发平台账号

我们需要先在高德开放平台注册一个账号,以申请获取 key 等权限信息。注册流程很简单,就不赘述了,获取成功后点击此处:

image-20230504100153524

点击创建新应用,至于里面的内容就是随便填都可以:

image-20230504100638922

点击添加 Key ,创建你的 Key 值,我们后面都需要使用,具体你是哪个开发平台就勾选哪一个:

image-20230504100932468

下面是最后生成的 Key。在参考博客中是直接使用 key 获取并本地导入下载的SDK,而我使用的是动态导入,大家可以尝试一下哪个更适合你的开发。

image-20230504101121345

三、导入以及使用

以下内容较多篇幅较长,大家可以根据目录选择阅读,我会结合官方文档以及参考文档详细说明每一个方法的使用以及具体实现,但最好还是按顺序看下去。

1、参考博客与文档以及相关地址

高德官方文档:地址

开发参考博客:地址(不是我的博客)

2、导入SDK

在导入这一块我尝试了很多种方法,最终实现的是这个方法:怎么引入高德地图 ,通过这个方法可以定义一个全局的地图实例供我们调用高德API。

效果

image-20230504142312187

代码

<template><!-- 地图底框 --><view id="wrapper"></view></template><script>    let mapObj = null; // 生成地图实例    window.mapInit = function() {mapObj = new AMap.Map('wrapper', {center: [113.382, 22.5211],layers: [new AMap.TileLayer.Satellite(), // 卫星new AMap.TileLayer.RoadNet() // 路网],zoom: 13});// 在这里可以做一些回调处理  定位 标记点 等等  或者把amap弄成一个全局变量// 引入单个插件AMap.plugin('AMap.ToolBar', function() { // 异步加载插件var toolbar = new AMap.ToolBar();map.addControl(toolbar);});};    export default {        data() {}onLoad() {// #ifdef H5this.loadScrpit();// #endif},         methods: {             loadScrpit() { // 挂载动态jsvar script = document.createElement('script');script.src = 'https://webapi.amap.com/maps?v=1.4.15&key=(这里是你申请的KEY)&callback=mapInit';document.body.appendChild(script);},         }    }</script>

代码讲解

首先是在 onLoad() 在页面加载阶段内调用动态挂载函数,熟悉原生 JavaScript 的朋友都应该可以明白这是一个创建 标签,并把它插入 body 内的操作。关键是在标签的属性上,我们需要传入 Key 值和回调函数。

📌 此处的回调函数可以取任意名,但需要注意的是在 window.function() 接收函数时需要同名,否则无法成功接收回调函数。

mapObj = new AMap.Map('wrapper', {center: [Longitude, Latitude],layers: [new AMap.TileLayer.Satellite(), // 卫星new AMap.TileLayer.RoadNet() // 路网],zoom: 13});

在本文中我使用 mapObj 全局存储地图的实例, new AMap.Map('id',Object) 的参数:

3、点击坐标定位

点击代码实际上和挂载地图是一样的代码,只需要修改中心点的位置,重新挂载即可。但问题也随之出现,如果你已经设置了标点坐标与信息窗体,重新挂载后将会消除这些信息,你需要再次挂载这些信息。也就是说你如果需要保存定位前的标点,需要先保存对应的坐标。

代码

mapObj = new AMap.Map('wrapper', {center: [Longitude, Latitude],layers: [new AMap.TileLayer.Satellite(), // 卫星new AMap.TileLayer.RoadNet() // 路网],zoom: 13});

代码讲解

基本和上面说的一样,只要替换中心的定位坐标即可。在下面你会了解到如何挂载自定义标点与信息窗体,这些信息都会在你定位后消失,需要重新挂载,也就是保存坐标信息再次挂载坐标标点。

4、自定义标点

自定义标点主要是定义图标的图像以及大小、偏移量等参数。需要注意的是,标点自定义必须在地图实例挂载之后,否则无法定义成功。自定义标点信息成功后再挂载标点,最后实现的就是下图效果。

效果

image-20230612101134611

代码

<template><!-- 地图底框 --><view id="wrapper"></view></template><script>    let mapObj = null; // 生成地图实例    // ------------------------------ 更新内容1 ----------------------------- //    let icon = null; // 生成图片实例let punctuation = []; // 生成标点实例    // ---------------------------------------------------------------------- //    window.mapInit = function() {mapObj = new AMap.Map('wrapper', {center: [Longitude, Latitude],layers: [new AMap.TileLayer.Satellite(), // 卫星new AMap.TileLayer.RoadNet() // 路网],zoom: 13});// 在这里可以做一些回调处理  定位 标记点 等等  或者把amap弄成一个全局变量// 引入单个插件AMap.plugin('AMap.ToolBar', function() { // 异步加载插件var toolbar = new AMap.ToolBar();map.addControl(toolbar);});};    export default {        data() {}onLoad() {// #ifdef H5this.loadScrpit();// #endif         // ------------------------------ 更新内容2 ----------------------------- //            let time = setInterval(() => { // 等待地图挂载后再自定义标点if (mapObj != null) {this.setIcon(); // 挂载坐标图片信息this.getCoordinateList(type); // 获取坐标clearInterval(time);}}, 100)          // ---------------------------------------------------------------------- //},         methods: {             loadScrpit() { // 挂载动态jsvar script = document.createElement('script');script.src = 'https://webapi.amap.com/maps?v=1.4.15&key=(这里是你申请的KEY)&callback=mapInit';document.body.appendChild(script);},     // ------------------------------ 更新内容3 ----------------------------- //             setIcon() { // 设置icon// 创建 AMap.Icon 实例icon = new AMap.Icon({size: new AMap.Size(48, 60), // 图标尺寸image: "image.png", // Icon的图像imageSize: new AMap.Size(48, 60), // 根据所设置的大小拉伸或压缩图片imageOffset: new AMap.Pixel(0, 0) // 图像相对展示区域的偏移量,适于雪碧图等});},getCoordinateList(type) { // 获取坐标uni.request({url: this.url_str, // 你的请求后台的地址method: 'GET',data: {region: '你的地区参数',},success: (e) => {console.log(e);mapObj.remove(punctuation);this.setMapMarkerList(this.list); // 赋予坐标图片标点}})},            setMapMarkerList(list) { // 批量生成标点let that = this;// console.log(list);list.forEach(function(marker) {let punctuationItem = new AMap.Marker({map: mapObj,icon: icon,position: [marker.Longitude, marker.Latitude],offset: new AMap.Pixel(-13, -30)});punctuation.push(punctuationItem);});},            // ---------------------------------------------------------------------- //         }    }</script>

代码讲解

更新内容1:创建全局的图片的实例 icon,只需要创建一次,直到更换标点图案。全局的标点按需加载,每次跳转与切换坐标定位,都需要重新挂载。

let icon = null; // 生成标点图片实例let punctuation = []; // 生成标点实例

更新内容2:在 onLoad() 里设置定时器监听地图是否挂载成功,没挂载地图实例前无法挂载标点图片与坐标标点。一旦监听到地图组件挂载便取消对应的定时器监听。

let time = setInterval(() => { // 等待地图挂载后再自定义标点if (mapObj != null) {this.setIcon(); // 挂载坐标图片信息this.getCoordinateList(type); // 获取坐标并挂载坐标标点clearInterval(time);}}, 100)

更新内容3:

  • setIcon(): 设置自定义标点图片的参数,具体的参数看下面介绍,按照对应的测试一下就可以调整为自己想要的效果了。
  • getCoordinateList(): 请求获取所需的坐标信息,在赋予标点时需要根据对应的坐标信息进行挂载。这里需要注意的是 mapObj.remove(punctuation) 这行代码,它用于去除过往的标点,当你需要根据不同的地区筛选时就需要使用这个去除旧的标点。
  • setMapMarkerList():请求标点后,调用该函数传入标点坐标,通过循环批量生成标点,并且存入 punctuation 以备后期需要消除标点使用。
setIcon() { // 设置icon// 创建 AMap.Icon 实例icon = new AMap.Icon({size: new AMap.Size(48, 60), // 图标尺寸image: "image.png", // Icon的图像imageSize: new AMap.Size(48, 60), // 根据所设置的大小拉伸或压缩图片imageOffset: new AMap.Pixel(0, 0) // 图像相对展示区域的偏移量,适于雪碧图等});},getCoordinateList(type) { // 获取坐标uni.request({url: this.url_str, // 你的请求后台的地址method: 'GET',data: {region: '你的地区参数',},success: (e) => {console.log(e);mapObj.remove(punctuation);             this.list = e.data.list;this.setMapMarkerList(this.list); // 赋予坐标图片标点}})},setMapMarkerList(list) { // 批量生成标点let that = this;// console.log(list);list.forEach(function(marker) {let punctuationItem = new AMap.Marker({map: mapObj,icon: icon,position: [marker.Longitude, marker.Latitude],offset: new AMap.Pixel(-13, -30)});punctuation.push(punctuationItem);});},

5、自定义信息框体

实现信息框体功能,实际上就是为标点绑定一个点击事件,点击后再对相应的标点进行渲染。难点主要在如何渲染信息窗体数据并且在信息窗体内绑定点击事件。

效果

image-20230616154841089

代码

<template><!-- 地图底框 --><view id="wrapper"></view></template><script>    let mapObj = null; // 生成地图实例    let icon = null; // 生成图片实例let punctuation = []; // 生成标点实例    // ------------------------------ 更新内容1 ----------------------------- //    let infoWindow = null // 信息窗体let isShowText = false; // 窗体是否打开    // ---------------------------------------------------------------------- //    window.mapInit = function() {mapObj = new AMap.Map('wrapper', {center: [Longitude, Latitude],layers: [new AMap.TileLayer.Satellite(), // 卫星new AMap.TileLayer.RoadNet() // 路网],zoom: 13});        // ------------------------------ 更新内容2 ----------------------------- //        mapObj.on('click', () => {if (isShowText) {isShowText = false;infoWindow.close();}});infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30),isCustom: true,});        // ---------------------------------------------------------------------- //// 在这里可以做一些回调处理  定位 标记点 等等  或者把amap弄成一个全局变量// 引入单个插件AMap.plugin('AMap.ToolBar', function() { // 异步加载插件var toolbar = new AMap.ToolBar();map.addControl(toolbar);});};    export default {        data() {}onLoad() {// #ifdef H5this.loadScrpit();// #endif            let time = setInterval(() => { // 等待地图挂载后再自定义标点if (mapObj != null) {this.setIcon(); // 挂载坐标图片信息this.getCoordinateList(type); // 获取坐标clearInterval(time);}}, 100)},         // ------------------------------ 更新内容3 ----------------------------- //         created() {let that = this;window.getParkDetail = function() {that.isBottomShow = false;that.isList = false;isShowText = false;infoWindow.close();};},        // ---------------------------------------------------------------------- //         methods: {             loadScrpit() { // 挂载动态jsvar script = document.createElement('script');script.src = 'https://webapi.amap.com/maps?v=1.4.15&key=(这里是你申请的KEY)&callback=mapInit';document.body.appendChild(script);},             setIcon() { // 设置icon...},getCoordinateList(type) { // 获取坐标...},                        setMapMarkerList(list) { // 批量生成标点let that = this;// console.log(list);list.forEach(function(marker) {let punctuationItem = new AMap.Marker({map: mapObj,icon: icon,position: [marker.Longitude, marker.Latitude],offset: new AMap.Pixel(-13, -30)});                      // ----------------------------- 更新内容4 ----------------------------- //                      punctuationItem.Id = marker.Id;punctuationItem.on('click', that.markerClick);                      // -------------------------------------------------------------------- //punctuation.push(punctuationItem);});},             // ------------------------------ 更新内容5 ----------------------------- //             markerClick(e) {let that = this;uni.request({url: this.url_str,method: 'GET',data: {Id: e.target.Id,},success: (res) => {let content =`
${res.Img}">
${res.Name}
项目区域:
${res.Region}
项目地址:
${res.Region}${res.Address}
入驻企业:
${res.Client}
查看详情
`
;infoWindow.setContent(content);infoWindow.open(mapObj, e.target.getPosition());isShowText = true;}})}, // ---------------------------------------------------------------------- // } }</script>

代码讲解

更新内容1:创建全局的的实例 infoWindow ,也是只要挂载一次即可。主要用于信息窗体的打开与关闭。

isShowText 是用于判断当前的窗体是否打开,在点击或移动地图时关闭窗体。

let infoWindow = null // 信息窗体let isShowText = false; // 窗体是否打开

更新内容2:mapObj 是地图实例,可以给它绑定点击事件,根据 isShowText 的状态来判定是否开启了窗体。infoWindow.close() 方法用于关闭当前窗体。

窗体的方法调用不用等待 new AMap.InfoWindow() 创建实例,因为没有也触发不了关闭🤣。

  • offset:信息窗体距离标点的偏移量,这个具体的参数需要你们自己调整了。
  • isCustom:是指是否开启自定义信息窗体,这个设置为 true 就好了。
mapObj.on('click', () => {if (isShowText) {isShowText = false;infoWindow.close();}});infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30),isCustom: true,});

更新内容3:这个方法是直接挂载在window对象上,这样才可以被信息窗体内的事件所触发。主要用于关闭当前的信息窗体,打开某个界面或是跳转到某个链接网址。

需要的操作就写在这里面 getParkDetail() 这个函数名不是固定的,你可以根据自己的业务功能重新命名。

created() {let that = this;window.getParkDetail = function() {that.isBottomShow = true; // 打开某个显示框that.isList = true; // 打开某个列表isShowText = false;infoWindow.close();};},

更新内容4:这个 Id 就只是当初的用做全球的参数,如果你不需要的话也不用加上。重点在于绑定的点击事件。这个点击事件决定了信息窗体的挂载,当点击标点时,触发该动态渲染信息窗体的方法。

punctuationItem.Id = marker.Id;punctuationItem.on('click', that.markerClick);

更新内容5:我们信息窗体里的内容肯定是动态渲染的,这就需要我们去重新请求来获取具体的详情。

infoWindow.setContent() 方法可以向当前的信息窗体实例添加自定义的内容,因为太长了,我移除了大段的代码,具体的写法请参照上文,在下文 content 的内容里会做一部分的讲解。

我们通过 infoWindow.open() 方法打开当前的信息窗体,第一个参数是当前挂载信息窗体的地图 mapObj ,第二个参数就是它当前的位置的获取方法,这个是固定的没有什么需要注意。

markerClick(e) {let that = this;uni.request({url: this.url_str,method: 'GET',data: {Id: e.target.Id,},success: (res) => {let content; // 添加的内容,详见下文infoWindow.setContent(content); // 渲染infoWindow.open(mapObj, e.target.getPosition());isShowText = true;}})},

content 的内容:

  • 这里因为我们需要动态添加内容,我们需要使用到 模板字符串 的格式,直接无提示写 dom 确实比较麻烦,新手记不住可以先去把样式写好再拷进来。这里是必须写原生,不然无法正常显示。

  • 在宽高这里,它是支持 vw 和 vh 的,写大屏的时候可以用这个,或者你直接写固定也可以。

  • 绑定点击事件这里必须用自启动函数来调用你挂载在 window 对象的方法,不然没有办法直接对事件进行处理,如果你有更好的方法欢迎评论区补充指正👍。

  • ${res.Client} 就是模板字符串的写法,没有很难的地方,详见 模板字符串 的文档。

let content = `
查看详情
${res.Client}">
`

四、结尾

本文仅记录我个人的解决思路,在封装或是调用等方面上会有所欠缺,欢迎大佬指正补充相关方面的技术博客与文档。如果有什么疑问也欢迎大家评论区或是私信我,我看见就会回复。

如果本文有帮助到你,可否给我一个赞,你的支持就是我创作的动力👍。

来源地址:https://blog.csdn.net/get_404/article/details/131289225

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯