uniapp地图开发(APP,H5)

uniapp地图开发(APP,H5)

  • 背景
  • 实现
    • 页面实现
    • 功能实现
    • 注意事项
  • 尾巴

背景

最近项目中需要使用地图相关功能,需要用到聚合,marker拖拽,自定义marker显示内容,根据角色不同maker显示不同图标等功能。查阅了uniapp官方API关于map相关的文档,发现官方API支持有限,很多功能无法实现或者不支持。而且地图相关页面还有很多弹窗,APP端必须使用nvue才能实现同层渲染,而nvue用起来有有诸多限制,比如无法使用封装的全局方法之类的。一番摸索之后我觉得放弃官方map组件,使用renderJs配合地图商js API来实现功能。这里以高德地图为例,老规矩先上个图镇楼:
请添加图片描述

实现

新建一个vue页面,并引入renderjs相关的script标签,模板中新增一个div标签(必须要设置id)用来承载高德地图。

页面实现

模板部分:

<template>
	<view class="content">
		<!--这里maph可以设置为整个页面高度,或者自定义-->
		<div id='container' class="map" :style="'height:' + maph + 'px;'"></div>
	</view>
</template>

renderjs中mounted引入js API

...
const script = document.createElement('script');
//这里key要去高德官网去申请
script.src = 'https://webapi.amap.com/maps?v=2.0&key=you key';
script.onload = this.initAmap.bind(this);
document.head.appendChild(script);
...

功能实现

主要是根据你项目的功能去调用高德地图API。上面示例图中用到了聚合,点拖拽,自定义marker上的label,自定义聚合簇样式等,更多丰富用法可以参考官方文档。
其实到这里也没有啥好说的,就一个页面,主要还是根据自己项目功能参考官方文档为主,下面就将整个页面代码贴出供大家参考:

<template>
	<view class="content">
		<div id='container' class="map" :style="'height:' + maph + 'px;'"></div>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				maph: 0
			}
		},
		onLoad() {
			this.maph = uni.getSystemInfoSync().windowHeight
		},
		methods: {

		}
	}
