移動端和vue接入騰訊地圖前端定位組件位置不準確以及自己創建地圖

1.介紹

關於騰訊地圖開發的博客還是挺少的,此教程只是給一些初進入接入騰訊地圖文檔的作爲參考,我也是一知半解,但是對於一些需要簡單接入地圖的小夥伴就足夠了,因爲我也是看着官方文檔來寫的,所以以官方文檔爲準騰訊地圖api官方接入文檔

溫馨提示:運行的代碼必須是在sever上的,不然沒有效果,vscode可以下載liverserver去啓一個服務,或者使用webpack,也可以部署到服務器也可以

2.展示

  2.1:展示官方文檔中的前端定位中的demo

在這裏插入圖片描述
在這裏插入圖片描述
上面二維碼可以看到定位組件展示的效果

3.實現(定位組件地址

  3.1:key鑑權
  • key用途

    Key用於識別開發者身份、驗證權限,並在某些情況下方便聯繫到您。不使用Key會導致部分功能無法正常使用。

  • Key使用限制

    目前Key申請完全免費,基礎功能使用免費,且沒有調用次數限制。

  • Key使用方法

    在加載API服務時通過key參數傳入您申請的Key。

  • Key如何申請

    使用QQ賬號登錄,點擊控制檯—密鑰管理—申請創建密鑰,填寫應用名及應用描述即可申請。一個賬號最多可以申請5個Key

  3.2:創建key

      控制檯 \Longrightarrow key管理 \Longrightarrow 創建新祕鑰

      注意:要選中WebServeiceApi,僅白名單中的域名纔可使用此key調用WebService服務,留空則不限制,如果是項目中使用的話要配置,因爲我們現在是寫demo所以不寫也無所謂

  3.3:調用騰訊地圖
     3.3.1:通過ifram調用

ifram調用直接複製官網的地址就行,只需要你的key,如果你不需要上面的黑色的框,只需要把ifram的heigiht改爲0

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Geolocation Components Demo - zoom effect</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,
    minimum-scale=1,maximum-scale=1,user-scalable=no">
    <style>
        * {margin: 0; padding: 0; border: 0;}
        body {
            position: absolute;
            width: 100%;
            height: 100%;
        }
        #geoPage, #markPage {
            position: relative;
        }
    </style>
</head>
<body>
    <!--  通過 iframe 嵌入前端定位組件,此處沒有隱藏定位組件,使用了定位組件的在定位中視覺特效  -->
    <iframe id="geoPage" width="100%" height="30%" frameborder=0 scrolling="no"
    src="https://apis.map.qq.com/tools/geolocation?key=youkey&referer=myapp&effect=circle"></iframe>
 
    <script type="text/JavaScript">
        var loc;
        var isMapInit = false;
        //監聽定位組件的message事件
        window.addEventListener('message', function(event) {
            loc = event.data; // 接收位置信息
            console.log('location', loc);
                
            if(loc  && loc.module == 'geolocation') { //定位成功,防止其他應用也會向該頁面post信息,需判斷module是否爲'geolocation'
                var markUrl = 'https://apis.map.qq.com/tools/poimarker' +
                '?marker=coord:' + loc.lat + ',' + loc.lng +
                ';title:我的位置;addr:' + (loc.addr || loc.city) +
                '&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp';
                //給位置展示組件賦值
                document.getElementById('markPage').src = markUrl;
            } else { //定位組件在定位失敗後,也會觸發message, event.data爲null
                console.log('定位失敗');
              
            }
 
            /* 另一個使用方式
            if (!isMapInit && !loc) { //首次定位成功,創建地圖
                isMapInit = true;
                createMap(event.data);
            } else if (event.data) { //地圖已經創建,再收到新的位置信息後更新地圖中心點
                updateMapCenter(event.data);
            }
            */
        }, false);
        //爲防止定位組件在message事件監聽前已經觸發定位成功事件,在此處顯示請求一次位置信息
        document.getElementById("geoPage").contentWindow.postMessage('getLocation', '*');
 
        //設置6s超時,防止定位組件長時間獲取位置信息未響應
        setTimeout(function() {
            if(!loc) {
                //主動與前端定位組件通信(可選),獲取粗糙的IP定位結果
            document.getElementById("geoPage")
                .contentWindow.postMessage('getLocation.robust', '*');
            }
        }, 6000); //6s爲推薦值,業務調用方可根據自己的需求設置改時間,不建議太短
    </script>
 
    <!-- 接收到位置信息後 通過 iframe 嵌入位置標註組件 -->
    <iframe id="markPage" width="100%" height="100%" frameborder=0 scrolling="no" src=""></iframe>
</body>
</html>

效果:
在這裏插入圖片描述

     3.3.2:自定義創建地圖
       步驟介紹:就是根據騰訊api中的定位組件獲取經緯度,然後通過這個經緯度去創建一個地圖

如圖的代碼是獲得當前的定位地址並且去初始化,在這裏要填寫你的key,要不無法完成創建。

注意:你需要在手機的瀏覽器上去看,在電腦上的網頁查看的話,肯定會與差距,也不能再微信瀏覽器中查看,如果需要在微信瀏覽器中查看效果需要設置https

關於zoom的問題: 在你創建地圖的時候如果你在手機端那麼你的zoom一定要調到最大值,要不你會看不到你當前的地區

