2021-12-2 uniapp地图定位的研究

14 篇文章 1 订阅

文章重点是我研究的历程与成果,另外一些遇到的小问题分析。

学习目标:

这次的研究只针对两个需求:一个是将中文的地址在地图上标记出来,另外一个是唤起第三方的地图做路线规划以及导航,在这个基础上,我们都知道在导航的时候会有起点、终点和途径点,起点如果没有设置,就会默认是使用者的当前位置吧。

学习内容:

在此次学习中,我使用了三种方式来做的。

  • 直接使用了微信小程序的sdk
  • rendjs直接渲染地图
  • uni-app的map组件实现地图的显示和定位,导航的时候直接唤起第三方地图【不知道的话,我一般会说成是手机上已经安装的地图app】

我最终使用了第三项。
uniapp官网推荐的app用高德地图。所以我的研究范围大多是高德。

学习时间:

2021-11-8~2021-11-26的工作日,很不幸的是,我并不是每天都研究8个工时,原因是我每天都要去训练我自己的肢体动作,骨折的人懂骨折的人。

学习产出:

方案一:直接使用了微信小程序的sdk

先去高德的官网下载高德微信小程序的sdk
用法如下:
如果是uniapp,我是把所有的“wx”替换为“uni”,网上也找到其他的也是这么处理的。不当的话,欢迎指出。

// 引用高德地图微信小程序JSAPI模块
	var amapFile = require('@/utils/map/amap-uni.js');
	var myAmapFun;
	export default {
		data() {
			return {
				amapKey: '高德地图开放后台去申请key',
			}
		},
		onLoad(e) {
			 myAmapFun = new amapFile.AMapWX({
				key: this.amapKey
			});
			console.log(myAmapFun) 
		},
		//接下来在methods的方法中可以任意的通过调用myAmapFun下的api
	}

方案二:rendjs直接渲染地图

maps.js

class ownAMap {
	constructor(map) {
		// this.map=map;
	}
	//引入地图sdk
	static MapLoader() {
		return new Promise((resolve, reject) => {
			if (typeof window.AMap === 'function') {
				resolve(window.AMap)
			} else {
				// 动态引入较大类库避免影响页面展示
				const script = document.createElement('script');
				script.type = 'text/javascript';
				script.async = true;
				script.src =
					'https://webapi.amap.com/maps?v=1.4.15&callback=initAMap&key=高德地图开发平台申请的key';
				// script.onload = this.initAmap.bind(this)
				script.onerror = reject;
				document.head.appendChild(script);
			}
			window.initAMap = () => {
				resolve(window.AMap)
			}
		})
	}
	//初始化地图
	static initAmap(AMap) {
		let map = new AMap.Map('amap', {
			resizeEnable: true,
			center: [116.397428, 39.90923], //地图中心点
			zoom: 13 //地图显示的缩放级别
		})
		// this.map = map;
		return map
	}
	//将中文地址转为经纬度,已知地图
	static geoCodes(addrArrShz, map) {
		var markers = [];
		var geoCodeLocation = [];
		return new Promise(resolve => {
			map.plugin('AMap.Geocoder', () => {
				var geocoder = new AMap.Geocoder({
					// city: "010", //城市设为北京,默认:“全国”
				});
				geocoder.getLocation(addrArrShz, (status, result) => {
					if (status === 'complete' && result.geocodes.length) {
						console.log(result.geocodes.length)
						for (var i = 0; i < result.geocodes.length; i += 1) {
							var marker = new AMap.Marker({
								position: result.geocodes[i].location
							});
							geoCodeLocation.push(result.geocodes[i].location)
							markers.push(marker);
						}
						resolve({
							markers,
							geoCodeLocation
						})
					}
				});
			});

		})

	}

}
export default ownAMap

map.vue

<template>
	<view class="body_content">
		<view id="amap" :style="{height: mapHeight}" :prop="addrArrS" :change:prop="amap.updateProps"></view>
		<view class="" id="panel"></view>
		<view @click="openApp" class="btn">点击调起高德地图</view>
		<!-- <input type='button' id='callApp' class="btn" value='点击调起高德地图' /> -->
	</view>
</template>

