web移動端 定位 總結

/**

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章