欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 利用Leaflet.js创建交互式地图:多种形状单个区域绘制

利用Leaflet.js创建交互式地图:多种形状单个区域绘制

2024/10/25 4:19:57 来源:https://blog.csdn.net/m0_54340021/article/details/141226038  浏览:    关键词:利用Leaflet.js创建交互式地图:多种形状单个区域绘制

引言

        在地图应用开发中,用户经常需要对特定区域进行标识和规划。本文将深入探讨如何利用Vue.js的响应式特性与Leaflet.js的地图功能,打造一个支持多边形、矩形、圆形等多种形状绘制的交互式地图编辑器。

功能亮点

  • 自由绘制多边形:用户可以自由地在地图上绘制多边形区域。
  • 规则形状快速绘制:支持矩形和圆形的快速绘制,适用于规则区域标识。
  • 灵活的区域编辑:提供区域删除和重新绘制功能,满足用户编辑需求。
  • 个性化样式定制:用户可以自定义每个区域的名称和颜色,使地图更加个性化。
  • 响应式文本标注:文本标注会根据地图缩放级别智能显示,提升用户体验。

实现步骤与代码示例

        这里提供的代码块仅展示了部分关键功能,以帮助读者理解整个实现过程,完整的代码和项目资源可以在个人中心-资源库获取

1. 模板代码

模板代码是构建地图绘制功能界面的基础,结合Vue的数据绑定和事件处理能力,可以创建一个交互性强、用户友好的地图编辑工具

<template><div class="mapContainer"><div id="mapRef" ref="mapRef" style="height: 400px;"></div><!-- 工具栏 --><div class="control" v-if="!enableMapClick"><div class="color"><div class="title">区域名称/颜色:</div><el-input v-model="polygonStyle.regionName" placeHolder="区域名称" style="width:150px"></el-input><el-color-picker v-model="polygonStyle.color"></el-color-picker></div><div class="shape" v-if="isDraw"><div class="shapeItem" v-for="(item,index) in shapeList" :key="index" :class="{'active':polygonStyle.shape == index + 1}" @click="polygonStyle.shape = index + 1"><img :src="polygonStyle.shape == index + 1 ? item.imgActive : item.img" alt=""><div class="title">{{ item.name }}</div></div></div><div class="startOrdelete" @click="startDrawItems" v-if="isDraw"><img src="@/assets/images/electronicChart/start.png" alt=""></div><div class="startOrdelete" @click="clearDrawnItems" v-else><img src="@/assets/images/electronicChart/delete.png" alt=""></div></div></div>
</template>

2. 地图初始化

在Vue组件的mounted生命周期钩子中初始化地图,并设置地图的初始视图和交互行为

// 初始化加载
initMap() {// 实例this.map = L.map("mapRef", {center: [21.582007, 111.824558], // 地图中心zoom: 15, // 缩放比列zoomControl: false, // 是否显示 + - 按钮doubleClickZoom: false, // 是否双击放大// scrollWheelZoom: false, // 是否可以通过滑轮缩放attributionControl: false, // 是否显示右下角leaflet标识});// 加载出地图this.name = L.tileLayer("http://webrd01.is.autonavi.com/....(省略地址)",{   maxZoom: 18,attribution: '© OpenStreetMap contributors',},).addTo(this.map);if (!this.drawnItems) {this.drawnItems = new L.FeatureGroup().addTo(this.map);}if(this.latitudeLongitude){this.renderRegion()this.isDraw = false}
},

3.多边形/矩形/圆形绘制实现