<script>
	export default {
		props: {
			addrArr: {
				type: [Array],
				default: function() {
					return []
				}
			}
		},
		data() {
			return {
				mapHeight: 700 + 'rpx'
			}
		},
		computed: {
			addrArrS() {
				return this.addrArr
			}
		},
		mounted() {
			uni.getLocation({
			    type: 'gcj02',//gcj02\wgs84
			    success:  (res)=> {
			        console.log('当前位置的经度:' + res.longitude);
			        console.log('当前位置的纬度:' + res.latitude);
					// this.locationLat=new AMap.LngLat(res.longitude, res.latitude)
			    }
			});
			uni.getSystemInfo({
				success: (res)=> { // res - 各种参数
					console.log(res.windowHeight); // 屏幕的宽度 
					this.mapHeight = res.windowHeight+'px'
					/* let info = uni.createSelectorQuery().select(".类名");
					info.boundingClientRect((data)=>  { //data - 各种参数
						console.log(data)
						console.log(data.width) // 获取元素宽度
			 	}).exec() */
			 }
			});
		},
		methods: {
			openApp() {
				// #ifdef APP-PLUS
				let lat=116.328103;//116.328103,39.900835
				let lon=39.900835;
				let cityName='北京西站'
				let viaPoints=[{lat:116.618137,lng:40.08495},{lat:116.302509,lng:39.993474}];//&viaPoints="+URLEncoder.encode(JSON.stringify(viaPoints), "utf-8")
				// let url='baidumap://map/navi?location=' + lat + ',' + lon + '&title=xxx' + "&src=''&viaPoints="+viaPoints
				this.addressCoordinates('北京西站','',false);
				// this.openMapRoute(lat, lon, cityName)
				// #endif
				
			},
			addressCoordinates(cityName, name, isWaitInfo) {
				return new Promise(resolve => {
					plus.maps.Map.geocode(
						cityName,
					 event => {
							var address = event.address; // 转换后的地理位置
							var point = event.coord; // 转换后的坐标信息
							var coordType = event.coordType; // 转换后的坐标系类型
							console.log(point)
							if (isWaitInfo) {
								resolve({
									latitude: point.latitude,
									longitude: point.longitude,
									name: name,
									cityName: cityName,
									address: event.address,
									isWaitInfo: isWaitInfo
								})
								return
							}
			
							// 注入
							this.openMapRoute(point.latitude, point.longitude, cityName)
						},
						e => {
							var address = e.address; // 转换后的地理位置
							var point = e.coord; // 转换后的坐标信息
							var coordType = e.coordType; // 转换后的坐标系类型
							console.log(e)
							if (isWaitInfo) {
								resolve({
									latitude: point.latitude,
									longitude: point.longitude,
									name: name,
									address: e.address,
									isWaitInfo: isWaitInfo
								})
								return
							}
							// 注入
							this.openMapRoute(point.latitude, point.longitude, cityName)
						}
					);
				})
			
			},
			openMapRoute(lat, lon, cityName){
				var url = '';
				console.log(plus.os.name)
				let viaPoints=[{lat:116.618137,lng:40.08495},{lat:116.302509,lng:39.993474}];//&viaPoints="+URLEncoder.encode(JSON.stringify(viaPoints), "utf-8")
				if (plus.os.name == 'Android') {
					var hasBaiduMap = plus.runtime.isApplicationExist({
						pname: 'com.baidu.BaiduMap',
						action: 'baidumap://'
					});
					var hasAmap = plus.runtime.isApplicationExist({
						pname: 'com.autonavi.minimap',
						action: 'androidamap://'
					});
					var urlBaiduMap = 'baidumap://map/marker?location=' + lat + ',' + lon + '&title=' + cityName + "&src=''&viaPoints="+JSON.stringify(viaPoints);//navi,marker
					var urlAmap = "androidamap://viewMap?sourceApplication=''" + '&poiname=' + cityName + '&lat=' + lat +
						'&lon=' + lon +
						'&dev=0';
					if (hasAmap && hasBaiduMap) {
						plus.nativeUI.actionSheet({
							title: '选择地图应用',
							cancel: '取消',
							buttons: [{
								title: '百度地图'
							}, {
								title: '高德地图'
							}]
						}, function(e) {
							switch (e.index) {
								case 1:
									plus.runtime.openURL(urlBaiduMap);
									break;
								case 2:
									plus.runtime.openURL(urlAmap);
									break;
							}
						});
					} else if (hasAmap) {
						plus.runtime.openURL(urlAmap);
					} else if (hasBaiduMap) {
						plus.runtime.openURL(urlBaiduMap);
					} else {
						url = 'geo:' + lat + ',' + lon + '?q=%e6%95%b0%e5%ad%97%e5%a4%a9%e5%a0%82';
						plus.runtime.openURL(url); //如果是国外应用,应该优先使用这个,会启动google地图。这个接口不能统一坐标系,进入百度地图时会有偏差
					}
				} else {
					// iOS上获取本机是否安装了百度高德地图,需要在manifest里配置,在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加(如urlschemewhitelist:["iosamap","baidumap"])
					plus.nativeUI.actionSheet({
						title: '选择地图应用',
						cancel: '取消',
						buttons: [{
							title: 'Apple地图'
						}, {
							title: '百度地图'
						}, {
							title: '高德地图'
						}]
					}, function(e) {
						console.log('e.index: ' + e.index);
						switch (e.index) {
							case 1:
								url = 'http://maps.apple.com/?q=%e6%95%b0%e5%ad%97%e5%a4%a9%e5%a0%82&ll=' + lat + ',' +
									lon +
									'&spn=0.008766,0.019441';
								break;
							case 2:
								url = 'baidumap://map/marker?location=' + lat + ',' + lon + '&title=' + cityName +
									'&src=""';
								break;
							case 3:
								url = 'iosamap://viewMap?sourceApplication=""&poiname=' + cityName + '&lat=' + lat +
									'&lon=' + lon + '&dev=0';
								break;
							default:
								break;
						}
						if (url != '') {
							plus.runtime.openURL(url, function(e) {
								plus.nativeUI.alert('本机未安装指定的地图应用');
							});
						}
					});
				}
			}
		}
	}
