前端获取当前经纬度(gps,高德)

方法介绍: 

1. 该方法是个  promise  对象,因为不管是用 GPS 还是高德定位都是异步的

2. 方法优先是用 h5 自带 API 进行 GPS 定位,如果获取不到位置会使用高德定位(高德定位需要高德的key),如果都没获取到,那就经纬度都返回 0

3. 该 promise 封装的很拙略,能力至此,会慢慢优化的,本来使用的正常方法加回调函数处理获取到的经纬度,但考虑再三还是使用 promise 能好点

注意: 

1. 现在很多浏览器需要加密协议的链接才能获取到用户位置,保险起见,请使用加密协议的链接

2. 使用高德定位需要在高德那里申请key

3. 如果需要精度高或者后续还要使用高德地图对经纬度做其他处理,需要将 gps 获取到的经纬度转成高德经纬度,项目头部引得 GPS2AMAP就是处理这个的,代码在下面

 1 /* 
 2   该方法暴露出去的是一个promise,经纬度在resolve的第一个参数里
 3   使用方法:  startLocation.then(({lat, lng}) => {这里就是你的方法})
 4 */
 5 
 6 // 将gps 经纬度转为高德经纬度,精度要求高的需要这个东西
 7 import {
 8   GPS
 9 } from './GPS2AMAP'
10 let callback = null // promise 的 resolve会赋值给这个函数
11 // gps 定位成功回调
12 const onSuccess = (position) => {
13   const {
14     latitude: lat,
15     longitude: lng
16   } = position.coords
17   const exchange = GPS.gcj_encrypt(Number.parseFloat(lat), Number.parseFloat(lng)) // 对精度要求不高可以省略这步,把上面获取到的经纬度直接传给saveLocation
18   console.log('gps定位', `${exchange.lat}-${exchange.lng}`)
19   saveLocation(exchange.lat, exchange.lng)
20 }
21 // gps 定位失败回调
22 const onError = () => {
23   initAMAP()
24   console.error('gps失败')
25 }
26 // 初始化高德,加载高德js
27 const initAMAP = () => {
28   const key = 'xxxxxxxxxxx', // 从高德买来的key
29         MP = new Promise(function (resolve, reject) {
30           window.init = function () {
31             resolve(AMap)
32           };
33           let script = document.createElement("script");
34           script.type = "text/javascript";
35           script.src = "//webapi.amap.com/maps?v=1.4.6&key="+key+"&callback=init";
36           script.onerror = reject;
37           document.head.appendChild(script);
38         })
39   MP.then(function (AMap) {
40     startAMAPLocation(AMap)
41   }).catch(err=>{
42     console.error(JSON.stringify(err));
43   })
44 }
45 
46 // 开始高德定位
47 const startAMAPLocation = (AMap) => {
48   AMap.plugin('AMap.Geolocation', function () {
49     var geolocation = new AMap.Geolocation({
50       enableHighAccuracy: true, //是否使用高精度定位,默认:true
51       timeout: 8000, //超过10秒后停止定位,默认:5s
52       buttonPosition: 'RB', //定位按钮的停靠位置
53       buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
54       zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
55     });
56     // map.addControl(geolocation);
57     geolocation.getCurrentPosition(function (status, result) {
58       if (status == 'complete') {
59         console.log('高德: ', `${result.position.lat},${result.position.lng}`)
60         saveLocation(result.position.lat, result.position.lng)
61       } else {
62         console.error('高德失败')
63         saveLocation(0, 0)
64       }
65     });
66   });
67 }
68 // 处理获取到的经纬度
69 const saveLocation = (lat = 0, lng = 0) => {
70   lat && (lat = parseFloat(lat).toFixed(6))
71   lng && (lng = parseFloat(lng).toFixed(6))
72   typeof callback === 'function' && callback({lat, lng})
73 }
74 
75 // promise, resolve的第一个参数就是经纬度,
76 const startLocation = new Promise((resolve, reject) => {
77   callback = resolve
78   const options = {
79     enableHighAccuracy: true,
80     maximumAge: 1000,
81     timeout: 5000
82   }
83   if (navigator.geolocation) {
84     navigator.geolocation.getCurrentPosition(onSuccess, onError, options)
85   } else {
86     saveLocation(0, 0)
87     console.error('您的浏览器不支持地理位置定位')
88   }
89 })
90 export default startLocation

这里 GPS2AMAP.js ,这个方法是这位老哥的,去吧,皮噶求

 1 export const GPS = {
 2   PI : 3.14159265358979324,
 3   x_pi : 3.14159265358979324 * 3000.0 / 180.0,
 4   delta : function (lat, lng) {
 5       var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
 6       var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
 7       var dLat = this.transformLat(lng - 105.0, lat - 35.0);
 8       var dlng = this.transformlng(lng - 105.0, lat - 35.0);
 9       var radLat = lat / 180.0 * this.PI;
10       var magic = Math.sin(radLat);
11       magic = 1 - ee * magic * magic;
12       var sqrtMagic = Math.sqrt(magic);
13       dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
14       dlng = (dlng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
15       return {'lat': dLat, 'lng': dlng};
16   },
17 
18   //GPS---高德
19   gcj_encrypt : function ( wgsLat , wgslng ) {
20       if (this.outOfChina(wgsLat, wgslng))
21           return {'lat': wgsLat, 'lng': wgslng};
22 
23       var d = this.delta(wgsLat, wgslng);
24       return {'lat' : wgsLat + d.lat,'lng' : wgslng + d.lng};
25   },
26   outOfChina : function (lat, lng) {
27       if (lng < 72.004 || lng > 137.8347)
28           return true;
29       if (lat < 0.8293 || lat > 55.8271)
30           return true;
31       return false;
32   },
33   transformLat : function (x, y) {
34       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));
35       ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
36       ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
37       ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
38       return ret;
39   },
40   transformlng : function (x, y) {
41       var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
42       ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
43       ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
44       ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
45       return ret;
46   }
47 };

以上

posted @ 2019-09-27 12:05  blackbentel  阅读(12766)  评论(0编辑  收藏  举报