标签:定位,uniapp使用高德,坐标转换


前言

由于使用的是uniapp,所以没有用使用Android的SDK进行开发,但用到这个的Android key来进行做定位等uni方面的操作。


目录

文章目录

前言

二、使用步骤

1.在uniapp项目中使用高德

2.坐标转换

总结


一、申请高德key

1,去高德官网,点击 控制台—应用管理—我的应用,然后点击创建应用,如下图:

 应用名称  和  应用类型可以随你自己填写,没有什么明确的规定。

2,应用建好之后,点击添加key,表单内容如下图填写就好,key名称 随便填。

 3,还需要申请Android的key,步骤如下:

(1),再次点击添加key,然后选择Android平台,

 (2)获取安全码SHA1,第一种比较直接的就是进入 Dcloud开发者中心,然后在里面找到你的项目,点击进去,查看证书,如下图

 如果没有,就创建证书,这个证书后续还需要用作打包发行的。

 

 然后查看详情可以看到里面有生成的  SHA1 安全码,证书密码和下载证书是发行—云打包时选择使用自由证书时用的。

插个题外话 打包配置

二、使用步骤

1.在uniapp项目中使用高德

直接创建使用高德在H5上肯定是可以的,代码如下:

<template>
	<view class="app-page-bg">
		<view id="container" style="width:100vw;heigth:100vh"></view>
    </view>
</template>
<script>
	let mapPlayer = null; // 生成地图实例
	let options = {
		zoom: 16, // 初始化地图级别
		center: [108.921672, 34.250646],
	}
	window.mapInit = function() {
		mapPlayer = new AMap.Map('container', options);
	};
    mounted() {
		this.loadScrpit();
	},
	methods: {
			// 挂载动态js
		loadScrpit() {
			var script = document.createElement('script');
			script.src = '
https://webapi.amap.com/mapsv=1.4.15&key=你申请的web Key&callback=mapInit';
			document.body.appendChild(script);
		},
    }
}

</script>

 但在真机调试以及打包后,这种写法是有问题的,这时候我们需要了解一个视图层的概念,即 renderjs。renderjs 主要服务于APP,因为uni-app为vue+js+html进行编写,整个是h5的技术栈。而app上并没有document等基础对象。所以涉及到这些的前端类库就无法使用。renderjs 写法也不复杂,就是视图层和逻辑层分开,然后通过DOM来互相传值。

高德webjs在app上的使用如下所示:

<template>
	<view class="app-page-bg">
		<view id="container" style="width:100vw;heigth:100vh"></view>
    </view>
</template>
<script>
	export default {

    }
</script>

// 视图层
<script module="test" lang="renderjs">
	let mapPlayer = null; // 生成地图实例
	let options = {
		zoom: 16, // 初始化地图级别
		center: [108.921672, 34.250646],
	}
	window.mapInit = function() {
		mapPlayer = new AMap.Map('container', options);
	};
    mounted() {
		this.loadScrpit();
	},
	methods: {
			// 挂载动态js
		loadScrpit() {
			var script = document.createElement('script');
			script.src = '
https://webapi.amap.com/mapsv=1.4.15&key=你申请的web Key&callback=mapInit';
			document.body.appendChild(script);
		},
    }
}

</script>

 在uniapp 的 manifest.json 中做如下配置:

 (1)打开manifest.json,点击模块配置

 要做定位的话需要在App权限配置里面打开如下权限

 这时,准备工作就差不多做完了,可以去代码里面试一下定位准不准,这个只能真机调试才能出来。

<template>
	<view class="app-page-bg">
		<view id="container" style="width:100vw;heigth:100vh"></view>


		<!-- 给视图层传参 -->
		<view :prop="location" :change:prop="test.getLocationArr"></view>
    </view>