</script>
<script module="renderJS" lang="renderjs">
	var loadSdk = false; //是否已经加载完成地图sdk
	export default {
		data() {
			return {
				map: null
			}
		},
		mounted() {
			//这里安全码也是要自己申请
			window._AMapSecurityConfig = {
			    securityJsCode:'you code',
			}
			if (typeof window.AMap == 'function') {
				this.initAmap();
			} else {
				console.log('3333333333')
				// 动态引入较大类库避免影响页面展示
				const script = document.createElement('script');
				script.src = 'https://webapi.amap.com/maps?v=2.0&key=you key';
				script.onload = this.initAmap.bind(this);
				document.head.appendChild(script);
			}
		},
		methods: {
			initAmap(e, ownerVm) {
				//这里id必须跟模板中的容器id一样
				var map = new AMap.Map("container", {
					zoom: 12,  //设置地图显示的缩放级别
					center: [108.939621, 34.343147],  //设置地图中心点坐标
					//mapStyle: 'amap://styles/whitesmoke',  //设置地图的显示样式
					viewMode: '2D'  //设置地图模式
				});
				map.on('complete', () => {
					console.log('加载完成')
				})
				map.plugin(["AMap.Scale"],function(){
				    var scale = new AMap.Scale();
				    map.addControl(scale);
				});
				map.plugin(["AMap.ToolBar"],function(){
				    //加载工具条
				    var tool = new AMap.ToolBar();
				    map.addControl(tool);
				});
				map.plugin(["AMap.ControlBar"],function() {
				    var controlBar = new AMap.ControlBar()
				    map.addControl(controlBar)
				});
				
				var styles = [{
				    url:"https://a.amap.com/jsapi_demos/static/images/blue.png",
				    size:new AMap.Size(32,32),
				    offset:new AMap.Pixel(-16,-32),
					textColor: '#AACCFF'
				},
				{
				    url:"https://a.amap.com/jsapi_demos/static/images/green.png",
				    size:new AMap.Size(32,32),
				    offset:new AMap.Pixel(-16,-32),
					textColor: '#FFCE88'
				},
				{
				    url:"https://a.amap.com/jsapi_demos/static/images/green.png",
				    size:new AMap.Size(32,32),
				    offset:new AMap.Pixel(-16,-32),
				    textColor:'#CC0066'
				}];
				var points = [
					{lnglat: ["108.939621", "34.343147"] },
					{lnglat: ["108.932621", "34.313145"] },
					{lnglat: ["109.932621", "33.313147"] },
					{lnglat: ["109.132621", "33.913149"] },
					{lnglat: ["108.122621", "35.213148"] },
					{lnglat: ["109.522621", "34.013147"] },
					{lnglat: ["108.567621", "35.456127"] },
					{lnglat: ["107.212621", "33.953137"] },
					{lnglat: ["108.182621", "35.299147"] },
					{lnglat: ["109.900621", "34.209167"] },
					{lnglat: ["108.000521", "33.099014"] },
				];
				var cluster
				// 加载点聚合插件
				AMap.plugin(["AMap.MarkerCluster"], function() {
					if (cluster) {
					    cluster.setMap(null);
					}
					cluster = new AMap.MarkerCluster(map, points, {
						//gridSize: 80, // 聚合网格像素大小
						styles: styles,
						renderMarker: (content) => {
							let icon = new AMap.Icon({
								// 图标尺寸
								size: new AMap.Size(32, 32),
								// 图标的取图地址
								image: './static/mark.png',
								// 图标所用图片大小
								imageSize: new AMap.Size(32, 32),
								offset: new AMap.Pixel(-16, -32),
							});
							content.marker.setIcon(icon);
							content.marker.setDraggable(true)
							content.marker.on("dragend", res => {
								console.log('dragend',res.lnglat)
							})
							let label = {
								content: `<div style="display: flex;flex-direction: row;align-items: center;background: yellow;position:relative;margin:0;top:0;right:0;min-width:0;">
									<div style="padding: 3px 10px 3px 10px;background-color: aquamarine;border-radius: 8px;margin-right: 10px;">是的发送到</div>
									<div>水电费水电费</div>
								</div>`,
								direction: 'top'
							}
							content.marker.setLabel(label)
							content.marker.on('click', ev => {
								map.setZoomAndCenter(16, ev.target.getPosition());
							})
						},
						//配置此回调函数,上面配置的styles会失效
						renderClusterMarker: (context) => {
							context.marker.setOffset(new AMap.Pixel(-20, -40))
							context.marker.setContent(`<div style='background:red;color:white;border-radius: 50%;width:40px;height:40px;text-align:center;line-height:40px;'>${context.count}</div>`);
						}
					});

					cluster.on('click', (item) => {
						//此处是通过包含点的数量判断是否是聚合点,不是聚合点就执行上方单个点的点击方式
						if (item.clusterData.length <= 1) {
							return;
						}
						//这里是计算所有聚合点的中心点
						let alllng = 0,
							alllat = 0;
						for (const mo of item.clusterData) {
							alllng += mo.lnglat.lng;
							alllat += mo.lnglat.lat;
						}
						const lat = alllat / item.clusterData.length;
						const lng = alllng / item.clusterData.length;
						//这里是放大地图,此处写死了每次点击放大的级别,可以根据点的数量和当前大小适应放大,体验更佳
						var lnglat = new AMap.LngLat(lng, lat);
						map.setZoomAndCenter(map.getZoom() + 4, lnglat);
					});
				});

				//加载地理编码插件
				AMap.plugin(["AMap.Geocoder"], () => { //加载地理编码插件
					console.log('00000000000')
					var geocoder = new AMap.Geocoder({
					    city: '010' // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
					  })
					  
					  var address = '北京市海淀区苏州街';
					
					  geocoder.getLocation(address, function(status, result) {
						console.log('9999999999999',result,status)
					    if (status === 'complete' && result.info === 'OK') {
					      // result中对应详细地理坐标信息
					    }
					  })
				});

			}
		}
	}