</script>

<script module="amap" lang="renderjs">
	import ownAMap from '@/utils/map/maps.js'
	export default {
		data() {
			return {
				map: null,
				ownerInstanceObj: null, //service层对象
				arer: [],
				locationLat: '',
				markers: [],
			}
		},
		mounted() {
			
			ownAMap.MapLoader().then(AMap => {
				this.map = new AMap.Map('amap', {
					resizeEnable: true,
					center: [116.397428, 39.90923], //地图中心点
					zoom: 13 //地图显示的缩放级别
				})
				this.init()
			});
		},
		methods: {
			async init() {
				console.log(document)
				// var center = map.getCenter();
				//地址解析
				let addrArrShz = []
				if (this.addrArrS.length == 0) {
					return
				}
				for (let i = 0; i < this.addrArrS.length; i++) {
					addrArrShz.push(this.addrArrS[i].label)
				}
				this.map.remove(this.markers);
				this.markers = []
				let geoObj = await ownAMap.geoCodes(addrArrShz, this.map);
				console.log(geoObj)
				this.markers = geoObj.markers;
				this.map.add(this.markers);
				this.map.setFitView(this.markers);

			},
			updateProps(newValue, oldValue, ownerInstance, instance) {
				// 监听 service 层数据变更
				this.ownerInstanceObj = ownerInstance
			},

		}
	}
</script>

<style lang="scss" scoped>
	#amap {
		width: 100%;
	}

	.btn {
		position: fixed;
		bottom: 20px;
		right: 20px;
		background-color: white;
		width: 11rem
	}
</style>

方案三:uni-app的map组件实现地图的显示和定位,导航的时候直接唤起第三方地图

openMap.js

let itemList = ["百度地图", "高德地图", "腾讯地图"];
	// "baidumap://map/direction?mode=driving&destination=上地&origin=西二旗&src=push&viaPoints={"viaPoints":[{"name":"北京西站","lat":39.902463,"lng":116.327737}]}";

