Leaflet地图交互:实现图形与点的同时高亮效果
功能概述
在WebGIS应用中,高亮显示用户点击的地图要素是一项基础但重要的交互功能。本文将介绍如何使用Leaflet地图库实现同时高亮显示图形要素和相关点数据的功能。
核心代码解析
1. 高亮功能实现
const highlightBoth = async (feature, points) => {const mapInstance = await map.value?.leafletObject;if (!mapInstance) return;// 清除之前的高亮clearHighlights();// 创建图层组存放所有高亮要素const highlightGroup = L.featureGroup();// 高亮图形要素if (feature) {if (!mapInstance.editTools) {mapInstance.editTools = new L.Editable(mapInstance);}if (feature.geometry.type === 'Polygon') {const polygon = mapInstance.editTools.createPolygon(feature.geometry.coordinates[0].map(coord => [coord[1], coord[0]]),{ fillColor: '#00ffff',color: '#00ffff',fillOpacity: 0.2,weight: 5});highlightGroup.addLayer(polygon);} else {const featureLayer = L.geoJSON(feature, {style: {color: '#00ffff',weight: 5,opacity: 1,fillColor: '#00ffff',fillOpacity: 0.2}});highlightGroup.addLayer(featureLayer);}highlightState.value.feature = feature.geometry;}// 高亮点要素if (points?.length > 0) {points.forEach(point => {const coords = point.geometry.coordinates;const direction = point.properties.direction || 0;const icon = L.icon({iconUrl: flightIcon,iconSize: [20, 20],iconAnchor: [10, 10],iconRotate: direction});const marker = L.marker([coords[1], coords[0]], {icon,rotationAngle: direction,zIndexOffset: 1000});highlightGroup.addLayer(marker);});highlightState.value.points = points;}// 添加到地图highlightState.value.layers = highlightGroup;mapInstance.addLayer(highlightGroup);
};
2. 地图点击事件处理
const handleMapClick = async (event) => {if (isEditing.value) return;const mapInstance = await map.value?.leafletObject;if (!mapInstance) return;const { latlng } = event;try {// 获取地图数据const response = await getMapData({x: latlng.lng,y: latlng.lat,activeTab: props.activeTab});// 计算距离并排序const targetPoint = turf.point([latlng.lng, latlng.lat]);const features = response.features;const sortedFeatures = features.map(feature => {const centroid = turf.centroid(feature);const distance = turf.distance(targetPoint, centroid, { units: 'meters' });return { feature, distance };}).sort((a, b) => a.distance - b.distance);// 高亮最近的要素if (sortedFeatures?.length > 0) {props.refreshTaskList([sortedFeatures[0]]);let highlightPoints = [];if (props.activeTab === 'house') {const uuid = sortedFeatures[0].feature.properties.uuid;const pointsResponse = await getFeaturesByUuid(uuid);highlightPoints = pointsResponse?.features || [];}// 同时高亮图形和点highlightBoth(sortedFeatures[0].feature, highlightPoints);}} catch (error) {console.error('地图点击处理错误:', error);}
};
技术要点
- 图层管理:使用
L.featureGroup()
管理所有高亮要素,便于统一操作 - 要素高亮:
- 面要素使用半透明青色填充
- 线要素使用粗体青色线条
- 点要素高亮:
- 使用自定义图标
- 支持方向旋转
- 通过zIndexOffset确保显示在最上层
- 性能优化:
- 点击前清除之前的高亮
- 使用Turf.js计算要素距离并排序
应用场景
这种高亮交互适用于:
- 房产地图中高亮选中的房屋和周边设施
- 物流系统中高亮配送区域和配送点
- 任何需要同时展示区域和点数据的GIS应用
通过这种实现方式,可以直观地看到所选要素及其关联数据,大大提升地图交互体验。