</script>
<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}

	.map {
		z-index: 1;
		width: 750rpx;
	}

	.second {
		position: absolute;
		right: 0;
		bottom: 0;
		z-index: 9;
	}
	.amap-marker-label{
	    position: absolute;
	    z-index: 2;
	    border: 1px solid transparent;
	    background-color: #e5e5e5;
	    cursor: default;
	    padding: 3px;
	    font-size: 12px;
	    line-height: 14px;
		border-radius: 10px;
	}
	.test {
		display: flex;
		flex-direction: row;
		align-items: center;
		background: yellow;
	}
	.test1 {
		padding: 3px 10px 3px 10px;
		background-color: aquamarine;
		border-radius: 8px;
		margin-right: 10px;
	}
</style>

其实页面逻辑很简单,主要是涉及高德API调用来实现功能。这里还有个小bug,自定义dom label拖动地图和缩放地图可能会导致marker闪烁,我已经给官方提bug了,官方后续会修复。
在这里插入图片描述

注意事项

使用renderjs方式理论上还可以使用百度和腾讯地图,(腾讯地图有尝试过是可以的,百度地图没试过),这种方式支持H5和APP平台,微信小程序还是只能乖乖使用官方的地图组件进行开发,如果是跨平台项目记得区分。另外各地图厂商js API其实是给PC端用的,有些API放移动端可能不适用,具体看情况而定。

尾巴

今天的文章就到这里了,希望能给大家帮助,如果喜欢我的文章,欢迎给我点赞,评论,关注,谢谢大家!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos教程

常见的微服务架构&#xff1a; 1. dubbo: zookeeper dubbo SpringMVC/SpringBoot 配套 通信方式&#xff1a;rpc 注册中心&#xff1a;zookeeper / redis 2.SpringCloud &#xff1a; 全家桶 轻松嵌入第三方组件 (Netflix) 配套 通信方式&#xff1a;http restful 注册中心…

【MATLAB】史上最全的13种数据拟合算法全家桶

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 【MATLAB】傅里叶级数拟合算法 傅里叶级数拟合算法是一种强大而灵活的数学方法&#xff0c;可以将复杂的函数拆解成多个简单的正弦和余弦函数的和。通过求解函数中的系数&#xff0c;我们可以用有限项傅里叶级数来拟合…

类和对象(下篇)

再谈构造函数 构造函数体赋值 在之前的学习中我们知道&#xff0c;在创建一个对象时&#xff0c;我们的编译器就会自动调用构造函数将对象初始化&#xff0c;给对象中各个成员变量一个合适的初始值。 例如&#xff1a; class Date { public:Date(int year, int month, int d…

Java文件流大家族(通俗易懂,学习推荐版,很详细)——操作文件本身和文件中的数据

1.File&#xff08;操作文件本身&#xff09; 1.定义 目录 2.常用方法 3.路径引用符 可以用/或者\\分隔路径 还可以用File.separator分隔路径&#xff0c;会根据不同系统使用啥分隔符。 4.绝对路径、相对路径及桌面路径表示 桌面路径为&#xff1a; 我电脑的用户名为X 5.示例…

服务器数据恢复-误操作导致xfs分区数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌OceanStorT系列某型号存储MD1200磁盘柜&#xff0c;组建的raid5磁盘阵列。上层分配了1个lun&#xff0c;安装的linux操作系统&#xff0c;划分两个分区&#xff0c;分区一通过lvm进行扩容&#xff0c;分区二格式化为xfs文件系统。 服务器…

初级数据结构(七)——二叉树

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;六&#xff09;——堆 | NULL 下一篇-> 1、写在前面 二叉树的基本概念在《初级数据结构&#xff08;五&#xff09;——树和二叉树的概念》中已经介绍得足够详细了。上一…

海康威视对讲广播系统 RCE漏洞复现(CVE-2023-6895)

0x01 产品简介 Hikvision Intercom Broadcasting System是中国海康威视(Hikvision)公司的一个对讲广播系统。 0x02 漏洞概述 Hikvision Intercom Broadcasting System 3.0.3_20201113_RELEASE(HIK)版本存在操作系统命令注入漏洞,该漏洞源于文件/php/ping.php的参数jsonda…