// #ifdef APP-PLUS
var hasBaiduMap = plus.runtime.isApplicationExist({
	pname: 'com.baidu.BaiduMap',
	action: 'baidumap://'
});
var hasQQ = plus.runtime.isApplicationExist({
	pname: 'com.tencent.map',
	action: 'qqmap://'
});
var hasAmap;
let AppitemList = [];
if (plus.os.name == 'Android') {
	hasAmap = plus.runtime.isApplicationExist({
		pname: 'com.autonavi.minimap',
		action: 'androidamap://'
	});
} else {
	hasAmap = plus.runtime.isApplicationExist({
		pname: 'com.autonavi.minimap',
		action: 'iosamap://'
	});
}
if (hasBaiduMap) {
	AppitemList.push({
		title: "百度地图"
	})
}
if (hasAmap) {
	AppitemList.push({
		title: "高德地图"
	})
}
if (hasQQ) {
	AppitemList.push({
		title: "腾讯地图"
	})
}
// #endif
//规划路线
function openMapRoutePlan(options, mode) {
	var bdapp = "baidumap://map/direction";
	var bdappDown = "http://map.baidu.com/zt/qudao/newfengchao/1012337a/html/slide.html";
	var qqmap = "qqmap://map/routeplan";
	var qqmapDefault = "https://apis.map.qq.com/uri/v1/routeplan";
	var amapuri = "iosamap://route/plan/";
	var amapuriDown="https://apps.apple.com/cn/app/id461703208"
	// #ifdef APP-PLUS
	if (plus.os.name == 'Android') {
		amapuri = "amapuri://route/plan/";
		amapuriDown = "http://wap.amap.com/";
	}
	// #endif
	let startGeo={}
	let endGeo={
		latitude:options.destination.latitude,
		longitude: options.destination.longitude
	}
	let originName = options.origin && options.origin.name ? options.origin.name : "起点";
	let destinationName = options.destination.name ? options.destination.name : "终点";
	let viaPoints = options.viaPoints?options.viaPoints:{}
	
	var bdMode = "driving";
	if (mode == "bus") {
		bdMode = "transit";
	} else if (mode == "walk") {
		bdMode = "walking";
	} else if (mode == "bike") {
		bdMode = "riding";
	}
	bdapp += "?coord_type=gcj02&mode=" + bdMode + "&src=uniapp&viaPoints="+viaPoints;
	if (options.origin) {
		startGeo={
			latitude:options.origin.latitude,
			longitude:options.origin.longitude
		}
		bdapp += "&origin=name:" + originName + "|latlng:" + startGeo.latitude + "," + startGeo
			.longitude;
	}
	if (options.destination) {
		bdapp += "&destination=name:" + destinationName + "|latlng:" + endGeo.latitude +
			"," + endGeo.longitude
	}
	var amapMode = 0;
	if (mode == "bus") {
		amapMode = 1;
	} else if (mode == "walk") {
		amapMode = 2;
	} else if (mode == "bike") {
		amapMode = 3;
	}
	amapuri += "?sourceApplication=uniapp&t=" + amapMode+"&viaPoints="+viaPoints;
	if (options.origin) {
		amapuri += "&slat=" + startGeo.latitude + "&slon=" + startGeo
			.longitude + "&sname=" + originName;
	}
	if (options.destination) {
		amapuri +="&dlat=" + endGeo.latitude + "&dlon=" + endGeo.longitude +
			"&dname=" + destinationName;
	}
	qqmap += "?type=" + mode +"&viaPoints="+viaPoints;
	if (options.origin) {
		qqmap += "&from=" + originName + "&fromcoord=" + startGeo.latitude + "," +
			startGeo.longitude;
	}
	if (options.destination) {
		qqmap += "&to=" + destinationName + "&tocoord=" + endGeo.latitude + "," + endGeo
			.longitude;
	}
	qqmapDefault += "?type=" + mode + "&policy=1&viaPoints="+viaPoints;
	if (options.origin) {
		qqmapDefault += "&from=" + originName + "&fromcoord=" +
			startGeo.latitude + "," + startGeo.longitude ;
	}
	if (options.origin) {
		qqmapDefault += "&to=" + destinationName + "&tocoord=" + endGeo.latitude +
			"," + endGeo.longitude;
	}
	openActionSheet(bdapp,amapuri,qqmap,qqmapDefault)
}
//导航
function toNavigation(options) {
	let destinationName = options.destination.name ? options.destination.name : "终点";
	let viaPoints = options.viaPoints?options.viaPoints:{}
	let endGeo={
		latitude:options.destination.latitude,
		longitude:options.destination.longitude
	}
	var bdapp = "baidumap://map/navi?location=" + endGeo.latitude + "," + endGeo.longitude + "&query=" +
		destinationName + "&coord_type=gcj02&src=uniapp&viaPoints="+viaPoints;
	var bdappDown = "http://map.baidu.com/zt/qudao/newfengchao/1012337a/html/slide.html";
	var qqmap = "qqmap://map/routeplan?type=drive&to=" + destinationName + "&tocoord=" + endGeo.latitude + "," +
		endGeo.longitude;
	var qqmapDefault = "https://apis.map.qq.com/uri/v1/routeplan?type=drive&to=" + destinationName + "&tocoord=" +
		endGeo.latitude + "," + endGeo.longitude + "&policy=1";
	var amapuri="iosamap://navi?sourceApplication=uniapp&lat=" + endGeo.latitude + "&lon=" + endGeo
			.longitude + "&poiname=" + destinationName + "&dev=1";
	var amapuriDown = "https://apps.apple.com/cn/app/id461703208";
	// #ifdef APP-PLUS
	if (plus.os.name == 'Android') {
		amapuri = "androidamap://navi?sourceApplication=uniapp&lat=" + endGeo.latitude + "&lon=" + endGeo
			.longitude + "&poiname=" + destinationName + "&dev=1";
		amapuriDown = "http://wap.amap.com/";
	}
	// #endif
	openActionSheet(bdapp,amapuri,qqmap,qqmapDefault)
}
//唤起
function openActionSheet(bdapp,amapuri,qqmap,qqmapDefault){
	// #ifdef APP-PLUS
	plus.nativeUI.actionSheet({
			title: "选择导航",
			cancel: "取消",
			buttons: AppitemList
		},
		(res)=> {
			if(res.index==0){//取消
				return
			}
			if (hasBaiduMap && hasAmap) {
				if (res.index == 1) {
					appOpenUrl(bdapp);
					return
				}
				if (res.index == 2) {
					appOpenUrl(amapuri);
					return
				}
				 if (res.index == 3&&hasQQ) {
					appOpenUrl(qqmap);
					return
				}
				appOpenUrl(qqmapDefault);
				return
			}
			if (!hasBaiduMap && hasAmap) {
				if (res.index == 1) {
					appOpenUrl(amapuri);
					return
				}
				if (res.index == 2&&hasQQ) {
					appOpenUrl(qqmap);
					return
				} 
				appOpenUrl(qqmapDefault);
				return
			}
			 if (hasBaiduMap && !hasAmap) {
				if (res.index == 1) {
					appOpenUrl(bdapp);
					return
				}
				if (res.index == 2&& hasQQ) {
					appOpenUrl(qqmap);
					return
				}
				appOpenUrl(qqmapDefault);
				return
			}
			if (res.index == 1 && hasQQ) {
				appOpenUrl(qqmap);
				return
			}
			appOpenUrl(qqmapDefault);
		}
	);
	// #endif
	// #ifndef APP-PLUS
	uni.showActionSheet({
		itemList: itemList,
		success: (res) => {
			if (res.tapIndex == 0) {
				openURL(bdapp, bdappDown)
			} else if (res.tapIndex == 1) {
				openURL(amapuri, amapuriDown)
			} else {
				openURL(qqmap, qqmapDefault)
			}
	
		}
	})
	// #endif
}


