前面講了,向地圖中添加 marker, polyline, polygon的圖形要素。這些功能都是屬於比較基礎的功能,一般會應用到查詢結果或分析結果的展現場景。除此以外,這些基礎圖形的繪製也是其餘高級別功能的基礎,例如框選、量測等功能。這章內容就主要講在地圖上實現圖像繪製與量測功能。vue
點,線,面的繪製的關鍵在於根據用戶在的操做上的操做去獲取正確的座標,並將這些座標組織爲不一樣要素類型數據。三種類型的要素的繪製中相同的地方在於都必須監測到用戶在地圖上所作到操做,不一樣在於對用戶操做結果的響應。git
而監測用戶對於地圖的操做就是監聽 map
對象的 click
, dbclick
, mouseover
等事件。下面會分要素作功能分析。下面講的繪製的功能邏輯爲是左鍵單擊進行繪製,雙擊結束繪製。github
點要素的繪製很是簡單,只須要監聽 map
對象的左鍵單擊事件,而後添加點要素就能夠了。完整的流程以下圖所示。bash
全部的代碼都是在第一章的項目結構中添加或者修改的less
// src\components\MapDraw.vue
<template>
<div class="map-tools">
<ul>
<li :class="[{active: activeTool == 'point'}]" @click="point">Point</li>
<li @click="$emit('polyline')">Polyline</li>
<li @click="$emit('polygon')">Polygon</li>
</ul>
</div>
</template>
<script>
export default {
name: "mapDraw",
data() {
return {
activeTool: ""
};
},
methods: {
point() {
if (this.activeTool !== "point") {
this.activeTool = "point";
this.$emit("point");
} else {
this.activeTool = "";
this.$emit("end");
}
}
}
};
</script>
<style lang="less">
.map-tools {
position: absolute;
right: 15px;
top: 15px;
z-index: 999;
height: 36px;
box-shadow: 0px 0px 50px 2px rgba(0, 0, 0, 0.35);
background-color: #fff;
ul {
display: flex;
padding: 0;
margin: 0;
list-style: none;
li {
padding: 0 15px;
height: 36px;
font-size: 13px;
line-height: 36px;
cursor: pointer;
}
li.active {
background-color: rgb(102, 156, 255);
color: #fff;
}
li:hover {
background-color: rgb(212, 224, 246);
}
}
}
</style>
複製代碼
// src\views\Point.vue
<template>
<div class="map-container">
<div id="map-container"></div>
<MapDraw @point="drawPoint" @polyline="drawPolyline" @polygon="drawPolygon" @end="drawOff"></MapDraw>
</div>
</template>
<script>
import MapDraw from "@/components/MapDraw.vue";
export default {
name: "map-point",
components: { MapDraw },
data() {
return {
map: null,
OSMUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
};
},
mounted() {
this.map = this.$utils.map.createMap("map-container");
this.$utils.map.createTileLayer(this.map, this.OSMUrl, {});
this.map.setView([51.505, -0.09], 13);
},
methods: {
drawOn(fn) {
// 監聽地圖點擊事件
this.map.off("click");
this.map.on("click", evt => fn(evt));
},
drawOff() {
// 移除監聽地圖點擊事件
this.map.off("click");
},
drawPoint() {
this.drawOn(evt => {
this.$utils.map.createMakerByLatlng(evt.latlng).addTo(this.map);
});
},
drawPolyline() {},
drawPolygon() {}
}
};
</script>
<style lang="less">
.map-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
#map-container {
width: 100%;
height: 100%;
}
}
</style>
複製代碼
地圖開關組件和 Point 頁面的時間綁定請不詳細介紹了。工具
以上頁面爲繪製線、面的功能留出了接口,後面的文章會用到。若是順利的話你看的效果是以下:post
點繪製很簡單。不過有幾個細節須要注意。flex
接着咱們對上述問題依次進行處理。ui
在 Vue-CLI and Leaflet (3): 添加 marker, polyline, polygon 中提到修復默認圖標沒法加載顯示的問題,咱們在map.js 添加了代碼,添加上 iconAnchor
屬性。[ iconWidth / 2, iconHeight]this
// src\utils\map.js
......
// 解決默認 maker 沒法顯示的問題
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
let DefaultIcon = $L.icon({
iconAnchor: [13, 41],
iconUrl: icon,
shadowUrl: iconShadow
});
$L.Marker.prototype.options.icon = DefaultIcon;
......
複製代碼
在 map.js 添加修改樣式和還原鼠標樣式的代碼。
// src\utils\map.js
......
// 存儲鼠標樣式
let CursorStyle = "";
......
// 添加鼠標樣式
const addCursorStyle = (map, cursorStyle) => {
CursorStyle = cursorStyle;
$L.DomUtil.addClass(map._container, cursorStyle);
};
// 移除鼠標樣式
const removerCoursorStyle = map => {
$L.DomUtil.removeClass(map._container, CursorStyle);
};
......
複製代碼
除此以外還須要在全局樣式中添加上對應的樣式類,並正確調用上面的修改樣式的方法才能實現對應的效果。這裏我在 assets->style
下添加了一個 leaflet.less
,注意添加後要將其引用
// 添加點,鼠標的樣式
.leaflet-container.pointer-cursor {
cursor: pointer;
}
複製代碼
修改 Point.vue,在繪製開始時即監聽地圖點擊事件時修改鼠標樣式 // src\views\Point.vue
<template>
<div class="map-container">
<div id="map-container"></div>
<MapDraw @point="drawPoint" @polyline="drawPolyline" @polygon="drawPolygon" @end="drawOff"></MapDraw>
</div>
</template>
<script>
import MapDraw from "@/components/MapDraw.vue";
export default {
name: "map-point",
components: { MapDraw },
data() {
return {
map: null,
OSMUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
};
},
mounted() {
this.map = this.$utils.map.createMap("map-container");
this.$utils.map.createTileLayer(this.map, this.OSMUrl, {});
this.map.setView([51.505, -0.09], 13);
},
methods: {
drawOn(fn) {
// 監聽地圖點擊事件
this.map.off("click");
this.map.on("click", evt => fn(evt));
},
drawOff() {
// 移除監聽地圖點擊事件
this.map.off("click");
// 復原鼠標平移樣式
this.$utils.map.removerCoursorStyle(this.map);
},
drawPoint() {
this.$utils.map.addCursorStyle(this.map, "pointer-cursor");
this.drawOn(evt => {
this.$utils.map.createMakerByLatlng(evt.latlng).addTo(this.map);
});
},
drawPolyline() {},
drawPolygon() {}
}
};
</script>
<style lang="less">
.map-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
#map-container {
width: 100%;
height: 100%;
}
}
</style>
複製代碼
效果以下:
這裏,我結束繪製的功能放在,繪製開關的按鈕上的,再次點擊Point 按鈕,回覆移除地圖點擊事件,復原地圖鼠標樣式,復原 Point 按鈕樣式。這樣就有一個完成第繪製的功能了。
// src\views\Point.vue => method
drawOff() {
// 移除監聽地圖點擊事件
this.map.off("click");
// 復原鼠標平移樣式
this.$utils.map.removerCoursorStyle(this.map);
}
複製代碼
以上就是點繪製功能的介紹,原本想點線面一塊兒出的,可是怕文章太長了會很差閱讀。因此後面會陸續更新線繪製,面繪製等功能。若是有任何建議請各位留言。
(一) Vue-CLI and Leaflet:起步 - 在 Vue-CLI 中使用 Leaflet
(二) Vue-CLI and Leaflet:地圖基本操做(放大,縮小,平移,定位等)
(三) Vue-CLI and Leaflet: 添加 marker, polyline, polygon
(四) Vue-CLI and Leaflet: 添加 tooltips 和 popup
(七) Vue-CLI and Leaflet: 面 繪 制
(八) Vue-CLI and Leaflet :加載 Esri ArcGIS Map Service
(九) Vue-CLI and Leaflet: 圖層控制基本功能的實現
(十) Vue-CLI and Leaflet: AGS 屬性查詢與點圖查詢
(十一)Vue-CLI and Leaflet: 點聚合 Leaflet.markercluster
源碼請參看 個人GitHub,因爲文章是一邊coding,一邊寫的因此 Github 裏面的源碼可能有點亂,能夠根據功能來找對應的代碼。後面會陸續整理完善。