騰訊位置服務開發應用-使用教程,案例分享,知識總結 前言 一、騰訊位置服務是什麼? 二、使用步驟 三.微信小程序JavaScript SDK

把你的前端拿捏得死死的,每天學習得爽爽的,達達前端程序員,搜索【程序員哆啦A夢】關注這個不一樣的程序員。

前言

作爲一名在職崗位爲【前端開發工程師】的程序員,我開發的應用程序經常需要獲取用戶位置信息,需要再某些場合下使用展示地圖以及地圖商的某些地點,需要獲取行政區劃列表(省市區)以及地址詳情信息,需要在地圖上規劃一條(動態)路線,軌跡回放,小車移動,需要創建信息窗口,用於地點的摘要性信息的展示。

公司內做的是共享項目, 場景是這樣的,一種常見共享充電寶(功能差不多和流行的共享單車一樣),在做小程序首頁時,需要做到的是掃碼充電,聯繫客服(問題反饋),獲取地理位置,開篇即是一副地理位置,在你附近獲取到區域內店鋪信息,點擊該店的logo標誌可以獲取該店的地理位置,營業時間,店名,距離,是否當前該店裏是否有可借的充電寶等信息。

共享充電電動車🚗,首頁也是一副地理位置地圖,可以獲取你附近最近的共享電動車,獲取車的地址,狀態等信息。顯示該車的剩餘電量,使用記錄,租借訂單,獲取行程軌跡,某時間段內的里程,動態顯示軌跡等。

涉及到的共享其實內容很多(如除了電動車,充電寶,還可租借設備等),但大都功能幾乎相同,需要交押金,租借費用,信用免押金等。開發過app,H5,web網站,小程序項目都與地圖相關的位置服務息息相關,讓我說說與位置服務有關的故事。

下面主要還是講解其中的關於地圖功能等功能,使用的也是騰訊位置開發服務。會一步一步說明,做一些案例展示,代碼說明,使用教程。(注意這裏我回去看開發教程,儘量把每個功能都熟悉地說明一下使用方法

一、騰訊位置服務是什麼?

騰訊位置服務無疑是獲取位置服務等信息內容,該產品亮點:

  1. 定位:爲合作伙伴和廣大開發者提供完善的位置解決方案,已爲社交、出行、遊戲、商業、O2O、物流等領域提供專業精準的定位服務
  2. 地圖:騰訊位置服務在多平臺爲開發者提供了豐富的地圖展現形式,幫助從屬於不同領域的開發人員輕鬆完成構建地圖並在其基礎上打造專屬內容的工作。同時配合海量數據、個性化定製、可視化等能力滿足各個行業場景下對地圖的需求
  3. 地點搜索:基於海量鮮活地點(POI)數據,提供周邊搜索,城市範圍搜索,關鍵詞輸入提示、分類篩選等多種搜索能力,面向社交、物流、出行等行業打造專屬搜索策略,體驗更勝一籌
  4. 路線規劃:根據出發地、目的地以及路線策略設置,結合精準的實時交通路況提供駕車、步行、騎行、公交路線規劃能力,助力開發者爲用戶提供貼心、人性化的出行體驗
  5. 微信小程序解決方案:騰訊位置服務全面擁抱小程序生態,從服務API、基礎地圖組件、插件、行業方案等多個層面服務不同場景需求的小程序開發者,助力小程序插上地圖的“翅膀”!
  6. 個性化地圖:個性化樣式:千行千面,助力開發者根據自身產品的使用場景、界面色調, 選取或者創建風格匹配的地圖樣式,體驗更勝一籌;個性化圖層:真實酷炫,助力開發者將精美繪圖生成地圖瓦片並置於地圖之上,讓旅遊景點、大學高校等區域的展示效果與衆不同

二、使用步驟

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,表示爲多邊形)

