騰訊位置服務定位組件實現(xiàn)周邊公用廁所遠近排序分布圖

前言

地圖應用非常廣泛,目前地圖服務,都提供地圖操作、標注、地點搜索、出行規(guī)劃、地址解析、街景等接口,功能非常豐富。在實際開發(fā)過程中,各有優(yōu)劣。本次基于需求,使用騰訊位置服務作為一個公用廁所位置標注的H5頁面開發(fā)。

本次使用版本: JavaScript API 2.0版本。

項目需求

1、項目需求

基于騰訊位置服務,實現(xiàn)微信掃描二維碼后,在微信瀏覽器內,展示某縣城的公用廁所分布圖,按照用戶當前定位與各個廁所之間的距離遠近排序,點擊標注點跳轉到騰訊地圖進行導航。

image.png

2、需求分解

基于上述需求,對使用到的騰訊位置服務接口予以分解如下:

騰訊地圖加載;
自動定位;
信息點(POINTS)標注maker;
計算標注點之間的距離;
導航跳轉鏈接API接口;
街道與衛(wèi)星地圖切換控件;
縮放控件;

開發(fā)實戰(zhàn)

1、引入功能庫和附件庫

    <script charset="utf-8"
            src="https://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script>
    <script type="text/javascript"
            src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>

2、構建騰訊地圖容器

<!--地圖加載-->
<div id="location" onclick="getLocation();"><img src="{$url}{$STATIC}images/location.png" alt=""></div>
<div id="txmap"></div>

3、調用前端定位組件

由于項目需要多次調用地圖和定位,為此,在script腳本中map和geolocation都設置為全局函數(shù)。

  var map;//全局函數(shù)
  var geolocation = new qq.maps.Geolocation(appkey, "{$referer}");
  var options = {timeout: 8000};

 function getLocation() {
        geolocation.getLocation(showPosition, showErr, options);
    }

getLocation(sucCallback, errCallback, [options: {timeout: number, failTipFlag: boolean}])方法

獲取當前所在地理位置,調用一次即重新定位一次,定位數(shù)據(jù)比較精確。
sucCallback為定位成功回調函數(shù),必填;
errCallback為定位失敗回調函數(shù),選填,如果不填,請設為null;
options為定位選項,選填,可以通過timeout參數(shù)設置定位的超時時間,默認值為10s;
failTipFlag: 是否在定位失敗時給出提示引導用戶打開授權或打開定位開關。(即將支持)

1)定位成功回調函數(shù)

function showPosition(position) {
}

獲取位置坐標顯示地圖

        map = new qq.maps.Map(document.getElementById("txmap"), {
            // 地圖的中心地理坐標。
            center: new qq.maps.LatLng(position.lat, position.lng),
            zoom: 15
        });

定義當前位置maker樣式圖片

        var imgUrl = "static/rooted/images/icon.png";
        var anchor = new qq.maps.Point(6, 6),
                size = new qq.maps.Size(45, 46),
                origin = new qq.maps.Point(0, 0),
                icon = new qq.maps.MarkerImage(imgUrl, size, origin, anchor);

        var marker2 = new qq.maps.Marker({
            icon: icon,
            map: map,
            position: new qq.maps.LatLng(position.lat, position.lng)
        });

讀取信息點(POINTS)并在地圖上標注

1、標準JSON數(shù)據(jù)格式

為方便展示,此處僅展示數(shù)據(jù)格式,實際應用做,使用ajax獲取即可。

[
    {
        "toilet_id": "9",
        "toilet_name": "智慧廣場",
        "toilet_address": "西溪路 智慧中心南",
        "toilet_url": "upload/preview/2020-11/15784affe0de0d45c5f33625851527e9.jpg",
        "toilet_lon": "115.965248",
        "toilet_lat": "35.597050"
    },
    {
        "toilet_id": "14",
        "toilet_name": "唐塔公廁",
        "toilet_address": "東門街北段唐塔廣場",
        "toilet_url": "upload/preview/2020-11/8e5bda8c5b12f87ebad80c247d8f2b26.jpg",
        "toilet_lon": "115.946365",
        "toilet_lat": "35.602218"
    }
]

2、地圖標注并計算距離

   //地圖標注;
                getTxMap(newData, latlngs);
                //兩點間的距離;
                getDistance(newData, latlngs);

