地圖應用很是普遍,目前地圖服務,都提供地圖操做、標註、地點搜索、出行規劃、地址解析、街景等接口,功能很是豐富。在實際開發過程當中,各有優劣。本次基於需求,使用騰訊位置服務做爲一個公用廁所位置標註的H5頁面開發。javascript
本次使用版本: JavaScript API 2.0版本。php
基於騰訊位置服務,實現微信掃描二維碼後,在微信瀏覽器內,展現某縣城的公用廁所分佈圖,按照用戶當前定位與各個廁所之間的距離遠近排序,點擊標註點跳轉到騰訊地圖進行導航。html
基於上述需求,對使用到的騰訊位置服務接口予以分解以下:前端
騰訊地圖加載; 自動定位; 信息點(POINTS)標註maker; 計算標註點之間的距離; 導航跳轉連接API接口; 街道與衛星地圖切換控件; 縮放控件;
<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>
<!--地圖加載--> <div id="location" onclick="getLocation();">![]({$url}{$STATIC}images/location.png)</div> <div id="txmap"></div>
因爲項目須要屢次調用地圖和定位,爲此,在script腳本中map和geolocation都設置爲全局函數。java
var map;//全局函數 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}])方法web
獲取當前所在地理位置,調用一次即從新定位一次,定位數據比較精確。 sucCallback爲定位成功回調函數,必填; errCallback爲定位失敗回調函數,選填,若是不填,請設爲null; options爲定位選項,選填,能夠經過timeout參數設置定位的超時時間,默認值爲10s; failTipFlag: 是否在定位失敗時給出提示引導用戶打開受權或打開定位開關。(即將支持)
function showPosition(position) { }
獲取位置座標顯示地圖ajax
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)並在地圖上標註編程
一、標準JSON數據格式json
爲方便展現,此處僅展現數據格式,實際應用作,使用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" } ]
二、地圖標註並計算距離
//地圖標註; getTxMap(newData, latlngs); //兩點間的距離; getDistance(newData, latlngs);
經緯度標註封裝函數
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 href="https://apis.map.qq.com/uri/v1/routeplan?type=walk&from=起步位置&fromcoord=' + 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); } }
計算兩點間的距離函數封裝
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; //拼接新的距離數組數據; 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);
//定位失敗,自動跳轉頁面; function showErr() { //alert("定位失敗!"); window.location.href = "?m=Index&a=error" }
項目開發過程當中,須要本身拾取座標經緯度,以知足初始數據的測試和演示使用。通常會使用騰訊提供的座標拾取器。連接地址:https://lbs.qq.com/tool/getpo...
支持地址 精確/模糊 查詢; 支持POI點座標顯示; 座標鼠標跟隨顯示;
若是非要挑出點毛病的話,地圖拾取框過小了,想爲所欲爲的拾取座標,要縮放或拖拽不少次,心累。
在項目完成測試後,若是遇到成千上百的地址時,一個一個的拾取,好像不是一個合格的開發者的所爲。此時,就須要使用到地址解析和逆解析的API接口,即:在數據導入到數據庫的過程當中,自動批量地將地址轉化爲經緯度座標,知足前端的調用。
本例中使用了騰訊位置服務的WebService API,後端語言使用PHP,簡要的將該過程予以呈現。
一、封裝WebService API接口函數
官方實例,若是在前端直接使用getJSON函數,會出現「同源策略」被阻止,爲此須要後端爬取後,「曲線救國」。
//GET請求示例,注意參數值要進行URL編碼 https://apis.map.qq.com/ws/geocoder/v1/?address=北京市海淀區彩和坊路海淀西大街74號&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
/*地址轉座標封裝函數,文件名稱爲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; } //獲取前端傳入的地址參數; $address = $_GET["address"]; //輸出json數據格式,供前端調用; die(getGeoCoding($address));
二、前端調用
//自動獲取經緯度; 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); } }); }
三、效果演示
在導入地址數據的時候,必定要是省市區街道門牌號,地址越詳細精度越高,不然會解析不出來,謹記!
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
在開發過程當中,默認會這樣引入到前端文件。測試環境和生成環境一致,或者更換環境也是一直,不會出現問題的。可是若是是http和https不一致的協議環境下,引入文件就會出現錯誤提示。
建議的加載方式:src不使用協議名稱,讓其自動匹配。如:
<script charset="utf-8" src="//map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
學習一個新項目的最快捷方式是學會使用官方文檔,由於這些文檔是基礎中的基礎。但官方文檔的有時太官方,有些細節沒法清楚的展現出來。
官方文檔不能解決的問題時,會「面對CSDN編程」,每一個開發者遇到的問題不一樣,開發經驗不一樣,在CSDN上的記錄更多的是爲了不本身下次「入坑」提醒,沒法完整的將項目的細節描述清楚,也是初學者看到人家明明解決了,爲何本身不能夠的。
這裏就牽涉到騰訊地圖附加庫的引入。
<script charset="utf-8" src="://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script>
本項目中就碰見須要計算自動定位的經緯度和各個廁所之間的距離,須要使用geometry
幾何運算庫。在未理解官方文檔的前提下,強行CSDN,走路不少彎路才發現:開發語法明明對了,可是卻沒有計算出距離,就是沒引入對應的附加庫。
<script type="text/javascript" src="//3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
使用自動定位功能,必須引入自動定位的geolocation.min.js
附加庫,無須多言。
若是是首次開發地圖就使用騰訊地圖的話,出現這個錯誤的可能性比較低。若是有百度和高德地圖開發的經驗話,千萬不要想固然。在這個問題上浪費了半個小時才發現,騰訊的經緯度和百度、高德的問題是互換的。
騰訊經緯度
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),//構建點對象的是(經度,緯度)
在使用座標拾取器時,必定要選擇各個對應的工具,導航等牽涉到座標的地方必定要注意。
對於不一樣的廠家地圖的使用,通常都有「先入爲主」 的刻板印象,也有甲方緣由的客觀要求。
對比項 | 騰訊地圖 | 百度地圖 | 高德地圖 |
---|---|---|---|
功能 | 標註、信息框、覆蓋物、計算距離、軌跡、導航等經常使用功能 | 同前 | 同前 |
座標 | 火星座標 | BD-09座標 | 火星座標 |
座標結構 | (39.914850, 116.403765) | (116.4035,39.915) | (116.39, 39.9) |
語法結構 | 同高德 | 百度自有語法 | 同騰訊 |
開發文檔 | 相對集中 | 百度地圖開發平臺已升級到3.0版本,文檔多,類庫多 | 相對集中 |
延伸 | 數據可視化API服務 | 同前 | 同前 |
本次使用版本: JavaScript API 2.0版本,目前咱們提供的JavaScript API GL版本,功能更炫酷齊全,你們能夠嘗試接入使用。
做者:漏刻有時
連接:https://lockdatav.blog.csdn.n...
來源:CSDN
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。