點擊屬性

  1. @markertap-表示點擊標記點時觸發,e.detail={markerId}
  2. @labeltap-表示點擊label時觸發,e.detail = {markerId}
  3. @callouttap-表示點擊標記點對應的氣泡時觸發,e.detail = {markerId}
  4. @controltap-表示點擊控件時觸發,e.detail = {controlId}
  5. @regionchange-表示視野發生變化時觸發
  6. @tap-表示點擊地圖時觸發; App-nuve、微信小程序2.9支持返回經緯度
  7. @updated-表示在地圖渲染更新完成時觸發

我們在寫map組件時,組件的寬/高推薦寫直接量,比如說是 750rpx,不要設置百分比值,在uni-app中只支持gcj02座標。

介紹markers屬性-類型爲數組Array

由之前描述可知,markers屬性類型爲Array,表示標記點用於在地圖上顯示標記的位置。這個數組屬性,它裏面有它的對象配置屬性,分別是:

  1. id,表示 標記點id,類型爲Number,必填項,marker點擊事件回調會返回此id,建議爲每個marker設置上Number類型id,保證更新marker時有更好的性能。
  2. latitude,緯度,類型Number,必填項,浮點數,範圍 -90 ~ 90
  3. longitude,經度,類型Number,必填項,浮點數,範圍 -180 ~ 180
  4. title,標註點名,類型String,不是必填,點擊時顯示,callout存在時將被忽略
  5. iconPath,顯示的圖標,類型String,必填項,項目目錄下的圖片路徑
  6. rotate,旋轉角度,類型Number,不是必填,順時針旋轉的角度,範圍 0 ~ 360,默認爲 0
  7. alpha,標註的透明度,類型Number,不是必填,默認1,無透明,範圍 0 ~ 1
  8. width,標註圖標寬度,類型Number,不是必填,默認爲圖片實際寬度
  9. height,標註圖標高度,類型Number,不是必填,默認爲圖片實際高度
  10. callout,自定義標記點上方的氣泡窗口,類型Object,不是必填 - 可識別換行符
  11. label,爲標記點旁邊增加標籤,類型Object,不是必填 - 可識別換行符
  12. anchor,經緯度在標註圖標的錨點,默認底邊中點,不是必填,{x, y},x表示橫向(0-1),y表示豎向(0-1)。{x: .5, y: 1} 表示底邊中點

marker 上的氣泡 callout(Object類型)

marker數組 上屬性 callout 對象使用屬性:

  1. content,文本,String
  2. color,文本顏色,String
  3. fontSize,文字大小,Number
  4. borderRadiuscallout邊框圓角,Number
  5. bgColor,背景色,String
  6. padding,文本邊緣留白,Number
  7. display'BYCLICK':點擊顯示; 'ALWAYS':常顯String
  8. textAlign,文本對齊方式。有效值: left, right, centerString

marker 上的標籤 label(Object類型)

  1. content,文本,String
  2. color,文本顏色,String
  3. fontSize,文字大小,Number
  4. x,label的座標,原點是 marker 對應的經緯度,Number
  5. y,label的座標,原點是 marker 對應的經緯度,Number
  6. borderWidth,邊框寬度,Number
  7. borderColor,邊框顏色,String
  8. borderRadius,邊框圓角,Number
  9. bgColor,背景色,String
  10. padding,文本邊緣留白,Number
  11. textAlign,文本對齊方式。有效值: left, right, center,String

polyline

polyline表示指定一系列座標點,從數組第一項連線至最後一項

  1. points,經緯度數組,類型爲Array,必填,如:[{latitude: 0, longitude: 0}]
  2. color,線的顏色,類型爲String,不必填,如:#0000AA
  3. width,線的寬度,類型爲Number,不必填
  4. dottedLine,是否虛線,類型爲Boolean,不必填,默認值false
  5. arrowLine,帶箭頭的線,類型爲Boolean,不必填,默認值爲false
  6. arrowIconPath,更換箭頭圖標,類型爲String,不必填,在arrowLinetrue時,默認帶箭頭的線時生效
  7. borderColor,線的邊框顏色,類型爲String,不必填
  8. borderWidth,線的厚度,類型爲Number,不必填

