前言
地圖應(yīng)用非常廣泛滴须,目前地圖服務(wù),都提供地圖操作叽奥、標(biāo)注扔水、地點(diǎn)搜索、出行規(guī)劃朝氓、地址解析魔市、街景等接口,功能非常豐富赵哲。在實(shí)際開發(fā)過程中待德,各有優(yōu)劣。本次基于需求枫夺,使用騰訊位置服務(wù)作為一個(gè)公用廁所位置標(biāo)注的H5頁面開發(fā)将宪。
本次使用版本: JavaScript API 2.0版本。
項(xiàng)目需求
1橡庞、項(xiàng)目需求
基于騰訊位置服務(wù)较坛,實(shí)現(xiàn)微信掃描二維碼后,在微信瀏覽器內(nèi)扒最,展示某縣城的公用廁所分布圖丑勤,按照用戶當(dāng)前定位與各個(gè)廁所之間的距離遠(yuǎn)近排序,點(diǎn)擊標(biāo)注點(diǎn)跳轉(zhuǎn)到騰訊地圖進(jìn)行導(dǎo)航吧趣。
2法竞、需求分解
基于上述需求,對(duì)使用到的騰訊位置服務(wù)接口予以分解如下:
騰訊地圖加載强挫;
自動(dòng)定位岔霸;
信息點(diǎn)(POINTS)標(biāo)注maker;
計(jì)算標(biāo)注點(diǎn)之間的距離俯渤;
導(dǎo)航跳轉(zhuǎn)鏈接API接口秉剑;
街道與衛(wèi)星地圖切換控件;
縮放控件稠诲;
開發(fā)實(shí)戰(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诡曙、構(gòu)建騰訊地圖容器
<!--地圖加載-->
<div id="location" onclick="getLocation();"><img src="{$url}{$STATIC}images/location.png" alt=""></div>
<div id="txmap"></div>
3、調(diào)用前端定位組件
由于項(xiàng)目需要多次調(diào)用地圖和定位略水,為此价卤,在script腳本中map和geolocation都設(shè)置為全局函數(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}])方法
獲取當(dāng)前所在地理位置渊涝,調(diào)用一次即重新定位一次慎璧,定位數(shù)據(jù)比較精確。
sucCallback為定位成功回調(diào)函數(shù)跨释,必填胸私;
errCallback為定位失敗回調(diào)函數(shù),選填鳖谈,如果不填岁疼,請(qǐng)?jiān)O(shè)為null;
options為定位選項(xiàng)缆娃,選填捷绒,可以通過timeout參數(shù)設(shè)置定位的超時(shí)時(shí)間,默認(rèn)值為10s;
failTipFlag: 是否在定位失敗時(shí)給出提示引導(dǎo)用戶打開授權(quán)或打開定位開關(guān)贯要。(即將支持)
1)定位成功回調(diào)函數(shù)
function showPosition(position) {
}
獲取位置坐標(biāo)顯示地圖
map = new qq.maps.Map(document.getElementById("txmap"), {
// 地圖的中心地理坐標(biāo)暖侨。
center: new qq.maps.LatLng(position.lat, position.lng),
zoom: 15
});
定義當(dāng)前位置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)
});
讀取信息點(diǎn)(POINTS)并在地圖上標(biāo)注
1、標(biāo)準(zhǔn)JSON數(shù)據(jù)格式
為方便展示崇渗,此處僅展示數(shù)據(jù)格式字逗,實(shí)際應(yīng)用做,使用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扳肛、地圖標(biāo)注并計(jì)算距離
//地圖標(biāo)注;
getTxMap(newData, latlngs);
//兩點(diǎn)間的距離;
getDistance(newData, latlngs);
經(jīng)緯度標(biāo)注封裝函數(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);
}
}
計(jì)算兩點(diǎn)間的距離函數(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、定位失敗回調(diào)函數(shù)
//定位失敗乘碑,自動(dòng)跳轉(zhuǎn)頁面;
function showErr() {
//alert("定位失斖谙ⅰ!");
window.location.href = "?m=Index&a=error"
}
坐標(biāo)經(jīng)緯度拾取
1兽肤、騰訊坐標(biāo)拾取器
項(xiàng)目開發(fā)過程中套腹,需要自己拾取坐標(biāo)經(jīng)緯度,以滿足初始數(shù)據(jù)的測試和演示使用资铡。一般會(huì)使用騰訊提供的坐標(biāo)拾取器电禀。鏈接地址:https://lbs.qq.com/tool/getpoint/index.html。
支持地址 精確/模糊 查詢笤休;
支持POI點(diǎn)坐標(biāo)顯示蝉揍;
坐標(biāo)鼠標(biāo)跟隨顯示荣暮;
如果非要挑出點(diǎn)毛病的話超全,地圖拾取框太小了钝尸,想隨心所欲的拾取坐標(biāo)役听,要縮放或拖拽很多次,心累。
2、WebService API地址解析(地址轉(zhuǎn)坐標(biāo))
在項(xiàng)目完成測試后辕坝,如果遇到成千上百的地址時(shí),一個(gè)一個(gè)的拾取荐健,好像不是一個(gè)合格的開發(fā)者的所為酱畅。此時(shí),就需要使用到地址解析和逆解析的API接口江场,即:在數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫的過程中纺酸,自動(dòng)批量地將地址轉(zhuǎn)化為經(jīng)緯度坐標(biāo),滿足前端的調(diào)用址否。
本例中使用了騰訊位置服務(wù)的WebService API餐蔬,后端語言使用PHP,簡要的將該過程予以呈現(xiàn)在张。
1、封裝WebService API接口函數(shù)
官方實(shí)例矮慕,如果在前端直接使用getJSON函數(shù)帮匾,會(huì)出現(xiàn)“同源策略”被阻止,為此需要后端爬取后痴鳄,“曲線救國”瘟斜。
//GET請(qǐng)求示例,注意參數(shù)值要進(jìn)行URL編碼
https://apis.map.qq.com/ws/geocoder/v1/?address=北京市海淀區(qū)彩和坊路海淀西大街74號(hào)&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
/*地址轉(zhuǎn)坐標(biāo)封裝函數(shù)痪寻,文件名稱為points.php
*$address螺句,需要轉(zhuǎn)化的地址,越詳細(xì)經(jīng)緯度精度越高橡类;
*/
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ù)格式蛇尚,供前端調(diào)用;
die(getGeoCoding($address));
2、前端調(diào)用
//自動(dòng)獲取經(jīng)緯度;
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顾画、效果演示
<font color=red>在導(dǎo)入地址數(shù)據(jù)的時(shí)候取劫,一定要是省市區(qū)街道門牌號(hào),地址越詳細(xì)精度越高研侣,否則會(huì)解析不出來谱邪,謹(jǐn)記!</font>
注意事項(xiàng)
1庶诡、script標(biāo)簽加載API服務(wù)
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
在開發(fā)過程中惦银,默認(rèn)會(huì)這樣引入到前端文件。測試環(huán)境和生成環(huán)境一致,或者更換環(huán)境也是一直扯俱,不會(huì)出現(xiàn)問題的书蚪。但是如果是http和https不一致的協(xié)議環(huán)境下,引入文件就會(huì)出現(xiàn)錯(cuò)誤提示蘸吓。
建議的加載方式:src不使用協(xié)議名稱善炫,讓其自動(dòng)匹配。如:
<script charset="utf-8" src="http://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
2库继、附加庫的引入
學(xué)習(xí)一個(gè)新項(xiàng)目的最快捷方式是學(xué)會(huì)使用官方文檔箩艺,因?yàn)檫@些文檔是基礎(chǔ)中的基礎(chǔ)。但官方文檔的有時(shí)太官方宪萄,有些細(xì)節(jié)無法清楚的展示出來艺谆。
官方文檔不能解決的問題時(shí),會(huì)“面對(duì)CSDN編程”拜英,每個(gè)開發(fā)者遇到的問題不同静汤,開發(fā)經(jīng)驗(yàn)不同,在CSDN上的記錄更多的是為了避免自己下次“入坑”提醒居凶,無法完整的將項(xiàng)目的細(xì)節(jié)描述清楚虫给,也是初學(xué)者看到人家明明解決了,為什么自己不可以的侠碧。
這里就牽涉到騰訊地圖附加庫的引入抹估。
<script charset="utf-8"
src="://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script>
本項(xiàng)目中就遇見需要計(jì)算自動(dòng)定位的經(jīng)緯度和各個(gè)廁所之間的距離,需要使用geometry
幾何運(yùn)算庫弄兜。在未理解官方文檔的前提下药蜻,強(qiáng)行CSDN,走路很多彎路才發(fā)現(xiàn):開發(fā)語法明明對(duì)了替饿,但是卻沒有計(jì)算出距離语泽,就是沒引入對(duì)應(yīng)的附加庫。
3视卢、自動(dòng)定位組件庫
<script type="text/javascript"
src="http://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
使用自動(dòng)定位功能踱卵,必須引入自動(dòng)定位的geolocation.min.js
附加庫,無須多言据过。
4颊埃、經(jīng)緯度位置
如果是首次開發(fā)地圖就使用騰訊地圖的話,出現(xiàn)這個(gè)錯(cuò)誤的可能性比較低蝶俱。如果有百度和高德地圖開發(fā)的經(jīng)驗(yàn)話班利,千萬不要想當(dāng)然。在這個(gè)問題上浪費(fèi)了半個(gè)小時(shí)才發(fā)現(xiàn)榨呆,騰訊的經(jīng)緯度和百度罗标、高德的問題是互換的庸队。
騰訊經(jīng)緯度
new qq.maps.LatLng(39.914850, 116.403765); //構(gòu)建對(duì)象的是(緯度,經(jīng)度)
百度經(jīng)緯度
map.centerAndZoom(new BMap.Point(116.4035,39.915),8); //構(gòu)建對(duì)象的是(經(jīng)度闯割,緯度)
高德經(jīng)緯度
position: new AMap.LngLat(116.39, 39.9),//構(gòu)建點(diǎn)對(duì)象的是(經(jīng)度彻消,緯度)
在使用坐標(biāo)拾取器時(shí),一定要選擇各個(gè)對(duì)應(yīng)的工具宙拉,導(dǎo)航等牽涉到坐標(biāo)的地方一定要注意宾尚。
5、騰訊谢澈、百度和高德地圖開發(fā)比較
對(duì)于不同的廠家地圖的使用煌贴,一般都有“先入為主” 的刻板印象,也有甲方原因的客觀要求锥忿。
對(duì)比項(xiàng) | 騰訊地圖 | 百度地圖 | 高德地圖 |
---|---|---|---|
功能 | 標(biāo)注牛郑、信息框、覆蓋物敬鬓、計(jì)算距離淹朋、軌跡、導(dǎo)航等常用功能 | 同前 | 同前 |
坐標(biāo) | 火星坐標(biāo) | BD-09坐標(biāo) | 火星坐標(biāo) |
坐標(biāo)結(jié)構(gòu) | (39.914850, 116.403765) | (116.4035,39.915) | (116.39, 39.9) |
語法結(jié)構(gòu) | 同高德 | 百度自有語法 | 同騰訊 |
開發(fā)文檔 | 相對(duì)集中 | 百度地圖開發(fā)平臺(tái)已升級(jí)到3.0版本钉答,文檔多础芍,類庫多 | 相對(duì)集中 |
延伸 | 數(shù)據(jù)可視化API服務(wù) | 同前 | 同前 |
總結(jié)
本次使用版本: JavaScript API 2.0版本,目前我們提供的JavaScript API GL版本数尿,功能更炫酷齊全仑性,大家可以嘗試接入使用。
作者:漏刻有時(shí)
鏈接:https://lockdatav.blog.csdn.net/article/details/113412823
來源:CSDN
著作權(quán)歸作者所有砌创。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)虏缸,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處鲫懒。