/**
* 測試版本: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);
}