polygon

polygon指定一系列座標點,根據points座標數據生成閉合多邊形

  1. points,經緯度數組,array,必填,如:[{latitude: 0, longitude: 0}]
  2. strokeWidth,描邊的寬度,Number,否
  3. strokeColor 描邊的顏色,String,否
  4. fillColor,填充顏色,String,否
  5. zIndex,設置多邊形 Z 軸數值,Number,否

circles

circles在地圖上顯示圓

  1. latitude,緯度,Number,必填,浮點數,範圍 -90 ~ 90
  2. longitude,經度,Number,必填,浮點數,範圍-180 ~ 180
  3. color,描邊的顏色,String,不必填,如:#0000AA
  4. fillColor,填充顏色,String,不必填,如:#0000AA
  5. radius,半徑,Number,必填
  6. strokeWidth,描邊的寬度,Number,不必填

controls

controls在地圖上顯示控件,控件不隨着地圖移動

  1. id,控件idNumber,不必填,在控件點擊事件回調會返回此id
  2. position,控件在地圖的位置,Object,必填,控件相對地圖位置
  3. iconPath,顯示的圖標,String,必填,項目目錄下的圖片路徑,支持相對路徑寫法,以'/'開頭則表示相對項目根目錄;也支持臨時路徑
  4. clickable,是否可點擊,Boolean,不必填,默認不可點擊

position

  1. left,距離地圖的左邊界多遠,Number,不必填,默認爲0
  2. top,距離地圖的上邊界多遠,Number,不必填,默認爲0
  3. width,控件寬度,Number,不必填,默認爲圖片寬度
  4. 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參數說明

  1. typeString,不必填,默認爲 wgs84 返回 gps 座標,gcj02 返回國測局座標,可用於 uni.openLocation 的座標,app平臺高德SDK僅支持返回gcj02
  2. altitudeBoolean,不必填,傳入 true 會返回高度信息,由於獲取高度需要較高精確度,會減慢接口返回速度
  3. geocodeBoolean,不必填,默認false,是否解析地址信息
  4. successFunction,必填,接口調用成功的回調函數,返回內容詳見返回參數說明
  5. failFunction,不必填,接口調用失敗的回調函數
  6. completeFunction,不必填,接口調用結束的回調函數(調用成功、失敗都會執行)