</template>
<script>
	export default {
        data() {
            return {
                location: []
            }
        },

		mounted() {
			this.getlocation()
		},
        method: {// 获取定位
			getlocation() {
				var that = this
				// #ifdef APP-PLUS
				uni.getLocation({
					type: 'gcj02',
					geocode: 'true',
					success: function(res) {
                        console.log(res)
						that.location = [res.longitude, res.latitude]
					},
					// 定位失败
					fail: function(error) {
						uni.showModal({
							title: '提示',
							content: '获取定位失败,是否授权打开定位',
							success: (res) => {
								if (res.confirm) {
									uni.getSystemInfo({
										success: (sys) => {
											if (sys.platform == 'ios') {
												plus.runtime.openURL(
													"app-settings://");
											} else {
												var main = plus.android
													.runtimeMainActivity();
												var Intent = plus.android.importClass(
													"android.content.Intent"
												); 
												var mIntent =
													new Intent(                 
                                      'android.settings.LOCATION_SOURCE_SETTINGS'
													);
												main.startActivity(mIntent);
											}
										}
									})
								}
							}
						})
					}
				})
				// #endif
			},
        }
    }
</script>

// 视图层
<script module="test" lang="renderjs">
	let mapPlayer = null; // 生成地图实例
	let options = {
		zoom: 16, // 初始化地图级别
		center: [108.921672, 34.250646],
	}
	window.mapInit = function() {
		mapPlayer = new AMap.Map('container', options);
	};
    mounted() {
		this.loadScrpit();
	},
	methods: {
			// 挂载动态js
		loadScrpit() {
			var script = document.createElement('script');
			script.src = '
         https://webapi.amap.com/mapsv=1.4.15&key=你申请的web Key&callback=mapInit';
			document.body.appendChild(script);
		},
        getLocationArr(location ) {
			if(!mapPlayer) {
				return
			}

			options.center = location

			// #ifdef APP-PLUS
			let time = setInterval(() => { // 等待地图挂载后再做其他操作
				if (mapPlayer != null) {
					<!-- 打点,画线,覆盖物 -->
					clearInterval(time);
				}
			}, 100)
			// #endif
		},
    }
}

</script>

2.坐标转换

地图坐标系分很多种,高德用得一般是 gcj02,也称火星坐标系,WGS84和2000类似,那我们怎么把WGS84转换成gcj02供高德使用呢,咱们得分两步转换。

1,下载 proj4

 npm install proj4 -s

如果不行,试试下面这个

cnpm i proj4 -s

然后在项目中使用

<script>
    import proj4, { defs } from "proj4"
    import transformLatLng from './transformLatLng.js'
    proj4.defs([
    	[
		"EPSG:4545",
"+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
		],
	]);
    var out_of_china = function out_of_china(lng, lat) {
	    return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
    };
    data(){
        return {
            location:[ 606352.1267644756,3831640.2720496473 ]
        }
    },
	mounted() {
		this.wgs84togcj02(this.location)
	},
    method: {
        wgs84togcj02(location){
            var point = proj4("EPSG:4545", "EPSG:4326", location)
            let lnglat = transformLatLng(point)
            return lnglat;
        },
    }

新建一个页面。命名为 transformLatLng.js,内容如下:

var PI = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;

export function gcj02towgs84(lnglat) {
	let lng = lnglat[0]
	let lat = lnglat[1]
	if (out_of_china(lng, lat)) {
		return [lng, lat]
	} else {
		var dlat = transformlat(lng - 105.0, lat - 35.0);
		var dlng = transformlng(lng - 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);
		dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
		var mglat = lat + dlat;
		var mglng = lng + dlng;
		return [lng * 2 - mglng, lat * 2 - mglat]
	}
};
export function wgs84togcj02(lnglat) {
	let lng = lnglat[0]
	let lat = lnglat[1]
	if (out_of_china(lng, lat)) {
		return [lng, lat]
	} else {
		var dlat = transformlat(lng - 105.0, lat - 35.0);
		var dlng = transformlng(lng - 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);
		dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
		var mglat = lat + dlat;
		var mglng = lng + dlng;
		return [mglng, mglat]
	}
};

var transformlat = function transformlat(lng, lat) {
	var 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
};

var transformlng = function transformlng(lng, lat) {
	var 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 out_of_china = function out_of_china(lng, lat) {
	// var lat = +lat;
	// var lng = +lng;
	// 纬度3.86~53.55,经度73.66~135.05 
	return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
};

 如果要做其他类型转换的可以在网上找一找,大抵都差不多。

总结

在这里,uniapp里面使用高德地图就差不多了,剩下的就看官网api就好了。本文仅仅简单介绍了renderjs的传参使用,你们把这个当作js使用就可以了,只是uni.的一些内置方法在里面不管用,得在传统的 <script></script>里面去使用,然后把参数获取方法传到renderjs里面就行了。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