function appOpenUrl(_url) {
	plus.runtime.openURL(encodeURI(_url));
}

function openURL(url, downLoadUrl) {
	window.location.href = encodeURI(url);
	var startTime = Date.now();
	var endTime = 0;
	var t = setTimeout(() => {
		endTime = Date.now() - startTime;
		if (endTime >= 2000 && !(document.hidden || document.webkitHidden)) {
			window.location.href = encodeURI(downLoadUrl);
		} else {
			clearTimeout(t)
		}
	}, 2000)

}
let PI = 3.14159265358979324;
let x_pi = 3.14159265358979324 * 3000.0 / 180.0

function delta(lat, lon) {
	var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
	var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
	var dLat = transformLat(lon - 105.0, lat - 35.0);
	var dLon = transformLon(lon - 105.0, lat - 35.0);
	var radLat = lat / 180.0 * PI;
	var magic = Math.sin(radLat);
	magic = 1 - ee * magic * magic;
	var sqrtMagic = Math.sqrt(magic);
	dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
	dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
	return {
		'lat': dLat,
		'lon': dLon
	};
}

function gcj_encrypt(wgsLat, wgsLon) {
	if (outOfChina(wgsLat, wgsLon))
		return {
			'lat': wgsLat,
			'lon': wgsLon
		};
	var d = delta(wgsLat, wgsLon);
	return {
		'lat': wgsLat + d.lat,
		'lon': wgsLon + d.lon
	};
}

