移动端和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>

效果:

在这里插入图片描述

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