/**
* 测试版本:Chrome 79.0.3945.88、华为 Android 9、ios 12.3.1
* 总结:1、原生h5定位只支持https协议的站点,若使用此种定位方式需要将站点和后台站点升级到https方式,leaflet定位也属于原生定位方式。优点:定位精准;缺点:不支持http协议站点;
* 2、百度定位,优点:定位速度快,支持http;缺点:定位偏差特别大。但是经过坐标转换,ios上可以达到米级精度,Android浏览器上只能定位到市级;Chrome上偏差过大,无法使用;
* 3、腾讯定位:优点:定位较精准;缺点:在Chrome、Android上定位失败次数多,偶尔成功,ios与之相反,定位成功次数多;原因:Chrome、火狐以及部分套壳浏览器接入的定位服务在国外,有较大限制,失败率高;
* 4、高德定位:优点:在ios上定位准确,达到米级;缺点:在Chrome、Android上定位失败。原因:google Chrome浏览器本身的定位接口是黑洞,通过其请求定位完全没有回应,也会超时返回失败。
* 最终为了保证定位成功率,采用百度定位,并进行坐标转换。
*/
1、百度定位:
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=百度秘钥"></script>
let geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(
function(r) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
let lng = r.point.lng;
let lat = r.point.lat;
let correctobj = that.BD09toWGS84(lng, lat); //坐标转换
} else {
console.log("failed" + this.getStatus());
that.$message.error("无法获取当前位置");
}
},
{ enableHighAccuracy: true }
);
BD09toWGS84(lng, lat) {
let that = this;
//百度坐标转国标
let url =
"/baidu/geoconv/v1/?coords=" +
lng +
"," +
lat +
"&from=5&to=3&ak=百度秘钥";
this.axios
.get(url)
.then(function(msg) {
console.log(msg);
if (msg.data.status == 0) {
that.transformGCJ2WGS(
msg.data.result[0].y,
msg.data.result[0].x
);
}
})
.catch(function(error) {
console.log(error);
});
},
//国标转wgs84
transformGCJ2WGS(gcjLat, gcjLon) {
let d = delta(gcjLat, gcjLon);
return {
'lat': gcjLat - d.lat,
'lon': gcjLon - d.lon
}
var PI = 3.14159265358979324;
function delta(lat, lon) {
let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
let ee = 0.00669342162296594323; // ee: 椭球的偏心率。
let dLat = transformLat(lon - 105.0, lat - 35.0);
let dLon = transformLon(lon - 105.0, lat - 35.0);
let radLat = (lat / 180.0) * PI;
let magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
let 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 transformLat(x, y) {
let 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) {
let 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;
}
}
参考文章链接:https://blog.csdn.net/rrrrroy_Ha/article/details/89374211
2、leaflet定位:
that.mapObj.map.locate({
setView: true,
maxZoom: 16
});
that.mapObj.map.on("locationfound", function(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng)
.addTo(that.mapObj.map)
.bindPopup("你就在这个圈内");
L.circle(e.latlng, radius).addTo(that.mapObj.map);
});
that.mapObj.map.on("locationerror", function(e) {
console.log("定位出错=====>", e);
});
3、腾讯定位:
<script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
var geolocation = new qq.maps.Geolocation(
"腾讯秘钥",
"myapp"
);
var positionNum = 0;
var options = { timeout: 8000 };
function showPosition(position) {
var adCode = position.adCode; //邮政编码
var nation = position.nation; //中国
var city = position.city; //城市
var addr = position.addr; //详细地址
var lat = position.lat; //
var lng = position.lng; //火星坐标
}
function showErr() {
//TODO 如果出错了调用此方法
console.log("腾讯定位","获取不到位置")
}
geolocation.getLocation(showPosition, showErr, options);
4、高德定位:
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.3&key=高德秘钥"></script>
var mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function () {
let geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 是否使用高精度定位,默认:true
timeout: 10000, // 超过10秒后停止定位,默认:无穷大
maximumAge: 0, // 定位结果缓存0毫秒,默认:0
convert: true, // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, // 显示定位按钮,默认:true
buttonPosition: 'LB', // 定位按钮停靠位置,默认:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, // 定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, // 定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, // 定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy:true // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
});
mapObj.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', onComplete); // 返回定位信息
AMap.event.addListener(geolocation, 'error', onError); // 返回定位出错信息
});
function onComplete(obj){
let pos = obj.position;
let arr = pos.split(",");
var res = '经纬度:' + obj.position +
'\n精度范围:' + obj.accuracy +
'米\n定位结果的来源:' + obj.location_type +
'\n状态信息:' + obj.info +
'\n地址:' + obj.formattedAddress +
'\n地址信息:' + JSON.stringify(obj.addressComponent, null, 4);
alert(res);
}
function onError(obj) {
alert(obj.info + '--' + obj.message);
console.log(obj);
}