function bd_decrypt(bdLat, bdLon) {
	var x = bdLon - 0.0065,
		y = bdLat - 0.006;
	var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
	var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
	var gcjLon = z * Math.cos(theta);
	var gcjLat = z * Math.sin(theta);
	return {
		'lat': gcjLat,
		'lon': gcjLon
	};
}

function outOfChina(lat, lon) {
	if (lon < 72.004 || lon > 137.8347)
		return true;
	if (lat < 0.8293 || lat > 55.8271)
		return true;
	return false;
}

function transformLat(x, y) {
	var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
	ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
	ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
	ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
	return ret;
}

function transformLon(x, y) {
	var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
	ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
	ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
	ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
	return ret;
}
//途径点坐标转换
function transformViaPoints(type,viaPoints){
	let obj = JSON.parse(viaPoints);
	let viaPointsArr = obj.viaPoints;
	for(let i=0;i<viaPointsArr.length; i++){
		if(type=='wgs84'){
			viaPointsArr[i].latitude = gcj_encrypt(viaPointsArr[i].latitude,viaPointsArr[i].longitude).lat
			viaPointsArr[i].longitude=gcj_encrypt(viaPointsArr[i].latitude, viaPointsArr[i].longitude).lon
		}else if(type=='bd09'){
			viaPointsArr[i].latitude=bd_decrypt(viaPointsArr[i].latitude, viaPointsArr[i].longitude).lat
			viaPointsArr[i].longitude=bd_decrypt(viaPointsArr[i].latitude, viaPointsArr[i].longitude).lon
		}
	}
	console.log(viaPointsArr)
	return JSON.stringify({viaPoints:viaPointsArr})
}
export default {
	 获取地址坐标
	addressCoordinates(cityName) {
		return new Promise(resolve => {
			plus.maps.Map.geocode(
				cityName,
				event => {
					var address = event.address; // 转换后的地理位置
					var point = event.coord; // 转换后的坐标信息
					var coordType = event.coordType; // 转换后的坐标系类型
					resolve({
						latitude: point.latitude,
						longitude: point.longitude,
						cityName: cityName,
						name: event.address,
						address: event.address,
					})
				},
				e => {
					var address = e.address; // 转换后的地理位置
					var point = e.coord; // 转换后的坐标信息
					var coordType = e.coordType; // 转换后的坐标系类型
					resolve({
						latitude: point.latitude,
						longitude: point.longitude,
						name: e.address,
						address: e.address,
					})
				}
			);
		})
	},
	/* 路程规划 */
	routePlan(options, type = "gcj02") {
		let _mode = options.mode ? options.mode : "drive";
		if (type.toLowerCase() == "wgs84") {
			if (options.origin) {
				options.origin.latitude = gcj_encrypt(options.origin.latitude, options.origin.longitude).lat
				options.origin.longitude = gcj_encrypt(options.origin.latitude, options.origin.longitude).lon
			}
			options.destination.latitude = gcj_encrypt(options.destination.latitude, options.destination.longitude).lat
			options.destination.longitude = gcj_encrypt(options.destination.latitude, options.destination.longitude).lon
			options.viaPoints = transformViaPoints("wgs84",options.viaPoints)
		} else if (type.toLowerCase() == "bd09") {
			if (options.origin) {
				options.origin.latitude = bd_decrypt(options.origin.latitude, options.origin.longitude).lat
				options.origin.longitude = bd_decrypt(options.origin.latitude, options.origin.longitude).lon
			}
			options.destination.latitude = bd_decrypt(options.destination.latitude, options.destination.longitude).lat
			options.destination.longitude = bd_decrypt(options.destination.latitude, options.destination.longitude).lon
			options.viaPoints = transformViaPoints("bd09",options.viaPoints)
		}
		// #ifdef MP
		// #ifdef MP-WEIXIN
		const mapCtx = wx.createMapContext(options.mapId, this);
		mapCtx.openMapApp({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			destination: options.destination.name,
			complete: res => {
				console.log(res);
			}
		});
		// #endif
		// #ifdef MP-QQ
		qq.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif
		// #ifdef MP-ALIPAY
		my.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif
		// #ifdef MP-360 || MP-BAIDU || MP-TOUTIAO
		uni.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif

		// #endif
		// #ifndef MP
		switch (uni.getSystemInfoSync().platform) {
			case 'android':
				console.log('运行Android上')
				openMapRoutePlan(options, _mode)
				break;
			case 'ios':
				console.log('运行iOS上')
				openMapRoutePlan(options, _mode)
				break;
			default:
				console.log('运行在开发者工具上')
				break;
		}

		// #endif
	},
	navigation(options, type = "gcj02") {
		if (type.toLowerCase() == "wgs84") {
			options.destination.latitude = gcj_encrypt(options.destination.latitude, options.destination.longitude).lat
			options.destination.longitude = gcj_encrypt(options.destination.latitude, options.destination.longitude).lon
		} else if (type.toLowerCase() == "bd09") {
			options.destination.latitude = bd_decrypt(options.destination.latitude, options.destination.longitude).lat
			options.destination.longitude = bd_decrypt(options.destination.latitude, options.destination.longitude).lon
		}
		// #ifdef MP
		// #ifdef MP-WEIXIN
		const mapCtx = wx.createMapContext(options.mapId, this);
		mapCtx.openMapApp({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			destination: options.destination.name,
			complete: res => {
				console.log(res);
			}
		});
		// #endif
		// #ifdef MP-QQ
		qq.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif
		// #ifdef MP-ALIPAY
		my.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif
		// #ifdef MP-360 || MP-BAIDU || MP-TOUTIAO
		uni.openLocation({
			latitude: options.destination.latitude,
			longitude: options.destination.longitude,
			name: options.destination.name
		})
		// #endif
		// #endif
		// #ifndef MP
		switch (uni.getSystemInfoSync().platform) {
			case 'android':
				console.log('运行Android上')
				toNavigation(options)
				break;
			case 'ios':
				console.log('运行iOS上')
				toNavigation(options)
				break;
			default:
				console.log('运行在开发者工具上')
				break;
		}
		// #endif
	}
}