對於success返回參數說明:

  1. latitude,緯度,浮點數,範圍爲-90~90,負數表示南緯
  2. longitude,經度,浮點數,範圍爲-180~180,負數表示西經
  3. speed,速度,浮點數,單位m/s
  4. accuracy,位置的精確度
  5. altitude,高度,單位 m
  6. verticalAccuracy,垂直精度,單位 mAndroid 無法獲取,返回 0
  7. horizontalAccuracy,水平精度,單位 m
  8. address,地址信息(僅App端支持,需配置geocodetrue

address 地址信息說明

  1. countryString,國家 如“中國”,沒有則返回undefined
  2. provinceString,省份名稱 如“北京市”,沒有則返回undefined
  3. cityString,城市名稱,如“北京市”,沒有則返回undefined
  4. districtString,區,縣名稱 如“朝陽區”,沒有則返回undefined
  5. streetString,街道信息,如“酒仙橋路”,沒有則返回undefined
  6. streetNumString,獲取街道門牌號信息,如“3號”,沒有則返回undefined
  7. poiNameString POI信息,如“電子城.國際電子總部”,沒有則返回undefined
  8. postalCodeString,郵政編碼,如“100016”,沒有則返回undefined
  9. cityCodeString,城市代碼,如“010”,沒有則返回undefined

uni.chooseLocation(OBJECT)打開地圖選擇位置。

  1. latitudeString,不必填,目標地緯度
  2. longitudeString,不必填,目標地經度
  3. keywordString,不必填,搜索關鍵字,僅App平臺支持
  4. successFunction,必填
  5. failFunction,不必填
  6. completeFunction,不必填

success返回參數說明:

  1. name,位置名稱
  2. address,詳細地址
  3. latitude,緯度,浮點數,範圍爲-90~90,負數表示南緯,使用 gcj02 國測局座標系。
  4. 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> 組件。

該對象得方法列表:

  1. getCenterLocation OBJECT 獲取當前地圖中心的經緯度,返回的是 gcj02 座標系,可以用於 uni.openLocation
  2. moveToLocation OBJECT 將地圖中心移動到當前定位點,需要配合map組件的show-location使用
  3. translateMarker OBJECT 平移marker,帶動畫
  4. includePoints OBJECT 縮放視野展示所有經緯度
  5. getRegion OBJECT 獲取當前地圖的視野範圍
  6. getScale OBJECT 獲取當前地圖的縮放級別
  7. $getAppMap 獲取原生地圖對象 plus.maps.Map

getCenterLocationOBJECT 參數列表

success Function 不必填,接口調用成功的回調函數 ,res = { longitude: "經度", latitude: "緯度"}

moveToLocationOBJECT 參數列表 - 可不必填

translateMarkerOBJECT 參數列表

  1. markerId Number 必填 指定 marker
  2. destination Object 必填 指定 marker 移動到的目標點
  3. autoRotate Boolean 不必填 移動過程中是否自動旋轉 marker
  4. rotate Number 不必填 marker 的旋轉角度
  5. duration Number 不必填 動畫持續時長,默認值1000ms,平移與旋轉分別計算
  6. animationEnd Function 不必填 動畫結束回調函數
  7. 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,速度快,有基本信息

首頁點擊可以進行註冊,申請一個獲取keyhttps://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.個性化地圖樣式

爲什麼要用個性化地圖,提高不同場景下地圖的展現效果和用戶體驗。



爲什麼選擇騰訊位置服務個性化地圖:

  1. 全平臺通用
  2. 開發成本極小
  3. 個性化樣式支持動態更新
  4. 支持全局配置和分級配置
  5. 編輯平臺UI控件全面優化
  6. 每個元素可配置的屬性全部開放
  7. 能夠支持自定義的地圖元素擴充爲52種

5.騰訊位置入門步驟

  1. 登錄騰訊位置服務
  2. 驗證手機 與 郵箱
  3. 申請開發密鑰(Key
  4. 選擇您需要的產品

https://lbs.qq.com/webApi/component/componentGuide/componentMarker

位置展示組件



路線規劃組件




地圖選點組件



前端定位組件

三.微信小程序JavaScript SDK

  1. 我申請了開發者密鑰key
  2. 開通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/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview

騰訊位置服務爲微信小程序提供了基礎的標點能力、線和圓的繪製接口等地圖組件和位置展示、地圖選點等地圖API位置服務能力支持,使得開發者可以自由地實現自己的微信小程序產品。 在此基礎上,騰訊位置服務微信小程序JavaScript SDK是專爲小程序開發者提供的LBS數據服務工具包,可以在小程序中調用騰訊位置服務的POI檢索、關鍵詞輸入提示、地址解析、逆地址解析、行政區劃和距離計算等數據服務,讓您的小程序更強大!

插件市場:https://ext.dcloud.net.cn/plugin?id=3746可以多下載試試玩,後續更新插件內容。


申請騰訊地圖開發者所用到的key,鏈接: https://lbs.qq.com?lbs_invite=VJJIFLV

專屬邀請碼: VJJIFLV

我是Jeskson(達達前端),感謝各位人才的:點贊、收藏和評論,我們下期見!

文章持續更新,可以搜一搜「 程序員哆啦A夢 」第一時間閱讀,回覆【資料】有我準備的一線大廠資料,本文 http://www.dadaqianduan.cn/#/ 已經收錄,歡迎Star。

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