处理绘制事件,为新创建的图层设置样式,并添加到地图上。

        3.1 多边形绘制

        3.2 矩形绘制

        3.3 圆形绘制

    // 开启绘制区域图层startDrawItems(){if(this.polygonStyle.regionName && this.polygonStyle.color && this.polygonStyle.shape){if (!this.drawnItems) {var drawnItems = new L.FeatureGroup();this.drawnItems = drawnItems;this.map.addLayer(this.drawnItems);}this.drawControl = new L.Control.Draw({draw: { circlemarker: false },edit: {featureGroup: this.drawnItems,},});this.drawnItems.clearLayers();if(this.polygonStyle.shape == 1){// 多边形绘制开启this.polygon = new L.Draw.Polygon(this.map,this.drawControl.options.polygon).enable();}else if(this.polygonStyle.shape == 2){// 矩形绘制开启this.Rectangle = new L.Draw.Rectangle(this.map,this.drawControl.options.rectangle).enable();}else if(this.polygonStyle.shape == 3){// 圆形绘制开启this.circle = new L.Draw.Circle(this.map,this.drawControl.options.circle).enable();}this.map.on(L.Draw.Event.CREATED, (event) => {console.log(event, "绘制事件");var type = event.layerType;var layer = event.layer;// 设置填充颜色layer.setStyle({ color: this.polygonStyle.color,fillColor: this.polygonStyle.color }); // 添加文字标注this.createTextDivIcon(layer);// 添加到地图上this.drawnItems.addLayer(layer);console.log(layer._latlngs, "点位数据");if (type === "polygon") {// 多边形this.polygonStyle.latitudeLongitude = this.convertPolygonsData(layer._latlngs)} else if (type === "rectangle") {// 矩形this.polygonStyle.latitudeLongitude = this.convertPolygonsData(layer._latlngs)} else if (type === "circle") {// 圆形this.polygonStyle.radius = layer._mRadius;this.polygonStyle.latitudeLongitude = layer._latlng.lat + ',' + layer._latlng.lng;}this.isDraw = falsethis.$emit('draw-clicked', this.polygonStyle); // 触发事件,传递绘制区域数据})}else{this.$message({message: "请选择区域名称、颜色、形状",type: "warning",});}},// 创建一个文字标记,将文字图标放置在多边形的中心点createTextDivIcon(layer){let center;if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {center = layer.getBounds().getCenter();} else if (layer instanceof L.Circle) {center = layer.getLatLng();}const textIcon = L.divIcon({html: `<div class="berth-no-label">${this.polygonStyle.regionName}</div>`,className: 'my-div-icon',iconSize: [40, 14],iconAnchor: [14, 9.5],});const marker = L.marker(center, { icon: textIcon });marker.on('click', e => { console.log('标记点击');});this.drawnItems.addLayer(marker); // 将标记添加到绘制的图层组},

4.区域编辑与删除

提供方法以清除地图上的绘制区域,允许用户进行重新绘制或编辑。

// 清除绘制区域图层
clearDrawnItems() {// 清空图层组中的所有图层if (this.drawnItems) {this.drawnItems.clearLayers();}this.drawnItems = null; // 重置drawnItemsthis.isDraw = true
},
// 开启绘制区域图层
startDrawItems(){......
},

5.样式自定义修改

允许用户通过界面元素设置区域的名称和颜色,这些设置将实时反映在地图上。

6. 响应式文本标注

根据地图的缩放级别动态调整文本标注的显示,优化视觉效果。

// 当缩放结束时触发(实现多边形上的文字随地图缩放而变化大小)
handleZoomChange(e) {const zoomLevel = e.target._zoom;const minZoomToShowText = 15; // 定义最小缩放级别以显示文本// 获取所有文本标记this.map.eachLayer((layer) => {if (layer instanceof L.Marker) {const icon = layer.options.icon;if (icon.options.className === "my-div-icon") {// 根据缩放级别调整文字大小或隐藏if (zoomLevel < minZoomToShowText) {// 缩小到一定程度,隐藏文本layer.setOpacity(0);} else {// 其他情况,显示文本并可能调整大小layer.setOpacity(1);// 这里可以添加更多逻辑来调整文字大小}}}});
}, 

结语

本文详细介绍了如何使用Vue.js和Leaflet.js开发一个功能全面的地图编辑器,支持多种形状的绘制和编辑。通过实践这些步骤,开发者可以为用户提供一个强大且灵活的地图绘制工具,满足各种地理信息规划和展示的需求。希望本文能为有志于地图应用开发的你提供帮助和启发。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com