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: `
是的发送到
水电费水电费
`
, 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(`
${context.count}
`
); } }); 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了,官方后续会修复。
uniapp地图开发(APP,H5)_第1张图片

注意事项

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

尾巴

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

你可能感兴趣的:(uniapp,uni-app,uniapp,地图,uniapp,高德地图,uniapp,腾讯地图)