快速上手
注意:本篇文章程式碼是基於 百度地圖 JavaScript API v3.0 的條件下編寫,GL版本可能稍有變化。
地圖嘛,很重要的一部分就是座標經緯度了:
經度: 英文 longitude 縮寫 lng;緯度:英文 latitude 縮寫 lat
基本使用
在使用百度地圖的API之前,首先要有一個先金鑰(ak)才能開始使用。沒有的話可以免費申請。
1.引入js(該ak是mapv中示例的ak,需要測試的朋友可以使用)
<script src="//api.map.baidu.com/api?v=3.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ"></script>
或者使用npm
$ npm install vue-baidu-map
import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap, {
ak: '你申請的key'
})
2.初始化地圖
<template>
<div class="map-box" style="height:100%">
<!-- 準備容器 -->
<div class="baidu-map" id="baiduMap"></div>
</div>
</template>
<script>
export default {
data() {
return {
// base64自定義座標圖形
bluePoint:
"data:image/png;base64,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"
}
},
methods: {
init() {
const map = new BMap.Map('baiduMap', {
// 地圖是否可點選
enableMapClick: false,
// 座標型別 3為gcj02座標,5為bd0ll座標,預設為5
// 如確認座標正確,但是點出不來,或者位置錯誤。則確認下型別
coordsType: 5
})
// 一個點物件,包含座標及名稱
const center = {
name: '溫州市人民政府',
lng: '120.705832',
lat: '28.00032'
}
// 初始化地理座標 存放地理座標的物件
const point = new BMap.Point(center.lng, center.lat)
// 初始化地圖 將點設定為地圖的中心點 設定初始縮放等級
map.centerAndZoom(point, 12)
// 其它地圖配置
map.enableScrollWheelZoom(true) // 開啟滑鼠滾輪縮放
map.enableDragging() // 拖拽
}
},
mounted() {
this.init()
}
}
</script>
如此就能看到一個百度地圖了,但是除了地圖啥都沒有。
新增點(標記)
在百度地圖中新增的點又叫覆蓋物,它可以新增很多的覆蓋物:
新增覆蓋物使用addOverlay()
方法,下面寫一個新增單個點的方法:
makePoint(map, data) {
// Point(lng: Number, lat: Number) 經度在前
const MAPPoniter = new BMap.Point(data.lng, data.lat)
// 建立影像標註例項 預設樣式是個紅點 可進行設定
// 這裡設定為data中的一base64藍色點圖片
const blueIcon = new BMap.Icon(this.bluePoint, new BMap.Size(32, 38))
const MAPMarker = new BMap.Marker(MAPPoniter, { icon: blueIcon })
// 設定標籤 內容 偏移量
const label = new BMap.Label(data.name, {
offset: new BMap.Size(-27, 32)
})
// 標籤樣式
label.setStyle({
border: 'none',
background: '#ACACAC',
fontSize: 20,
fontWeight: 'bold',
color: 'red'
})
// 設定標籤
MAPMarker.setLabel(label)
// 設定 hover 時顯示的點的名稱
MAPMarker.setTitle(data.name)
// 點選事件監聽
MAPMarker.addEventListener('click', function (e) {
console.log(e)
})
// 在地圖中新增覆蓋物
map.addOverlay(MAPMarker)
}
一般設定setLabel
和setTitle
二選一吧,要直接顯示出資訊的時候就用setLabel
。
在init()
中呼叫該方法:
init(){
...
this.makePoint(map, center)
}
新增控制元件
百度地圖中還可新增一些輔助的控制元件,比如比例尺,縮放控制元件等。
init(){
// ......省略之前程式碼
// 新增縮放控制元件
const navigation = new BMap.NavigationControl({
anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
type: BMAP_NAVIGATION_CONTROL_SMALL
})
map.addControl(navigation)
}
注:因為eslint可能會提示BMAP_ANCHOR_BOTTOM_RIGHT
需要使用字串,但這些大寫的常量配置不應使用字串,否則會不生效。
清除地圖左下角的圖示
使用css即可讓圖示消失,但注意樣式不要放在scoped
中:
<style lang="less" scoped>
.baidu-map {
width: 100%;
height: 100%;
}
</style>
<style>
.anchorBL a {
display: none;
}
.anchorBL img {
display: none;
}
.anchorBL span {
display: none !important;
}
</style>
處理大量點的方法
新增幾個點,幾十個點用上面的方法就完了。但是若是有上千上萬個點也這麼處理嗎?雖然我們可以直接一個for迴圈,但是,這樣做了的話就是新增點是時候瀏覽器會卡住一段時間。所以新增大量點的時候可以使用如下方法,各自有優缺點依情況選用吧。
這裡先定義下點的格式:
[
{
"name": "溫州張和堂醫藥連鎖有限公司興元店",
"lng": "120.763505",
"lat": "27.96839093"
},
{
"name": "溫州萬康大藥房有限公司",
"lng": "120.7530476",
"lat": "27.97953802"
}
]
點聚合
點聚合的效果就是,將密集的多個點聚合在一起顯示一個大點並標註數量,點選可以放大,詳細見後面效果圖。
在index.html
中引入,百度地圖相關的工具庫:
<script src="//api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
<script src="//api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
點聚合的方法實現:
makePolyPoints(map, data) {
const MAPMarkers = []
map.clearOverlays()
data.forEach(point => {
const MAPMarker = new BMap.Marker(new BMap.Point(point.lng, point.lat))
MAPMarker.setTitle(point.name)
MAPMarkers.push(MAPMarker)
// 可以在點物件上新增屬性,點選的監聽能獲取該屬性
MAPMarker.zbbm = 'xxxxx'
MAPMarker.addEventListener('click', function (e) {
console.log('座標編碼:', e.target.zbbm)
})
})
if (map.markerClusterer) {
map.markerClusterer.clearMarkers()
}
// 使用點聚合
map.markerClusterer = new BMapLib.MarkerClusterer(map, {
markers: MAPMarkers
})
}
在init()
呼叫即可使用,如需要要使用labe
和自定義圖示icon
,與新增單個點的類似。
海量點
海量點就是不把點聚合起來,而是全部顯示出來。但使用這種方法的缺點是不能自定義點的圖示,只能使用官方提供的預設圖形作為點的圖示。
使用海量點需要引入:
<script src="//api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
<script src="//api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
海量點方法實現:
makeCollectionPoints(map, data) {
map.clearOverlays()
// 判斷是否支援使用 canvas (海量點)
if (document.createElement('canvas').getContext) {
// 座標點資料陣列
var points = []
for (var point of data) {
points.push(new BMap.Point(point.lng, point.lat))
}
// 海量點的配置屬性
// 配置圖示:大小 形狀 顏色
const options = {
size: BMAP_POINT_SIZE_NORMAL,
shape: BMAP_POINT_SHAPE_STAR,
color: 'yellow'
}
// 初始化海量點
const pointCollection = new BMap.PointCollection(points, options)
pointCollection.addEventListener('click', function (e) {
console.log(e)
})
map.addOverlay(pointCollection)
} else {
alert('瀏覽器不支援,請使用chrome、safari、IE8+以上瀏覽器')
}
}
ShapeType預設圖形:
常量 | 描述 |
---|---|
BMAP_POINT_SHAPE_CIRCLE | 圓形,為預設形狀 |
BMAP_POINT_SHAPE_STAR | 星形 |
BMAP_POINT_SHAPE_SQUARE | 方形 |
BMAP_POINT_SHAPE_RHOMBUS | 星形 |
BMAP_POINT_SHAPE_STAR | 菱形 |
BMAP_POINT_SHAPE_WATERDROP | 水滴狀,該型別無size和color屬性 |
其它具體引數配置參考:百度地圖 javascript 3.0 api
使用mapv
mapv是百度地圖官方推出的地理資訊視覺化開源庫,藉助其也能進行大量座標點的新增操作。
它是使用canvas在地圖上新增了一層,能保證速度和自定義點圖示,首先匯入mapv的庫$npm install mapv
,或者:
<script src="//mapv.baidu.com/build/mapv.min.js"></script>
點的資料格式
[
{
geometry: {
type: 'Point',
coordinates: [123, 23]
},
fillStyle: 'red',
size: 30
},
{
geometry: {
type: 'Point',
coordinates: [121, 33]
},
fillStyle: 'rgba(255, 255, 50, 0.5)',
size: 90
}
]
配置項說明
{
zIndex: 1, // 層級
size: 5, // 大小值
fillStyle: 'rgba(200, 200, 50, 1)', // 填充顏色
strokeStyle: 'rgba(0, 0, 255, 1)', // 描邊顏色
lineWidth: 4, // 描邊寬度
globalAlpha: 1, // 透明度
globalCompositeOperation: 'lighter', // 顏色疊加方式
shadowColor: 'rgba(255, 255, 255, 1)', // 投影顏色
shadowBlur: 35, // 投影模糊級數
shadowOffsetX: 0,
shadowOffsetY: 0,
lineCap: 'butt',
lineJoin: 'miter',
miterLimit: 10
}
mapv新增大量點的方法:
makeMapvPoints(map, data) {
if (document.createElement('canvas').getContext) {
// 使用自定義座標點圖形
var img = new Image()
img.src = this.bluePoint
// 建立mapv配置項
const iconOpt = {
draw: 'icon',
width: 32,
height: 38,
methods: {
click: item => {
if (item) console.log(item)
}
}
}
// 在圖片載入後再建立圖層才能自定義圖示
img.onload = function () {
// 點座標的陣列
const dataSet = []
// 構建dataset格式資料
data.forEach(point => {
const geometry = {}
geometry.type = 'Point'
geometry.coordinates = [point.lng, point.lat]
dataSet.push({
geometry,
icon: img,
tag: { name: point.name }
})
})
const mapSet = new mapv.DataSet(dataSet)
// dataSet.set(data) // 修改資料
// 疊加圖層
const mapvLayer = new mapv.baiduMapLayer(map, mapSet, iconOpt)
// 顯示圖層
mapvLayer.show()
// mapvLayer.hide() // 隱藏圖層
}
} else {
alert('瀏覽器不支援,請使用chrome、safari、IE8+以上瀏覽器')
}
}
注意:
- 在使用自定義圖示
icon
時,必須設定width
和height
或者size
。否則座標點的點選事件無法觸發。 - 在使用點選事件回撥時,要判斷回撥的引數是否為
null
。因為該事件總能觸發(在有無座標點選都能觸發),無座標點點選返回null
,有則非空。