功能概述
在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应用
通过这种实现方式,可以直观地看到所选要素及其关联数据,大大提升地图交互体验。