虾皮跨境电商物流:打造高效便捷的全球供应链解决方案

随着全球化的推进和电子商务的蓬勃发展&#xff0c;跨境电商物流成为了越来越多商家和消费者关注的焦点。虾皮&#xff08;Shopee&#xff09;作为一家领先的电商平台&#xff0c;不仅提供了丰富多样的商品选择&#xff0c;还致力于为卖家和消费者提供高效便捷的跨境电商物流服…

conda环境下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

SpringIOC之LocaleContext

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

使用Mosquitto/python3进行MQTT连接

一、简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议&#xff0c;为此&#xff0c;它需要一个消息中间件。 …

用BEVformer来卷自动驾驶-1

之所以是-1,是因为大概率1篇文章写不完,但是又不知道应该用几篇来说事,先写着看 按照惯例,上论文地址:2203.17270v1.pdf (arxiv.org) 什么是BEV, Birds -Eye-View的意思,就是鸟瞰 比如稍微传统一些的自动驾驶,大部分的实现。如果靠纯CV的方案的话,那么基本…

P73 bert奇闻

同一个字&#xff0c;前后接的不同&#xff0c;词汇的意思不同&#xff0c;通过bert 之后输出的向量也不一样。 bert 输出后的向量包含上下文的信息。 比如 吃苹果 和苹果电脑中的 果&#xff0c;向量不一样。 DNA 分类 把DNA 的 A T C G 用 we you he she 表示&#xff0c;然…

构建现代企业培训系统的技术实践

在当今竞争激烈的商业环境中&#xff0c;企业培训系统成为提高员工技能、促进组织发展的关键组成部分。本文将深入探讨构建现代企业培训系统的关键技术实践&#xff0c;旨在帮助企业更好地满足学员需求、提高培训效果。 1. 系统架构设计 现代企业培训系统的成功建设始于一个…

Java版企业电子招投标系统源代码,支持二次开发,采用Spring cloud微服务架构

招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业&#xff0c;旨在提高项目管理的效率和质量。该系…

关于redis单线程和IO多路复用的理解

首先&#xff0c;Redis是一个高性能的分布式缓存中间件。其复杂性不言而喻&#xff0c;对于Redis整体而言肯定不是只有一个线程。 我们常说的Redis 是单线程&#xff0c;主要是指 Redis 在网络 IO和键值对读写是采用一个线程来完成的&#xff0c;这也是 Redis 对外提供键值存储…

Zabbix6 使用Agent2实现证书监控的详细步骤

目标 我们的目标是通过获取网站的证书信息来实现网站证书监控。 使用agent2的key 只需使用其中的key&#xff0c;就能实现我们的目标功能。然而&#xff0c;由于它返回的是json格式的数据&#xff0c;我们需要根据数据来配置监控项目&#xff08;item&#xff09;和触发器&am…

从功能测试到测试开发,薪资翻倍,我整理的全网最全学习指南!

在这个吃技术的IT行业来说&#xff0c;我刚入行的时候每天做的也是最基础的工作&#xff0c;但是随着时间的消磨&#xff0c;我产生了对自我和岗位价值和意义的困惑。 一是感觉自己在浪费时间&#xff0c;另一个就是做了快2年的测试&#xff0c;感觉每天过得浑浑噩噩&#xff…

Mac查询本机ip地址

Mac系统版本和网络配置不同&#xff0c;可能会有一些细微差别。 一、 使用系统偏好设置 1、点击屏幕左上角的Apple图标&#xff0c;选择“系统偏好设置”。 2、点击“网络”。 3、 在左侧选择当前连接的网络&#xff08;如Wi-Fi或以太网&#xff09;&#xff0c;在右侧界面&a…

Leetcode—73.矩阵置零【中等】

2023每日刷题&#xff08;六十六&#xff09; Leetcode—73.矩阵置零 空间复杂度为O(mn)版实现代码 class Solution { public:void setZeroes(vector<vector<int>>& matrix) {int rowLen matrix.size();int colLen matrix[0].size();vector<int> row…