testmap.vue

<template>
	<view class="body_content">
		<map id="map" ref="ee" class="maps" :style="{height: mapHeight}" :longitude="location.longitude"
			:latitude="location.latitude" :markers="markers" :polyline="polylines" :show-location="true"></map>
		<view class="map_bottom">
			<view class="luxian">
				<button type="default" @click="godaohang">【途径点请用百度地图】导航</button>
			</view>
		</view>
	</view>
</template>

<script>
	// 引用高德地图微信小程序JSAPI模块
	// var amapFile = require('@/utils/map/amap-uni.js');
	// var myAmapFun;
	import Map from '@/utils/map/openMap.js'
	export default {
		data() {
			return {
				mapHeight: 600,
				addrArr: [],
				markers: [],
				polylines: [],
				amapKey: 'f0c0c545b32941ed025097140c3b39af',
				location: {
					longitude: 0,
					latitude: 0,
					address: ''
				}
			}
		},
		mounted() {
			uni.getLocation({
				type: 'gcj02', //gcj02\wgs84
				geocode: true,
				success: (res) => {
					console.log('当前位置的经度:' + res.longitude);
					console.log('当前位置的纬度:' + res.latitude);
					let addr = res.address;
					this.location.address = addr.country + addr.province + addr.city + addr.district + addr
						.street +
						addr.streetNum + addr.poiName + addr.cityCode;
					this.location.longitude = res.longitude;
					this.location.latitude = res.latitude;
					this.initMarker(this.addrArr);
				}
			});
			uni.getSystemInfo({
				success: (res) => { // res - 各种参数
					let info = uni.createSelectorQuery().select(".map_bottom");
					info.boundingClientRect((data) => { //data - 各种参数
						this.mapHeight = (res.windowHeight - uni.upx2px(data.height) - 20) + 'px'
					}).exec()
				}
			});
		},
		onLoad(e) {
			var _self = this;
			_self.addrArr = e.addrArr ? JSON.parse(e.addrArr) : {};
			// 高德地图的key
			/* myAmapFun = new amapFile.AMapWX({
				key: _self.amapKey
			});
			console.log(myAmapFun) */
		},
		methods: {
			godaohang() {
				this.location.name = this.location.address;
				let markers = JSON.parse(JSON.stringify(this.markers));
				/* {
					latitude: 39.98848272,
						longitude: 116.47560823,
						name: "终点名称"
				} */
				console.log(markers)
				if(markers.length==0){
					uni.showToast({
						title:"所选择的地点信息不全,不能去导航"
					})
					return
				}
				var options = {
					origin: this.location,
					destination:markers[markers.length-1], //导航终点点坐标和名称
					viaPoints:JSON.stringify({viaPoints:markers.slice(1, markers.length-1)}),
					mode: "drive", //导航方式 公交:bus驾车:drive(默认),步行:walk,骑行:bike
					mapId: "map" //map 组件的 id (微信小程序端必传)
				}
				Map.routePlan(options,'gcj02')
				// Map.navigation(options, 'gcj02')
			},
			async initMarker(addrArr) {
				let arr = [];
				for (let i = 0; i < addrArr.length; i++) {
					arr.push(await Map.addressCoordinates(addrArr[i].label));
				}
				// arr.unshift(this.location)
				for(let i = 0; i < arr.length; i++){
					arr[i].iconPath='/static/images/pos1.png';
					// arr[i].height=33;
					// arr[i].width=33;
				}
				let poliData = JSON.parse(JSON.stringify(arr))
				/* poliData[0].iconPath='/static/images/sx.png';//起始图标
				poliData[poliData.length-1].iconPath='/static/images/scfjx.png';//终点图标 */
				/* poliData.map(it=>{
					if(it.height==undefined){
						it.height=66;
					}
					if(it.width==undefined){
						it.width=33;
					}
				}) */
				this.markers = poliData;
				console.log(this.markers)
				/* this.polylines.push({
				  points: this.markers,
				  iconPath:'/static/images/sx.png',
				  // color: "#00f",
				  width: 6
				}); */
			},
			
		}
	}