經緯度標注封裝函數(shù)

        function getTxMap(newData, latlngs) {
            for (var i = 0; i < newData.length; i++) {
                (function (n) {
                    var marker = new qq.maps.Marker({
                        position: latlngs[n],
                        map: map
                    });

                    qq.maps.event.addListener(marker, 'click', function () {
                        var popHtml = '<div class="pop">到這里: <a  + position.lat + ',' + position.lng + '&to=' + newData[n].toilet_name + '&tocoord=' + newData[n].toilet_lat + ',' + newData[n].toilet_lon + '&policy=0&referer={$referer}">' + newData[n].toilet_name + '</a></div>';
                        infoWin.open();
                        infoWin.setContent(popHtml);
                        infoWin.setPosition(latlngs[n]);
                    });
                })(i);
            }
        }

計算兩點間的距離函數(shù)封裝

        function getDistance(newData, latlngs) {
            var newArr = [];
            var start = new qq.maps.LatLng(position.lat, position.lng);
            for (var i = 0; i < latlngs.length; i++) {
                var end = latlngs[i];
                var distance = Math.round(qq.maps.geometry.spherical.computeDistanceBetween(start, end) * 10) / 10;
                //拼接新的距離數(shù)組數(shù)據(jù);
                newArr.push({
                    toilet_id: newData[i].toilet_id,
                    toilet_name: newData[i].toilet_name,
                    toilet_address: newData[i].toilet_address,
                    toilet_url: newData[i].toilet_url,
                    toilet_lon: newData[i].toilet_lon,
                    toilet_lat: newData[i].toilet_lat,
                    distance: distance
                })
            }
            //升序排列;
            function compare(key) {
                return function (value1, value2) {
                    var val1 = value1[key];
                    var val2 = value2[key];
                    return val1 - val2;
                }
            }
            newArr.sort(compare('distance'));
            console.log(newArr);

2、定位失敗回調函數(shù)

    //定位失敗,自動跳轉頁面;
    function showErr() {
        //alert("定位失??!");
        window.location.href = "?m=Index&a=error"
    }

坐標經緯度拾取

1、騰訊坐標拾取器

項目開發(fā)過程中,需要自己拾取坐標經緯度,以滿足初始數(shù)據(jù)的測試和演示使用。一般會使用騰訊提供的坐標拾取器。鏈接地址:https://lbs.qq.com/tool/getpoint/index.html。

支持地址 精確/模糊 查詢;
支持POI點坐標顯示;
坐標鼠標跟隨顯示;

如果非要挑出點毛病的話,地圖拾取框太小了,想隨心所欲的拾取坐標,要縮放或拖拽很多次,心累。

2、WebService API地址解析(地址轉坐標)

在項目完成測試后,如果遇到成千上百的地址時,一個一個的拾取,好像不是一個合格的開發(fā)者的所為。此時,就需要使用到地址解析和逆解析的API接口,即:在數(shù)據(jù)導入到數(shù)據(jù)庫的過程中,自動批量地將地址轉化為經緯度坐標,滿足前端的調用。

本例中使用了騰訊位置服務的WebService API,后端語言使用PHP,簡要的將該過程予以呈現(xiàn)。

1、封裝WebService API接口函數(shù)

官方實例,如果在前端直接使用getJSON函數(shù),會出現(xiàn)“同源策略”被阻止,為此需要后端爬取后,“曲線救國”。

//GET請求示例,注意參數(shù)值要進行URL編碼
https://apis.map.qq.com/ws/geocoder/v1/?address=北京市海淀區(qū)彩和坊路海淀西大街74號&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
/*地址轉坐標封裝函數(shù),文件名稱為points.php
*$address,需要轉化的地址,越詳細經緯度精度越高;
 */
function getGeoCoding($address)
{
    $url = "https://apis.map.qq.com/ws/geocoder/v1/?address=" . $address . "&key={$key}";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}
//獲取前端傳入的地址參數(shù);
$address = $_GET["address"];
//輸出json數(shù)據(jù)格式,供前端調用;
die(getGeoCoding($address));

2、前端調用

    //自動獲取經緯度;
    var getAddress = function transAddress() {
        var address = $("#address").val();
        getPoints(address);
    }

    //前端頁面輸出;
    function getPoints(address) {
        $.getJSON("points.php", {address: address}, function (res) {
            if (res.status == 0) {
                $("#lng").val(res.result.location.lng);
                $("#lat").val(res.result.location.lat);
            } else {
                $("#message").html(res.message);
            }
        });
    }

3、效果演示

image

<font color=red>在導入地址數(shù)據(jù)的時候,一定要是省市區(qū)街道門牌號,地址越詳細精度越高,否則會解析不出來,謹記!</font>

注意事項

1、script標簽加載API服務

<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>

在開發(fā)過程中,默認會這樣引入到前端文件。測試環(huán)境和生成環(huán)境一致,或者更換環(huán)境也是一直,不會出現(xiàn)問題的。但是如果是http和https不一致的協(xié)議環(huán)境下,引入文件就會出現(xiàn)錯誤提示。

建議的加載方式:src不使用協(xié)議名稱,讓其自動匹配。如:

<script charset="utf-8" src="http://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>

2、附加庫的引入

學習一個新項目的最快捷方式是學會使用官方文檔,因為這些文檔是基礎中的基礎。但官方文檔的有時太官方,有些細節(jié)無法清楚的展示出來。

官方文檔不能解決的問題時,會“面對CSDN編程”,每個開發(fā)者遇到的問題不同,開發(fā)經驗不同,在CSDN上的記錄更多的是為了避免自己下次“入坑”提醒,無法完整的將項目的細節(jié)描述清楚,也是初學者看到人家明明解決了,為什么自己不可以的。

這里就牽涉到騰訊地圖附加庫的引入。

    <script charset="utf-8"
            src="://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script>

本項目中就遇見需要計算自動定位的經緯度和各個廁所之間的距離,需要使用geometry幾何運算庫。在未理解官方文檔的前提下,強行CSDN,走路很多彎路才發(fā)現(xiàn):開發(fā)語法明明對了,但是卻沒有計算出距離,就是沒引入對應的附加庫。

3、自動定位組件庫

   <script type="text/javascript"
            src="http://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>

使用自動定位功能,必須引入自動定位的geolocation.min.js附加庫,無須多言。

4、經緯度位置

如果是首次開發(fā)地圖就使用騰訊地圖的話,出現(xiàn)這個錯誤的可能性比較低。如果有百度和高德地圖開發(fā)的經驗話,千萬不要想當然。在這個問題上浪費了半個小時才發(fā)現(xiàn),騰訊的經緯度和百度、高德的問題是互換的。

騰訊經緯度

new qq.maps.LatLng(39.914850, 116.403765); //構建對象的是(緯度,經度)

百度經緯度

map.centerAndZoom(new BMap.Point(116.4035,39.915),8); //構建對象的是(經度,緯度)

高德經緯度

position: new AMap.LngLat(116.39, 39.9),//構建點對象的是(經度,緯度)

在使用坐標拾取器時,一定要選擇各個對應的工具,導航等牽涉到坐標的地方一定要注意。

5、騰訊、百度和高德地圖開發(fā)比較

對于不同的廠家地圖的使用,一般都有“先入為主” 的刻板印象,也有甲方原因的客觀要求。

對比項 騰訊地圖 百度地圖 高德地圖
功能 標注、信息框、覆蓋物、計算距離、軌跡、導航等常用功能 同前 同前
坐標 火星坐標 BD-09坐標 火星坐標
坐標結構 (39.914850, 116.403765) (116.4035,39.915) (116.39, 39.9)
語法結構 同高德 百度自有語法 同騰訊
開發(fā)文檔 相對集中 百度地圖開發(fā)平臺已升級到3.0版本,文檔多,類庫多 相對集中
延伸 數(shù)據(jù)可視化API服務 同前 同前

總結

本次使用版本: JavaScript API 2.0版本,目前我們提供的JavaScript API GL版本,功能更炫酷齊全,大家可以嘗試接入使用。

作者:漏刻有時

鏈接:https://lockdatav.blog.csdn.net/article/details/113412823

來源:CSDN

著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會,身份的轉變要...
    余生動聽閱讀 10,798評論 0 11
  • 彩排完,天已黑
    劉凱書法閱讀 4,452評論 1 3
  • 沒事就多看看書,因為腹有詩書氣自華,讀書萬卷始通神。沒事就多出去旅游,別因為沒錢而找借口,因為只要你省吃儉用,來...
    向陽之心閱讀 4,964評論 3 11
  • 表情是什么,我認為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息。高興了當然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,412評論 2 7

友情鏈接更多精彩內容