前面讲了,向地图中添加 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 里面的源码可能有点乱,能够根据功能来找对应的代码。后面会陆续整理完善。