标签:定位,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里面就行了。