</script>

<style>
	.content {
		flex: 1;
	}

	.maps {
		width: 750px;
		height: 500px;
	}

	.map_bottom {
		height: 180rpx;
	}
</style>

问题1:自定义基座之后,uniapp的查看位置以及获取位置的时候获取不到

在这个过程中,也值得一提的一个毛病,周转了半天,也咨询了同事,原来是我在高德地图上申请的key是有问题的。最后我就按照申请的流程老老实实的去做了,最后解决了。

uni.getLocation({
				type: 'gcj02', //gcj02\wgs84
				geocode: true,
				success: (res) => {
					console.log('当前位置的经度:' + res.longitude);
					console.log('当前位置的纬度:' + res.latitude);
					let addr = res.address;
					this.location.address = addr.country + addr.province + addr.city + addr.district + addr
						.street +
						addr.streetNum + addr.poiName + addr.cityCode;
					this.location.longitude = res.longitude;
					this.location.latitude = res.latitude;
					this.initMarker(this.addrArr);
				}
			});

问题2:高德地图在唤起之后导航是不支持自动添加上途径点

当我在官网上查找这个相关的内容时,发现并没有地方介绍了这个知识点。另外还咨询了同事,同事问了官方,确实是不支持。后来就考虑到百度地图。也是一波三折的。在uniapp插件市场上在使用地图的开发者,对方很热心的回答了我的疑问。我后面就继续去百度地图的官网上查找,终于是找到了百度地图唤起第三方地图的用法。

var bdMode = "driving";
var viaPoints = JSON.stringify({viaPoints:[{name":"北京西站",lat:39.902463,lng:116.327737}]});//这里是记得转为字符串
bdapp += "baidumap://map/direction?coord_type=gcj02&mode=" + bdMode + "&src=uniapp&viaPoints="+viaPoints;

参考:
uniapp的map组件
uniapp位置信息
高德地图开发平台
高德地图路线规划
百度地图开发平台
地图调起API,以安卓为例
h5+的maps

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值