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