把你的前端拿捏得死死的,每天學習得爽爽的,達達前端程式設計師,微信搜尋【程式設計師哆啦A夢】關注這個不一樣的程式設計師。
前言
作為一名在職崗位為【前端開發工程師】的程式設計師,我開發的應用程式經常需要獲取使用者位置資訊,需要再某些場合下使用展示地圖以及地圖商的某些地點,需要獲取行政區劃列表(省市區)以及地址詳情資訊,需要在地圖上規劃一條(動態)路線,軌跡回放,小車移動,需要建立資訊視窗,用於地點的摘要性資訊的展示。
公司內做的是共享專案, 場景是這樣的,一種常見共享充電寶(功能差不多和流行的共享單車一樣),在做小程式首頁時,需要做到的是掃碼充電,聯絡客服(問題反饋),獲取地理位置,開篇即是一副地理位置,在你附近獲取到區域內店鋪資訊,點選該店的logo標誌可以獲取該店的地理位置,營業時間,店名,距離,是否當前該店裡是否有可借的充電寶等資訊。
共享充電電動車?,首頁也是一副地理位置地圖,可以獲取你附近最近的共享電動車,獲取車的地址,狀態等資訊。顯示該車的剩餘電量,使用記錄,租借訂單,獲取行程軌跡,某時間段內的里程,動態顯示軌跡等。
涉及到的共享其實內容很多(如除了電動車,充電寶,還可租借裝置等),但大都功能幾乎相同,需要交押金,租借費用,信用免押金等。開發過app,H5,web網站,小程式專案都與地圖相關的位置服務息息相關,讓我說說與位置服務有關的故事。
下面主要還是講解其中的關於地圖功能等功能,使用的也是騰訊位置開發服務。會一步一步說明,做一些案例展示,程式碼說明,使用教程。(注意這裡我回去看開發教程,儘量把每個功能都熟悉地說明一下使用方法)
一、騰訊位置服務是什麼?
騰訊位置服務無疑是獲取位置服務等資訊內容,該產品亮點:
- 定位:為合作伙伴和廣大開發者提供完善的位置解決方案,已為社交、出行、遊戲、商業、O2O、物流等領域提供專業精準的定位服務
- 地圖:騰訊位置服務在多平臺為開發者提供了豐富的地圖展現形式,幫助從屬於不同領域的開發人員輕鬆完成構建地圖並在其基礎上打造專屬內容的工作。同時配合海量資料、個性化定製、視覺化等能力滿足各個行業場景下對地圖的需求
- 地點搜尋:基於海量鮮活地點(POI)資料,提供周邊搜尋,城市範圍搜尋,關鍵詞輸入提示、分類篩選等多種搜尋能力,面向社交、物流、出行等行業打造專屬搜尋策略,體驗更勝一籌
- 路線規劃:根據出發地、目的地以及路線策略設定,結合精準的實時交通路況提供駕車、步行、騎行、公交路線規劃能力,助力開發者為使用者提供貼心、人性化的出行體驗
- 微信小程式解決方案:騰訊位置服務全面擁抱小程式生態,從服務API、基礎地圖元件、外掛、行業方案等多個層面服務不同場景需求的小程式開發者,助力小程式插上地圖的“翅膀”!
- 個性化地圖:個性化樣式:千行千面,助力開發者根據自身產品的使用場景、介面色調, 選取或者建立風格匹配的地圖樣式,體驗更勝一籌;個性化圖層:真實酷炫,助力開發者將精美繪圖生成地圖瓦片並置於地圖之上,讓旅遊景點、大學高校等區域的展示效果與眾不同
二、使用步驟
1.uniapp開發map說明
使用uniapp是因為它是一個使用vue.js開發所有前端應用的框架,開發者編寫一套程式碼,可以釋出到ios,android,web以及各種小程式,快應用等多個平臺。
使用map
地圖元件開發,地圖元件用於展示地圖(使用的時騰訊地圖),說一下它的屬性有:
longitude
(型別為Number
,沒有預設值,表示中心經度)latitude
(型別為Number
,沒有預設值,表示中心緯度)scale
(型別為Number
,預設值為16,縮放級別取值範圍為5-18)markers
(型別為Array
陣列,型別為陣列即表示地圖上可以有多個,沒有預設值,表示標記點)polyline
(型別為Array
陣列,沒有預設值,表示路線,陣列上的所有點連成線)circles
(型別Array
陣列,表示圓)controls
(型別Array
陣列,表示控制元件)include-points
(型別Array
陣列,表示縮放視野已包含所有給定的座標點)enable-3D
(型別為Boolean
,預設值為false,表示是否顯示3D摟塊)show-compass
(型別為Boolean
,預設值為false,表示為是否顯示指南針)enable-overlooking
(型別為Boolean
,預設值為false,表示為是否開啟俯視)enable-satellite
(型別為Boolean
,預設值為false,表示為是否開啟衛星圖)enable-traffic
(型別為Boolean
,預設值為false,表示為是否開啟實時路況)show-location
(型別為Boolean
,表示顯示帶有方向的當前定位點)polygons
(型別Array
,表示為多邊形)
點選屬性
@markertap
-表示點選標記點時觸發,e.detail={markerId}
@labeltap
-表示點選label
時觸發,e.detail = {markerId}
@callouttap
-表示點選標記點對應的氣泡時觸發,e.detail = {markerId}
@controltap
-表示點選控制元件時觸發,e.detail = {controlId}
@regionchange
-表示視野發生變化時觸發@tap
-表示點選地圖時觸發;App-nuve
、微信小程式2.9支援返回經緯度@updated
-表示在地圖渲染更新完成時觸發
我們在寫map
元件時,元件的寬/高推薦寫直接量,比如說是750rpx
,不要設定百分比值,在uni-app
中只支援gcj02
座標。
介紹markers屬性-型別為陣列Array
由之前描述可知,markers屬性型別為Array,表示標記點用於在地圖上顯示標記的位置。這個陣列屬性,它裡面有它的物件配置屬性,分別是:
id
,表示 標記點id
,型別為Number
,必填項,marker
點選事件回撥會返回此id
,建議為每個marker
設定上Number
型別id
,保證更新marker
時有更好的效能。latitude
,緯度,型別Number
,必填項,浮點數,範圍-90 ~ 90
longitude
,經度,型別Number
,必填項,浮點數,範圍-180 ~ 180
title
,標註點名,型別String
,不是必填,點選時顯示,callout
存在時將被忽略iconPath
,顯示的圖示,型別String
,必填項,專案目錄下的圖片路徑rotate
,旋轉角度,型別Number
,不是必填,順時針旋轉的角度,範圍0 ~ 360
,預設為 0alpha
,標註的透明度,型別Number
,不是必填,預設1,無透明,範圍0 ~ 1
width
,標註圖示寬度,型別Number
,不是必填,預設為圖片實際寬度height
,標註圖示高度,型別Number
,不是必填,預設為圖片實際高度callout
,自定義標記點上方的氣泡視窗,型別Object
,不是必填 - 可識別換行符label
,為標記點旁邊增加標籤,型別Object
,不是必填 - 可識別換行符anchor
,經緯度在標註圖示的錨點,預設底邊中點,不是必填,{x, y},x表示橫向(0-1),y表示豎向(0-1)。{x: .5, y: 1} 表示底邊中點
marker 上的氣泡 callout(Object型別)
marker
陣列 上屬性 callout
物件使用屬性:
content
,文字,String
color
,文字顏色,String
fontSize
,文字大小,Number
borderRadius
,callout
邊框圓角,Number
bgColor
,背景色,String
padding
,文字邊緣留白,Number
display
,'BYCLICK':點選顯示; 'ALWAYS':常顯
,String
textAlign
,文字對齊方式。有效值:left, right, center
,String
marker 上的標籤 label(Object型別)
content
,文字,String
color
,文字顏色,String
fontSize
,文字大小,Number
- x,label的座標,原點是
marker
對應的經緯度,Number
- y,label的座標,原點是
marker
對應的經緯度,Number
- borderWidth,邊框寬度,Number
- borderColor,邊框顏色,String
- borderRadius,邊框圓角,Number
- bgColor,背景色,String
- padding,文字邊緣留白,Number
- textAlign,文字對齊方式。有效值:
left, right, center
,String
polyline
polyline
表示指定一系列座標點,從陣列第一項連線至最後一項
points
,經緯度陣列,型別為Array
,必填,如:[{latitude: 0, longitude: 0}]
color
,線的顏色,型別為String
,不必填,如:#0000AA
width
,線的寬度,型別為Number
,不必填dottedLine
,是否虛線,型別為Boolean
,不必填,預設值false
arrowLine
,帶箭頭的線,型別為Boolean
,不必填,預設值為false
arrowIconPath
,更換箭頭圖示,型別為String
,不必填,在arrowLine
為true
時,預設帶箭頭的線時生效borderColor
,線的邊框顏色,型別為String
,不必填borderWidth
,線的厚度,型別為Number
,不必填
polygon
polygon
指定一系列座標點,根據points
座標資料生成閉合多邊形
points
,經緯度陣列,array
,必填,如:[{latitude: 0, longitude: 0}]
strokeWidth
,描邊的寬度,Number
,否strokeColor
描邊的顏色,String
,否fillColor
,填充顏色,String
,否zIndex
,設定多邊形Z
軸數值,Number
,否
circles
circles
在地圖上顯示圓
latitude
,緯度,Number
,必填,浮點數,範圍-90 ~ 90
longitude
,經度,Number
,必填,浮點數,範圍-180 ~ 180
color
,描邊的顏色,String
,不必填,如:#0000AA
fillColor
,填充顏色,String
,不必填,如:#0000AA
radius
,半徑,Number
,必填strokeWidth
,描邊的寬度,Number
,不必填
controls
controls
在地圖上顯示控制元件,控制元件不隨著地圖移動
id
,控制元件id
,Number
,不必填,在控制元件點選事件回撥會返回此idposition
,控制元件在地圖的位置,Object
,必填,控制元件相對地圖位置iconPath
,顯示的圖示,String
,必填,專案目錄下的圖片路徑,支援相對路徑寫法,以'/'
開頭則表示相對專案根目錄;也支援臨時路徑clickable
,是否可點選,Boolean
,不必填,預設不可點選
position
left
,距離地圖的左邊界多遠,Number
,不必填,預設為0top
,距離地圖的上邊界多遠,Number
,不必填,預設為0width
,控制元件寬度,Number
,不必填,預設為圖片寬度height
,控制元件高度,Number
,不必填,預設為圖片高度
注意在uniapp中地圖元件的經緯度必填,如果不填,經緯度則預設值是北京的經緯度。
2.uniapp使用map元件
基本使用方法
使用uniapp開發中的map元件,基本使用方法:
<font color=#999AAA >程式碼如下(示例):
<map :scale="scale" style="width: 100%; height: 100%;"
enable-3D="false" show-compass="false" enable-overlooking="false"
:enable-satellite="false" :enable-traffic="false" show-location="false"
:latitude="latitude" :longitude="longitude" :markers="covers">
</map>
markers
屬性的使用,<font color=#999AAA >程式碼如下(示例):
markers: [{
id: 1, // Number
title: '1', // String-標註點名
rotate: 180, // Number - 順時針旋轉的角度,範圍 0 ~ 360,預設為 0
alpha: 0.5, // 預設1,無透明,範圍 0 ~ 1
latitude: 39.899,
longitude: 116.39742,
width: 30,
height: 30,
// callout: {
// display: "BYCLICK",
// padding: 10,
// borderRadius: 5,
// content: '',
// },
// anchor: {},
iconPath: '../../../static/location.png', // 顯示的圖示
}, {
id: 2,
title: '2', // String
latitude: 39.90,
longitude: 116.39,
callout: {
color: '#007AFF', // 文字顏色
bgColor: '#563BFF', // 背景色
display: "ALWAYS", // 'BYCLICK':點選顯示; 'ALWAYS':常顯
fontSize: 15,
textAlign: 'left', // 文字對齊方式。有效值: left, right, center
padding: 10, // 文字邊緣留白
borderRadius: 5,
content: '騰訊地圖',
},
label: {
content: 'Jeskson',
color: '#000000',
fontSize: 12,
borderWidth: 12,
borderColor: '#007AFF',
borderRadius: 5,
padding: 5,
textAlign: 'center',
bgColor: '#563BFF',
},
iconPath: '../../../static/location.png'
}]
預覽效果如下:
controls:[{
// 在地圖上顯示控制元件,控制元件不隨著地圖移動
id: 1, // 控制元件id
iconPath:'../../static/icon.png', // 顯示的圖示
position:{
// 控制元件在地圖的位置
left: 15,
top: 15,
width: 50,
height: 50
},
}],
地址搜尋
uni-app
只支援gcj02
座標
uni.getLocation(OBJECT)
中的object
引數
獲取當前的地理位置、速度。 在微信小程式中,當使用者離開應用後,此介面無法呼叫,除非申請後臺持續定位許可權;當使用者點選“顯示在聊天頂部”時,此介面可繼續呼叫。
OBJECT引數說明
type
,String
,不必填,預設為wgs84
返回gps
座標,gcj02
返回國測局座標,可用於uni.openLocation
的座標,app
平臺高德SDK
僅支援返回gcj02
altitude
,Boolean
,不必填,傳入true
會返回高度資訊,由於獲取高度需要較高精確度,會減慢介面返回速度geocode
,Boolean
,不必填,預設false
,是否解析地址資訊success
,Function
,必填,介面呼叫成功的回撥函式,返回內容詳見返回引數說明fail
,Function
,不必填,介面呼叫失敗的回撥函式complete
,Function
,不必填,介面呼叫結束的回撥函式(呼叫成功、失敗都會執行)
對於success
返回引數說明:
latitude
,緯度,浮點數,範圍為-90~90
,負數表示南緯longitude
,經度,浮點數,範圍為-180~180
,負數表示西經speed
,速度,浮點數,單位m/s
accuracy
,位置的精確度altitude
,高度,單位m
verticalAccuracy
,垂直精度,單位m
(Android
無法獲取,返回0
)horizontalAccuracy
,水平精度,單位m
address
,地址資訊(僅App
端支援,需配置geocode
為true
)
address
地址資訊說明
country
,String
,國家 如“中國”,沒有則返回undefined
province
,String
,省份名稱 如“北京市”,沒有則返回undefined
city
,String
,城市名稱,如“北京市”,沒有則返回undefined
district
,String
,區,縣名稱 如“朝陽區”,沒有則返回undefined
street
,String
,街道資訊,如“酒仙橋路”,沒有則返回undefined
streetNum
,String
,獲取街道門牌號資訊,如“3號”,沒有則返回undefined
poiName
,String POI
資訊,如“電子城.國際電子總部”,沒有則返回undefined
postalCode
,String
,郵政編碼,如“100016”
,沒有則返回undefined
cityCode
,String
,城市程式碼,如“010”
,沒有則返回undefined
uni.chooseLocation(OBJECT)
開啟地圖選擇位置。
latitude
,String
,不必填,目標地緯度longitude
,String
,不必填,目標地經度keyword
,String
,不必填,搜尋關鍵字,僅App平臺支援success
,Function
,必填fail
,Function
,不必填complete
,Function
,不必填
success
返回引數說明:
name
,位置名稱address
,詳細地址latitude
,緯度,浮點數,範圍為-90~90
,負數表示南緯,使用gcj02
國測局座標系。longitude
,經度,浮點數,範圍為-180~180
,負數表示西經,使用gcj02
國測局座標系。
<font color=#999AAA >程式碼如下(示例):
chooseLocation(e) { //開啟地圖選擇位置
uni.chooseLocation({
success: res => {
console.log('位置名稱:' + res.name);
console.log('詳細地址:' + res.address);
console.log('緯度:' + res.latitude);
console.log('經度:' + res.longitude);
uni.getLocation({
type: 'gcj02',
altitude:true,
geocode:true,
success: function(res) {
console.log('當前位置的經度:' + res.longitude);
console.log('當前位置的緯度:' + res.latitude);
}
});
console.log('省:' + res.address.slice(0, res.address.indexOf('省') + 1));
console.log('市:' + res.address.slice(res.address.indexOf('省') + 1, res.address.indexOf('市') + 1));
console.log('區:' + res.address.slice(res.address.indexOf('市') + 1, res.address.indexOf('區') + 1));
this.query.address = res.address;
this.query.latitude = res.latitude;
this.query.longitude = res.longitude;
this.query.province = res.address.slice(0, res.address.indexOf('省') + 1)
this.query.city = res.address.slice(res.address.indexOf('省') + 1, res.address.indexOf('市') + 1)
this.query.district = res.address.slice(res.address.indexOf('市') + 1, res.address.indexOf('區') + 1)
}
});
},
預覽效果:
獲取附近的動態,點聚合
uni.getNetworkType(OBJECT)
獲取網路型別。
uni.createMapContext(mapId,this)
建立並返回 map
上下文 mapContext
物件。在自定義元件下,第二個引數傳入元件例項this
,以操作元件內 <map>
元件。
mapContext
-mapContext
通過 mapId
跟一個 <map>
元件繫結,通過它可以操作對應的 <map>
元件。
該物件得方法列表:
getCenterLocation
OBJECT
獲取當前地圖中心的經緯度,返回的是gcj02
座標系,可以用於uni.openLocatio
nmoveToLocation
OBJECT
將地圖中心移動到當前定位點,需要配合map
元件的show-location
使用translateMarker
OBJECT
平移marker
,帶動畫includePoints
OBJECT
縮放視野展示所有經緯度getRegion
OBJECT
獲取當前地圖的視野範圍getScale
OBJECT
獲取當前地圖的縮放級別$getAppMap
獲取原生地圖物件plus.maps.Map
getCenterLocation
的 OBJECT
引數列表
success
Function
不必填,介面呼叫成功的回撥函式 ,res = { longitude: "經度", latitude: "緯度"}
moveToLocation
的 OBJECT
引數列表 - 可不必填
translateMarker
的 OBJECT
引數列表
markerId
Number
必填 指定marker
destination
Object
必填 指定marker
移動到的目標點autoRotate
Boolean
不必填 移動過程中是否自動旋轉marker
rotate
Number
不必填marker
的旋轉角度duration
Number
不必填 動畫持續時長,預設值1000ms
,平移與旋轉分別計算animationEnd
Function
不必填 動畫結束回撥函式fail
Function
不必填 介面呼叫失敗的回撥函式
<font color=#999AAA >程式碼如下(示例):
<view id="activeMap">
<view @tap="activeMarker={}">
<view class="page-body map-view" style="z-index: 1;position: relative;">
<view class="page-section page-section-gap map-view">
<map :markers="shops" id="map1" :show-location="true" :latitude="latitude" :longitude="longitude" @regionchange="regionChange"
@markertap="markerTap" @tap="activeMarker={}">
<!-- @markertap 點選標記點時觸發,e.detail = {markerId}-->
<!-- @tap 點選地圖時觸發-->
<!-- @regionchange 視野發生變化時觸發-->
</map>
<cover-image class="map-image" src="../static/address.png"></cover-image>
</view>
</view>
</view>
</view>
regionChange() { // 移動地圖後重新獲取門店
uni.createMapContext('map1', this).getCenterLocation({
success: res => {
console.log(res.latitude)
console.log(res.longitude)
this.shopTimeout = setTimeout(_ => {
this.shops = [{
address: "廣東省汕頭市xxx區xx大道1",
distance: 122,
end_time: "1",
id: 2,
latitude: "22.72078500009999",
longitude: "114.36090200009999",
shop: {
iconPath: '/static/logo.png',
id: 3,
latitude: "22.72078500009999",
longitude: "114.36090200009999",
height: 34,
width: 34,
shop: {return: 0}
},
return: 0,
height: 34,
width: 34,
start_time: "1",
store_name: "三星大酒店",
iconPath: '/static/shop.png',
}]
}, 500)
},
fail: res => {
uni.showModal({
content: '獲取位置失敗',
showCancel: false
})
}
})
},
預覽效果圖如下:
地圖上標註附近的人
<font color=#999AAA >程式碼如下(示例):
list: [{
id: 1264640,
user_id: 335187,
place: "Jeskson市",
text: "dadaqianduan.cn",
latitude: "27.267520",
longitude: "111.727120",
status: "normal",
nickname: "dada",
avatar: "https://image.aishencn.com/2020/10/20/002207441_40845724-user.jpg",
distance: 13419,
}, {
id: 1272720,
user_id: 36950,
place: "dadaqianduan市",
text: "dadaqianduan.cn",
latitude: "27.257640",
longitude: "111.747910",
deletetime: null,
status: "normal",
nickname: "dadaqianduan",
avatar: "https://image.aishencn.com/2020/04/09/004135379_37869100-user.jpg",
distance: 27070,
}, {
id: 1316740,
user_id: 366172,
place: "dadaqianduan.cn",
text: "dadaqianduan.cn",
images: "https://image.aishencn.com/2020/11/04/215134979_98197351-bbs.jpg",
latitude: "27.257430",
longitude: "111.732960",
status: "normal",
nickname: "dada",
avatar: "https://image.aishencn.com/2020/11/04/182622730_98197351-user.venus/cache/ext/crop/1604518314542_jpg",
distance: 27190,
images_arr: ["https://image.aishencn.com/2020/11/04/215134979_98197351-bbs.jpg"]
}],
預覽效果如圖:
定位附近門店
<font color=#999AAA >程式碼如下(示例):
// 兩點間距離
distance(la1, lo1, la2, lo2) {
var La1 = (la1 * Math.PI) / 180.0
var La2 = (la2 * Math.PI) / 180.0
var La3 = La1 - La2
var Lb3 = (lo1 * Math.PI) / 180.0 - (lo2 * Math.PI) / 180.0
var s =
2 *
Math.asin(
Math.sqrt(
Math.pow(Math.sin(La3 / 2), 2) +
Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(Lb3 / 2), 2)
)
)
s = s * 6378.137 //地球半徑
s = Math.round(s * 10000) / 10000
return s
},
// 計算最近的距離
nearDistance(array, centerLatitude, centerLongitude) {
let temp = []
for (let i = 0, l = array.length; i < l; i++) {
const element = array[i]
let d = this.distance(
element.latitude,
element.longitude,
centerLatitude,
centerLongitude
)
temp.push(d)
}
this.distanceL = Math.min.apply(null, temp)
}
效果如下圖:
滑動軌跡
<font color=#999AAA >程式碼如下(示例):
<map :polyline="polyline" :scale="scale" id="maps" :markers="markers" :latitude="center.latitude"
:longitude="center.longitude">
</map>
// 播放標記點
playMarkars() {
if (this.polyline.length == 0) {
uni.showModal({
content: '當前時間範圍內沒有軌跡,無法播放!',
})
this.isPlay = false // 無
this.playIndex = 0 // 第一個
return
}
this.playIndex = Math.min(this.points.length - 1, this.playIndex)
this.markers = [this.formatMarker(this.points[this.playIndex++], 'ALWAYS')]
this.timer = setInterval(_ => {
var i = this.playIndex++
this.nextAdaress(i);
if (i >= this.points.length) {
clearInterval(this.timer)
this.isPlay = false
this.playIndex = 0
this.initMarkers()
return
}
this.markers = [this.formatMarker(this.points[i], 'ALWAYS')]
}, 1000)
},
formatMarker(point, display = "BYCLICK") {
let content = [
"時間:" + parseTime(point.create_time),
"運動狀態:" + (point.sport == 1 ? '運動' : '靜止'),
"地址:" + point.address || ''
]
return {
id: point.id,
iconPath: '/static/dada.png',
width: 35,
height: 35,
latitude: point.latitude,
longitude: point.longitude,
callout: {
display: display,
padding: 10,
borderRadius: 5,
content: content.join("\n")
}
}
},
nextAdaress(index) {
const len = 10;
if (this.isGetAddress) {
return
}
for (let i = 0; i < len; i++) {
if (!this.points[i + index]) {
break
}
if (this.points[i + index].address === undefined) {
this.isGetAddress = true
this.getAddress(i + index, len * 2, _ => {
this.isGetAddress = false
});
break
}
}
},
圖片效果如下:
vue接入騰訊地圖介面
騰訊(推薦)
https://apis.map.qq.com/ws/location/v1/ip={$ip}&key={$key}
需要申請key
,速度快,有基本資訊
首頁點選可以進行註冊,申請一個獲取key
:https://lbs.qq.com?lbs_invite=VJJIFLV
key管理,建立新金鑰,填寫相應資訊即可
1.建立地圖預覽效果圖如下:
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=申請的key"></script>
<script type="text/javascript">
function initMap() {
var center = new TMap.LatLng(39.984104, 116.307503);
//初始化地圖
var map = new TMap.Map("container", {
rotation: 20,//設定地圖旋轉角度
pitch:30, //設定俯仰角度(0~45)
zoom:12,//設定地圖縮放級別
center: center//設定地圖中心點座標
});
}
</script>
2.地圖載入完成效果圖:
<script>
function initMap() {
//初始化地圖
var map = new TMap.Map("container", {
center: new TMap.LatLng(39.984104, 116.307503)
});
//監聽地圖瓦片載入完成事件
map.on("tilesloaded", function () {
document.getElementById("tip").innerHTML = "地圖瓦片已載入完成"
})
}
</script>
3.非同步載入地圖
<script>
function initMap() {
var map = new TMap.Map("container", {
pitch: 45,
zoom: 12,
center: new TMap.LatLng(39.984104, 116.307503)
});
}
function loadScript() {
//建立script標籤,並設定src屬性新增到body中
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://map.qq.com/api/gljs?v=1.exp&key=申請key";
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
4.同時載入兩個地圖效果圖如下:
<script>
function initMap() {
//初始化地圖一
var mapOne = new TMap.Map("containerOne", {
pitch:45,
center: new TMap.LatLng(39.984104, 116.307503)
});
//初始化地圖二
var mapTwo = new TMap.Map("containerTwo", {
center: new TMap.LatLng(39.984104, 116.307503)
});
}
</script>
5.獲取地圖中心效果如下圖:
<script>
var centerInfo = document.getElementById("center-info");
var center = new TMap.LatLng(39.984104, 116.307503);//設定中心點座標
//初始化地圖
var map = new TMap.Map("container", {
center: center
});
//獲取地圖中心點事件
function getCenter() {
var mapCenter = map.getCenter(); //獲取地圖中心點座標
centerInfo.innerHTML = "當前地圖中心為: " + mapCenter.getLat().toFixed(6) + "," + mapCenter.getLng().toFixed(6);
}
//設定地圖中心點事件
function setCenter() {
map.setCenter(new TMap.LatLng(39.908802,116.397502));//座標為天安門
centerInfo.innerHTML = "當前地圖中心為: 39.908802,116.397502";
}
</script>
6.地圖平移效果圖如下:
<script>
function initMap() {
var position = document.getElementById("position");
var txt = document.getElementById("txt");
var center = new TMap.LatLng(39.984104, 116.307503);//設定中心點座標
//初始化地圖
var map = new TMap.Map("container", {
center: center
});
location.innerHTML = map.getCenter().toString();
//監聽地圖開始平移
map.on("panstart", function () {
txt.innerHTML = "地圖開始平移"
})
//監聽地圖平移
map.on("pan",function(){
txt.innerHTML = "地圖正在平移";
position.innerHTML = map.getCenter().toString();//獲取地圖中心點
})
//監聽地圖平移結束
map.on("panend",function(){
txt.innerHTML = "地圖結束平移";
})
}
</script>
3.vue接入騰訊地圖
<template>
<div>
<div id="map" style="width:500px;height:500px;"></div>
</div>
</template>
<script>
export default {
data() {
return {
longitude: "",
latitude: ""
};
},
methods: {
init() {
let address = "";
let that = this;
var center = new qq.maps.LatLng(34.754152, 113.667636);
var map = new qq.maps.Map(document.getElementById('map'), {
center: center,
zoom: 13,
disableDefaultUI: true
});
var marker = new qq.maps.Marker({
position: center,
map: map
});
var infoWin = new qq.maps.InfoWindow({
map: map
});
var geocoder = new qq.maps.Geocoder({
complete: function(res) {
console.log(res);
address = res.detail.nearPois[0].name;
}
});
qq.maps.event.addListener(map, "click", function(event) {
this.longitude = event.latLng.getLat();
this.latitude = event.latLng.getLng();
console.log(event);
let lat = new qq.maps.LatLng(this.longitude, this.latitude);
geocoder.getAddress(lat);
setTimeout(() => {
infoWin.open();
infoWin.setContent(
'<div style="text-align:center;white-space:nowrap;">' +
address +
"</div>"
);
infoWin.setPosition(event.latLng);
}, 200);
});
}
},
mounted() {
this.init();
}
};
</script>
<style scoped>
</style>
使用前需要在index.html
裡引入<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
才可以使用地圖。
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=yourkey"></script>
<template>
<div>
<div id="container" style="width:500px;height:500px;"></div>
</div>
</template>
<script>
export default{
data() {
return {
longitude:39.956987, // 經度
latitude:116.235128 // 緯度
}
},
mounted () {
this.init();
},
methods:{
init() {
var myLatlng = new qq.maps.LatLng(39.945687,116.3976968);
var myOptions = {
zoom: 8, // 設定地圖縮放級別
center: myLatlng, // 設定中心點樣式
mapTypeId: qq.maps.MapTypeId.ROADMAP
}
var map = new qq.maps.Map(document.getElementById("container"), myOptions);
}
}
}
</script>
建立地圖例項
var map=new qq.maps.Map(document.getElement('container'),{
center,//座標,即最初顯示的地圖中心
zoom //縮放級別,即顯示的比例
})
給地圖新增事件
qq.maps.event.addListener(map,'click',function(res){
// res即點選後的位置資訊
})
新增標記
var marker=new qq.maps.Marker({
position, // 標記點的位置,也可以是通過IP獲取到的座標
map, // 標記在哪個地圖上
animation, // 標記顯示時的動畫效果
title, // 滑鼠懸浮到標記上時的標題
draggable // 是否可拖拽
})
建立資訊視窗
var info=new qq.maps.InfoWindow({
map, // 標記在哪個地圖上
content // 資訊視窗的內容
})
覆蓋物
var polyline=new qq.maps.Polyline({
map, // 標記在哪個地圖上
path, // 一個座標陣列,折線、多邊形就是依靠這些座標陣列來成形的
strokeColor, // 折線顏色
strokeDashStyle, // 折線樣式
strokeWeight, // 折線寬度
editable, // 折線是否可編輯
clickable // 是否可點選
})
單個標註點
在mounted
生命週期或者從後臺介面獲得資訊後呼叫初始化地圖方法
initMap (latitude, longitude, message) {
var center = new qq.maps.LatLng(latitude, longitude);
var map = new qq.maps.Map(
document.getElementById("container"),
{
center: center,
zoom: 13
}
);
var marker = new qq.maps.Marker({
position: center,
map: map
});
var info = new qq.maps.InfoWindow({
map: map
});
// 懸浮標記顯示資訊
qq.maps.event.addListener(marker, 'mouseover', function() {
info.open();
info.setContent(`<div style="margin:10px;">${message}</div>`);
info.setPosition(center);
});
qq.maps.event.addListener(marker, 'mouseout', function() {
info.close();
});
},
多個標註點
markers: [ ]; // 標記點陣列
mounted () {
this.initMap(this.markers)
},
initMap (arr) {
// 預設以陣列第一項為中心
var center = new qq.maps.LatLng(arr[0].latitude, arr[0].longitude);
var map = new qq.maps.Map(
document.getElementById("container"),
{
center: center,
zoom: 13
}
);
// 提示窗
var info = new qq.maps.InfoWindow({
map: map
});
for (var i = 0; i < arr.length; i++) {
var data = arr[i];
var marker = new qq.maps.Marker({
position: new qq.maps.LatLng(data.latitude, data.longitude),
map: map
});
marker.id = data.id;
marker.name = data.name;
// 點選事件
qq.maps.event.addListener(marker, 'mouseover', function() {
info.open();
// 設定提示窗內容
info.setContent(`<div><p>${this.name}</p></div>`);
// 提示窗位置
info.setPosition(new qq.maps.LatLng(this.position.lat, this.position.lng));
});
qq.maps.event.addListener(marker, 'mouseout', function() {
info.close();
});
}
}
4.個性化地圖樣式
為什麼要用個性化地圖,提高不同場景下地圖的展現效果和使用者體驗。
為什麼選擇騰訊位置服務個性化地圖:
- 全平臺通用
- 開發成本極小
- 個性化樣式支援動態更新
- 支援全域性配置和分級配置
- 編輯平臺UI控制元件全面優化
- 每個元素可配置的屬性全部開放
- 能夠支援自定義的地圖元素擴充為52種
5.騰訊位置入門步驟
- 登入騰訊位置服務
- 驗證手機 與 郵箱
- 申請開發金鑰(
Key
) - 選擇您需要的產品
https://lbs.qq.com/webApi/component/componentGuide/componentMarker
位置展示元件
路線規劃元件
地圖選點元件
前端定位元件
三.微信小程式JavaScript SDK
- 我申請了開發者金鑰
key
- 開通
webserviceAPI
服務:控制檯 ->key
管理 -> 設定(使用該功能的key
)-> 勾選webserviceAPI
-> 儲存
(小程式SDK
需要用到webserviceAPI
的部分服務,所以使用該功能的KEY
需要具備相應的許可權)
日呼叫量:1萬次 / Key
----併發數:5次 / key / 秒
。
onLoad() {
console.log('頁面載入了')
// 例項化API核心類
qqmapsdk = new QQMapWX({
// key: '申請的key'
});
},
onShow() {
console.log('頁面顯示了')
// 呼叫介面dadaqianduan
qqmapsdk.search({
keyword: '酒店',
success: (res) => {
console.log(res);
},
fail: (err) => {
console.log(err);
},
complete: (cres) => {
console.log(cres);
}
})
},
我返回的資料如圖:QQMapWX
-- 小程式JavaScriptSDK
核心類 -- new QQMapWX(options:Object)
// 引入SDK核心類
var QQMapWX = require('xxx/qqmap-wx.js');
// 例項化API核心類
var demo = new QQMapWX({
key: '開發金鑰(key)' // 必填
});
地點搜尋:
// 地點搜尋
nearbySearchBtn() {
qqmapsdk.search({
keyword: 'kfc', //搜尋關鍵詞
location: '39.980014,116.313972', //設定周邊搜尋中心點
success: (res) => {
var mks = []
for (var i = 0; i < res.data.length; i++) {
mks.push({ // 獲取返回結果,放到mks陣列中
title: res.data[i].title,
id: res.data[i].id,
latitude: res.data[i].location.lat,
longitude: res.data[i].location.lng,
iconPath: "/location.png", //圖示路徑
width: 20,
height: 20
})
}
this.markers = mks
},
fail: (res) => {
console.log(res);
},
complete: (res) => {
console.log(res);
}
});
},
效果如圖:
<script>
// 引入SDK核心類,js檔案根據自己業務,位置可自行放置
// var QQMapWX = require('../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js');
import QQMapWX from '../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js';
var qqmapsdk;
export default {
components: {},
data() {
return {
backfill: '',
markers: [],
suggestion: [],
}
},
onLoad() {
console.log('頁面載入了') // 例項化API核心類
qqmapsdk = new QQMapWX({ // key: '申請的key'
key: '自己申請,我的就不放出來了'
});
},
onShow() {
console.log('頁面顯示了') // 呼叫介面dadaqianduan
qqmapsdk.search({
keyword: '酒店',
success: (res) => {
console.log(res);
},
fail: (err) => {
console.log(err);
},
complete: (cres) => {
console.log(cres);
}
})
},
onReady() {
console.log('頁面初次渲染完成了')
},
methods: {
getsuggest(e) {
console.log(e.detail.value)
qqmapsdk.getSuggestion({
keyword: e.detail.value, //使用者輸入的關鍵詞,可設定固定值,如keyword:'KFC'
//region:'北京', //設定城市名,限制關鍵詞所示的地域範圍,非必填引數
success: (res) => {//搜尋成功後的回撥
console.log(res);
var sug = [];
for (var i = 0; i < res.data.length; i++) {
sug.push({ // 獲取返回結果,放到sug陣列中
title: res.data[i].title,
id: res.data[i].id,
addr: res.data[i].address,
city: res.data[i].city,
district: res.data[i].district,
latitude: res.data[i].location.lat,
longitude: res.data[i].location.lng
});
}
this.suggestion = sug
},
fail: (error)=> {
console.error(error);
},
complete: (res)=> {
console.log(res);
}
});
},
backfillBtn(e) {
var id = e.currentTarget.id;
for (var i = 0; i < this.suggestion.length; i++) {
if (i == id) {
this.backfill = this.suggestion[i].title
}
}
},
// 地點搜尋
nearbySearchBtn() {
qqmapsdk.search({
keyword: 'kfc', //搜尋關鍵詞
location: '39.980014,116.313972', //設定周邊搜尋中心點
success: (res) => {
var mks = []
for (var i = 0; i < res.data.length; i++) {
mks.push({ // 獲取返回結果,放到mks陣列中
title: res.data[i].title,
id: res.data[i].id,
latitude: res.data[i].location.lat,
longitude: res.data[i].location.lng,
iconPath: "/static/location.png", //圖示路徑
width: 20,
height: 20
})
}
this.markers = mks
},
fail: (res) => {
console.log(res);
},
complete: (res) => {
console.log(res);
}
});
},
},
onHide() {
console.log('頁面隱藏了')
},
}
</script>
預覽效果如圖下:
<script>
import QQMapWX from '../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js';
var qqmapsdk;
export default {
components: {},
data() {
return {
backfill: '',
markers: [],
poi: {
latitude: 39.984060,
longitude: 16.307520
},
}
},
onLoad() {
console.log('頁面載入了') // 例項化API核心類
qqmapsdk = new QQMapWX({ // key: '申請的key'
key: ''
});
},
onShow() {
console.log('頁面顯示了')
},
onReady() {
console.log('頁面初次渲染完成了')
},
methods: {
formSubmit(e) {
qqmapsdk.reverseGeocoder({
location: e.detail.value.reverseGeo || '',
//獲取表單傳入的位置座標,不填預設當前位置,示例為string格式
//get_poi: 1, //是否返回周邊POI列表:1.返回;0不返回(預設),非必須引數
success: (res) => {
console.log(res);
var res = res.result;
var mks = [];
/**
* 當get_poi為1時,檢索當前位置或者location周邊poi資料並在地圖顯示,可根據需求是否使用
*
for (var i = 0; i < result.pois.length; i++) {
mks.push({ // 獲取返回結果,放到mks陣列中
title: result.pois[i].title,
id: result.pois[i].id,
latitude: result.pois[i].location.lat,
longitude: result.pois[i].location.lng,
iconPath: './resources/placeholder.png', //圖示路徑
width: 20,
height: 20
})
}
*
**/
//當get_poi為0時或者為不填預設值時,檢索目標位置,按需使用
mks.push({ // 獲取返回結果,放到mks陣列中
title: res.address,
id: 0,
latitude: res.location.lat,
longitude: res.location.lng,
iconPath: '/static/location.png', //圖示路徑
width: 20,
height: 20,
callout: { //在markers上展示地址名稱,根據需求是否需要
content: res.address,
color: '#000',
display: 'ALWAYS'
}
});
this.markers = mks;
// this.poi = {
// latitude: res.location.lat,
// longitude: res.location.lng
// }
},
fail: (error) => {
console.error(error);
},
complete: (res) => {
console.log(res);
}
})
}
},
onHide() {
console.log('頁面隱藏了')
},
}
</script>
geocoder
-- 提供由地址描述到所述位置座標的轉換,與逆地址解析reverseGeocoder()
的過程正好相反。
預覽效果如圖:
formSubmit(e) {
//呼叫地址解析介面
qqmapsdk.geocoder({
//獲取表單傳入地址 e.detail.value.geocoder
address: e.detail.value, //地址引數,例:固定地址,address: '北京市海淀區彩和坊路海淀西大街74號'
success: (res)=> {//成功後的回撥
console.log(res);
var res = res.result;
var latitude = res.location.lat;
var longitude = res.location.lng;
//根據地址解析在地圖上標記解析地址位置
this.markers = [{
id: 0,
title: res.title,
latitude: latitude,
longitude: longitude,
iconPath: '/static/location.png',//圖示路徑
width: 20,
height: 20,
callout: { //可根據需求是否展示經緯度
content: latitude + ',' + longitude,
color: '#000',
display: 'ALWAYS'
}
}],
this.poi= { //根據自己data資料設定相應的地圖中心座標變數名稱
latitude: Number(latitude),
longitude: Number(longitude),
}
},
fail: (error)=> {
console.error(error);
},
complete: (res)=> {
console.log(res);
}
})
}
預覽效果圖如下:
formSubmit(e){
//呼叫距離計算介面
console.log(this.start,'dadaqianduan')
qqmapsdk.calculateDistance({
//mode: 'driving',//可選值:'driving'(駕車)、'walking'(步行),不填預設:'walking',可不填
//from引數不填預設當前地址
//獲取表單提交的經緯度並設定from和to引數(示例為string格式)
// from: e.detail.value.start || '', //若起點有資料則採用起點座標,若為空預設當前地址
from: this.start || '',
to: this.end,
// to: e.detail.value.dest, //終點座標
success: (res)=> {//成功後的回撥
console.log(res);
var res = res.result;
var dis = [];
for (var i = 0; i < res.elements.length; i++) {
dis.push(res.elements[i].distance); //將返回資料存入dis陣列,
}
this.distance=dis
},
fail: (error)=> {
console.error(error);
},
complete: (res)=> {
console.log(res);
}
});
}
},
呼叫獲取城市列表介面,效果圖如下:
onShow() {
console.log('頁面顯示了')
//呼叫獲取城市列表介面
qqmapsdk.getCityList({
success: (res) => { //成功後的回撥
console.log(res);
console.log('省份資料:', res.result[0]); //列印省份資料
this.a = res.result[0]
console.log('城市資料:', res.result[1]); //列印城市資料
this.b = res.result[1]
console.log('區縣資料:', res.result[2]); //列印區縣資料
this.c = res.result[2]
},
fail: (error) => {
console.error(error);
},
complete: (res) => {
console.log(res);
}
});
},
獲取城市區縣,效果圖如下:
onShow() {
console.log('頁面顯示了')
//呼叫獲取城市列表介面
qqmapsdk.getCityList({
success: (res) => { //成功後的回撥
console.log(res);
console.log('省份資料:', res.result[0])
var city = res.result[0];
//根據對應介面getCityList返回資料的Id獲取區縣資料(以北京為例)
qqmapsdk.getDistrictByCityId({
// 傳入對應省份ID獲得城市資料,傳入城市ID獲得區縣資料,依次類推
id: city[0].id, //對應介面getCityList返回資料的Id,如:北京是'110000'
success: (res) => { //成功後的回撥
console.log(res);
console.log('對應城市ID下的區縣資料(以北京為例):', res.result[0]);
},
fail: (error) => {
console.error(error);
},
complete: (res) => {
console.log(res);
}
});
},
fail: (error) => {
console.error(error);
},
complete: (res) => {
console.log(res);
}
});
},
參考地址:https://lbs.qq.com/miniProgra...
騰訊位置服務為微信小程式提供了基礎的標點能力、線和圓的繪製介面等地圖元件和位置展示、地圖選點等地圖API
位置服務能力支援,使得開發者可以自由地實現自己的微信小程式產品。 在此基礎上,騰訊位置服務微信小程式JavaScript
SDK
是專為小程式開發者提供的LBS
資料服務工具包,可以在小程式中呼叫騰訊位置服務的POI
檢索、關鍵詞輸入提示、地址解析、逆地址解析、行政區劃和距離計算等資料服務,讓您的小程式更強大!
外掛市場:https://ext.dcloud.net.cn/plugin?id=3746可以多下載試試玩,後續更新外掛內容。
申請騰訊地圖開發者所用到的key,連結: https://lbs.qq.com?lbs_invite=VJJIFLV
專屬邀請碼: VJJIFLV
我是Jeskson(達達前端),感謝各位人才的:點贊、收藏和評論,我們下期見!
文章持續更新,本文 http://www.dadaqianduan.cn/#/ 已經收錄,歡迎Star。