在這裏插入圖片描述

初始化呢的代碼包括創建一個地圖,可marker圖標,還有一個自定義Overlay

在這裏插入圖片描述

代碼部分:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>前端定位模塊</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    <style type="text/css">
        html,
        body {
            width: 100%;
            height: 100%;
        }

        * {
            margin: 0px;
            padding: 0px;
        }

        body,
        button,
        input,
        select,
        textarea {
            font: 12px/16px Verdana, Helvetica, Arial, sans-serif;
        }

        p {
            width: 603px;
            padding-top: 3px;
            overflow: hidden;
        }


        #container {
            width: 100%;
            height: 100%;
        }
    </style>
    <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=youkey"></script>
    <script type="text/javascript"
        src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>

</head>

<div id="container"></div>
<script>
    let options = { timeout: 8000 };
    const geolocation = new qq.maps.Geolocation("youkey", "myapp");
    geolocation.getLocation(showPosition, showErr, options)
    function showPosition(position) {
        console.log(position)
        let lat = position.lat
        let lng = position.lng
        init(lat, lng)
    };

    function showErr(err) {
        console.log(err)
    };
    function init(lat, lng) {
        let center = new qq.maps.LatLng(lat, lng)
        const map = new qq.maps.Map(document.getElementById("container"), {
            center: center,  // 地圖的中心地理座標。
            zoom: 20, // 地圖的中心地理座標。
            panControl: true, //不顯示平移控件
            panControlOptions: {
                //設置平移控件的位置爲相對右方中間位置對齊.
                position: qq.maps.ControlPosition.LEFT_BOTTOM

            },
            zoomControl: false,//不顯示縮放控件
            mapZoomType: qq.maps.MapZoomType.CENTER,
            mapTypeControlOptions: {
                //設置控件的地圖類型ID,ROADMAP顯示普通街道地圖,SATELLITE顯示衛星圖像,HYBRID顯示衛星圖像上的主要街道透明層
                mapTypeIds: [
                    qq.maps.MapTypeId.ROADMAP,
                    qq.maps.MapTypeId.SATELLITE,
                    qq.maps.MapTypeId.HYBRID
                ],

            }

        });
        //創建一個marker
        var marker = new qq.maps.Marker({
            //設置Marker的位置座標
            position: center,
            //設置顯示Marker的地圖
            map: map
        });
        marker.setVisible(true);// 設置marker的可見性
        marker.setDraggable(false); //設置marker是否可以被拖拽
        var anchor = new qq.maps.Point(15, 19), //設置Marker自定義圖標的屬性
            origin = new qq.maps.Point(0, 0),
            size = new qq.maps.Size(32, 32), //size是圖標尺寸
            icon = new qq.maps.MarkerImage(
                "/icon.png",
                size,
                origin,
                anchor
            );
        marker.setIcon(icon);
        //設置圖標結束

        function CustomOverlay(position, index) {
            this.index = index;
            this.position = position;
        }
        CustomOverlay.prototype.aaa = '1'
        console.dir(CustomOverlay.prototype)
        CustomOverlay.prototype = new qq.maps.Overlay();
        //定義construct,實現這個接口來初始化自定義的Dom元素
        CustomOverlay.prototype.construct = function () {
            var div = this.div = document.createElement("div");
            var divStyle = this.div.style;
            divStyle.position = "absolute";
            divStyle.width = "150px";
            divStyle.height = "30px";
            divStyle.backgroundColor = "#FFFFFF";
            divStyle.textAlign = "center";
            divStyle.lineHeight = "30px";
            divStyle.borderRadius = "5px";
            divStyle.cursor = "pointer";
            divStyle.color = 'blue'
            this.div.innerHTML = this.index;
            //將dom添加到覆蓋物層
            var panes = this.getPanes();
            //設置panes的層級,overlayMouseTarget可接收點擊事件
            panes.overlayMouseTarget.appendChild(div);

            var self = this;
            this.div.onclick = function () {
                alert(self.index);
            }
        }
        //實現draw接口來繪製和更新自定義的dom元素
        CustomOverlay.prototype.draw = function () {
            var overlayProjection = this.getProjection();
            //返回覆蓋物容器的相對像素座標
            var pixel = overlayProjection.fromLatLngToDivPixel(this.position);
            var divStyle = this.div.style;
            divStyle.left = pixel.x - 70 + "px";
            divStyle.top = pixel.y - 60 + "px";
        }
        //實現destroy接口來刪除自定義的Dom元素,此方法會在setMap(null)後被調用
        CustomOverlay.prototype.destroy = function () {
            this.div.onclick = null;
            this.div.parentNode.removeChild(this.div);
            this.div = null
        }
        var latlng = map.getCenter();
        var overlay = new CustomOverlay(latlng, '點擊門店圖標可查看導航');
        overlay.setMap(map);
        let flag = true
        qq.maps.event.addListener(marker, 'click', function () {
            if (flag) {
                overlay.destroy()
                flag = false
                return flag
            }
            if (!flag) {
                console.log('重新渲染')
                flag = true
                overlay.construct()
                overlay.draw()
                return;
            }

        });

    }
</script>
</body>

</html>

效果:

在這裏插入圖片描述

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