|
@@ -66,14 +66,18 @@ const state = reactive({
|
|
|
let soilTypeLayer = null
|
|
|
let geoJSONLayer;
|
|
|
let currentInfoWindow = null;
|
|
|
-let surveyDataLayer = ref(null);
|
|
|
+const surveyDataLayer = ref(null); // 保持响应式引用
|
|
|
+let currentLayerId = 0; // 添加图层版本控制[3,4](@ref)
|
|
|
let multiPolygon;
|
|
|
-const districtLayers = ref(new Map()) // 存储区县图层
|
|
|
+const districtLayers = ref(new Map()) // 存储区县图层
|
|
|
+const combinedSurveyFeatures = ref([]); // 存储原始数据
|
|
|
+const currentSurveyFilter = ref([]); // 当前选中区域
|
|
|
|
|
|
const categoryColors = { // 分类颜色配置
|
|
|
'优先保护类': '#00C853', // 绿色
|
|
|
'安全利用类': '#FFD600', // 黄色
|
|
|
- '严格管控类': '#D50000' // 红色
|
|
|
+ '严格管控类': '#D50000', // 红色
|
|
|
+ '其他': '#CCCCCC' // 灰色
|
|
|
};
|
|
|
|
|
|
const tMapConfig = reactive({
|
|
@@ -213,6 +217,7 @@ const initMap = async () => {
|
|
|
const geojsonData = await loadGeoJSON('/data/单元格.geojson');
|
|
|
initMapWithGeoJSON(geojsonData, map);
|
|
|
await initSurveyDataLayer(map);
|
|
|
+ filterSurveyDataLayer(currentSurveyFilter.value)
|
|
|
// 绑定点击事件
|
|
|
// map.on('click', handleMapClick)
|
|
|
// markersLayer.on('click', handleMarkerClick)
|
|
@@ -497,44 +502,122 @@ async function loadGeoJSON(url) {
|
|
|
|
|
|
const handleRegionChange = async (districtNames) => {
|
|
|
console.log('收到区域变更:', districtNames)
|
|
|
+ currentSurveyFilter.value = districtNames;
|
|
|
|
|
|
- // 删除已取消选择的图层
|
|
|
- Array.from(districtLayers.value.keys()).forEach(name => {
|
|
|
- if (!districtNames.includes(name)) {
|
|
|
- const layer = districtLayers.value.get(name)
|
|
|
- layer.setMap(null) // 正确销毁图层
|
|
|
- districtLayers.value.delete(name)
|
|
|
+
|
|
|
+ // // 删除已取消选择的图层
|
|
|
+ // Array.from(districtLayers.value.keys()).forEach(name => {
|
|
|
+ // if (!districtNames.includes(name)) {
|
|
|
+ // const layer = districtLayers.value.get(name)
|
|
|
+ // layer.setMap(null) // 正确销毁图层
|
|
|
+ // districtLayers.value.delete(name)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // // 添加新选择的图层
|
|
|
+ // await Promise.all(districtNames.map(async name => {
|
|
|
+ // if (!districtLayers.value.has(name)) {
|
|
|
+ // try {
|
|
|
+ // const geoData = await loadGeoJSON(`/data/${name}.geojson`)
|
|
|
+
|
|
|
+ // // 创建独立图层实例
|
|
|
+ // const layer = new TMap.value.vector.GeoJSONLayer({
|
|
|
+ // map: map, // 确保传入当前地图实例
|
|
|
+ // data: geoData,
|
|
|
+ // zIndex: 3,
|
|
|
+ // styles: {
|
|
|
+ // // 按腾讯地图规范定义样式
|
|
|
+ // polygonStyle: new TMap.value.PolygonStyle({
|
|
|
+ // color: randomRGBA(0.3),
|
|
|
+ // borderColor: '#FF0000',
|
|
|
+ // borderWidth: 2
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // districtLayers.value.set(name, layer)
|
|
|
+ // } catch (error) {
|
|
|
+ // console.error(`加载【${name}】边界失败:`, error)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }))
|
|
|
+ filterSurveyDataLayer(districtNames);
|
|
|
+}
|
|
|
+
|
|
|
+const filterSurveyDataLayer = (selectedRegions) => {
|
|
|
+ // ===== 1. 销毁旧图层 ===== [1,3](@ref)
|
|
|
+ if (surveyDataLayer.value) {
|
|
|
+ surveyDataLayer.value.setMap(null); // 从地图解除关联
|
|
|
+ surveyDataLayer.value.destroy(); // 释放内存资源
|
|
|
+ surveyDataLayer.value = null; // 清除引用
|
|
|
}
|
|
|
- })
|
|
|
|
|
|
- // 添加新选择的图层
|
|
|
- await Promise.all(districtNames.map(async name => {
|
|
|
- if (!districtLayers.value.has(name)) {
|
|
|
+ const mergedCategoryColors = {
|
|
|
+ ...categoryColors,
|
|
|
+ };
|
|
|
+
|
|
|
+ // 创建样式(包含默认分类)
|
|
|
+ const pointStyles = Object.keys(mergedCategoryColors).map(category => ({
|
|
|
+ id: category,
|
|
|
+ style: new TMap.value.MarkerStyle({
|
|
|
+ width: 12,
|
|
|
+ height: 12,
|
|
|
+ anchor: { x: 6, y: 6 },
|
|
|
+ src: createColoredCircle(mergedCategoryColors[category])
|
|
|
+ })
|
|
|
+ }));
|
|
|
+ const layerId = `survey-layer-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
|
+ surveyDataLayer.value = new TMap.value.MultiMarker({
|
|
|
+ id: layerId,
|
|
|
+ map: map,
|
|
|
+ styles: Object.assign({}, ...pointStyles.map(s => ({ [s.id]: s.style }))),
|
|
|
+ geometries: [] // 初始空数据
|
|
|
+ });
|
|
|
+ if (!surveyDataLayer?.value) {
|
|
|
+ throw new Error("调查数据图层未初始化")
|
|
|
+ }
|
|
|
+ if (!combinedSurveyFeatures?.value) {
|
|
|
+ throw new Error("调查数据未加载")
|
|
|
+ }
|
|
|
+ console.groupCollapsed("[区域过滤] 调试信息");
|
|
|
+ console.log("🔄 收到过滤请求,当前选中区域:", selectedRegions);
|
|
|
+ console.log("📦 原始数据总量:", combinedSurveyFeatures.value.length);
|
|
|
+
|
|
|
+ const filtered = selectedRegions.length === 0
|
|
|
+ ? combinedSurveyFeatures.value
|
|
|
+ : combinedSurveyFeatures.value.filter(feature => {
|
|
|
+ const xmc = feature.properties.XMC || '';
|
|
|
+ return selectedRegions.some(region => xmc.includes(region));
|
|
|
+ });
|
|
|
+ console.log("✅ 过滤后数据量:", filtered.length);
|
|
|
+ console.log("🔍 示例过滤后数据:", filtered.slice(0,3).map(f => ({
|
|
|
+ id: f.properties.ID,
|
|
|
+ XMC: f.properties.XMC,
|
|
|
+ CMC: f.properties.CMC
|
|
|
+ })));
|
|
|
+ console.groupEnd();
|
|
|
+
|
|
|
try {
|
|
|
- const geoData = await loadGeoJSON(`/data/${name}.geojson`)
|
|
|
+ surveyDataLayer.value.setGeometries(filtered.map(feature => ({
|
|
|
+ id: feature.properties.ID || feature.properties.OBJECTID,
|
|
|
+ styleId: feature.properties.H_XTFX || '其他',
|
|
|
+ position: new TMap.value.LatLng(
|
|
|
+ feature.geometry.coordinates[1],
|
|
|
+ feature.geometry.coordinates[0]
|
|
|
+ ),
|
|
|
+ properties: {
|
|
|
+ ...feature.properties,
|
|
|
+ H_XTFX: feature.properties.H_XTFX || '其他'
|
|
|
+ }
|
|
|
|
|
|
- // 创建独立图层实例
|
|
|
- const layer = new TMap.value.vector.GeoJSONLayer({
|
|
|
- map: map, // 确保传入当前地图实例
|
|
|
- data: geoData,
|
|
|
- zIndex: 3,
|
|
|
- styles: {
|
|
|
- // 按腾讯地图规范定义样式
|
|
|
- 'polygon': new TMap.value.PolygonStyle({
|
|
|
- color: randomRGBA(0.3),
|
|
|
- borderColor: '#FF0000',
|
|
|
- borderWidth: 2
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- districtLayers.value.set(name, layer)
|
|
|
- } catch (error) {
|
|
|
- console.error(`加载【${name}】边界失败:`, error)
|
|
|
- }
|
|
|
+ })));
|
|
|
+ console.log("🗺️ 图层更新成功");
|
|
|
+ } catch (e) {
|
|
|
+ console.error("[图层操作异常]", e);
|
|
|
+ error.value = `地图更新失败: ${e.message}`;
|
|
|
+ setTimeout(() => error.value = null, 5000);
|
|
|
}
|
|
|
- }))
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
// 生成随机颜色
|
|
|
const randomRGBA = (alpha = 1) => {
|
|
@@ -602,40 +685,55 @@ function initMapWithGeoJSON(geojsonData, map) {
|
|
|
// 加载调查数据并初始化图层
|
|
|
const initSurveyDataLayer = async (map) => {
|
|
|
try {
|
|
|
- // 加载GeoJSON数据
|
|
|
- const surveyData = await loadGeoJSON('/data/调查数据.geojson');
|
|
|
+ const geoJsonFiles = [
|
|
|
+ '/data/调查数据.geojson',
|
|
|
+ '/data/河池1.geojson',
|
|
|
+ '/data/河池2.geojson'
|
|
|
+ ];
|
|
|
+
|
|
|
+ const surveyDataArray = await Promise.all(geoJsonFiles.map(loadGeoJSON));
|
|
|
+ const features = surveyDataArray.flatMap(geoData => geoData.features);
|
|
|
|
|
|
- // 创建分类样式
|
|
|
- const pointStyles = Object.keys(categoryColors).map(category => ({
|
|
|
+ // 保存原始数据用于过滤
|
|
|
+ combinedSurveyFeatures.value = features;
|
|
|
+
|
|
|
+ // 合并颜色配置(添加默认分类)
|
|
|
+ const mergedCategoryColors = {
|
|
|
+ ...categoryColors,
|
|
|
+ };
|
|
|
+
|
|
|
+ // 创建样式(包含默认分类)
|
|
|
+ const pointStyles = Object.keys(mergedCategoryColors).map(category => ({
|
|
|
id: category,
|
|
|
style: new TMap.value.MarkerStyle({
|
|
|
width: 12,
|
|
|
height: 12,
|
|
|
anchor: { x: 6, y: 6 },
|
|
|
- src: createColoredCircle(categoryColors[category]) // 生成圆形图标
|
|
|
+ src: createColoredCircle(mergedCategoryColors[category])
|
|
|
})
|
|
|
}));
|
|
|
|
|
|
- // 初始化图层
|
|
|
- surveyDataLayer = new TMap.value.MultiMarker({
|
|
|
+ // 初始化图层(处理缺失属性)
|
|
|
+ surveyDataLayer.value = new TMap.value.MultiMarker({
|
|
|
map: map,
|
|
|
styles: Object.assign({}, ...pointStyles.map(s => ({ [s.id]: s.style }))),
|
|
|
- geometries: surveyData.features.map(feature => ({
|
|
|
- id: feature.properties.ID,
|
|
|
- styleId: feature.properties.H_XTFX,
|
|
|
+ geometries: combinedSurveyFeatures.value.map(feature => ({
|
|
|
+ id: feature.properties.ID || feature.properties.OBJECTID,
|
|
|
+ styleId: feature.properties.H_XTFX || '其他', // 设置默认值
|
|
|
position: new TMap.value.LatLng(
|
|
|
- feature.geometry.coordinates[1],
|
|
|
+ feature.geometry.coordinates[1],
|
|
|
feature.geometry.coordinates[0]
|
|
|
),
|
|
|
properties: {
|
|
|
...feature.properties,
|
|
|
-
|
|
|
+ // 强制添加H_XTFX字段保证数据一致性
|
|
|
+ H_XTFX: feature.properties.H_XTFX || '其他'
|
|
|
}
|
|
|
}))
|
|
|
});
|
|
|
|
|
|
// 添加点击事件
|
|
|
- surveyDataLayer.on('click', (event) => {
|
|
|
+ surveyDataLayer.value.on('click', (event) => {
|
|
|
const prop = event.geometry.properties;
|
|
|
if (currentInfoWindow) currentInfoWindow.close();
|
|
|
currentInfoWindow = new TMap.value.InfoWindow({
|
|
@@ -650,7 +748,12 @@ const initSurveyDataLayer = async (map) => {
|
|
|
});
|
|
|
});
|
|
|
} catch (error) {
|
|
|
- console.error('调查数据加载失败:', error);
|
|
|
+ console.error("调查数据加载失败:", error);
|
|
|
+ // 添加详细错误日志
|
|
|
+ console.groupCollapsed("[错误详情]");
|
|
|
+ console.error("错误对象:", error);
|
|
|
+ console.trace("调用堆栈");
|
|
|
+ console.groupEnd();
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -691,7 +794,7 @@ const createColoredCircle = (color) => {
|
|
|
return;
|
|
|
}
|
|
|
if (surveyDataLayer) {
|
|
|
- surveyDataLayer.setVisible(state.showSurveyData);
|
|
|
+ surveyDataLayer.value.setVisible(state.showSurveyData);
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -738,9 +841,9 @@ onBeforeUnmount(() => {
|
|
|
soilTypeLayer.destroy();
|
|
|
soilTypeLayer = null;
|
|
|
}
|
|
|
- if (surveyDataLayer) {
|
|
|
- surveyDataLayer.destroy();
|
|
|
- surveyDataLayer = null;
|
|
|
+ if (surveyDataLayer.value) {
|
|
|
+ surveyDataLayer.value.setMap(null);
|
|
|
+ surveyDataLayer.value.destroy();
|
|
|
}
|
|
|
})
|
|
|
</script>
|
|
@@ -994,6 +1097,7 @@ onBeforeUnmount(() => {
|
|
|
.point-info h3[data-category="优先保护类"] { --category-color: #00C853; }
|
|
|
.point-info h3[data-category="安全利用类"] { --category-color: #FFD600; }
|
|
|
.point-info h3[data-category="严格管控类"] { --category-color: #D50000; }
|
|
|
+.point-info h3[data-category="其他"] { --category-color: #CCCCCC; }
|
|
|
.highlight-status {
|
|
|
padding: 8px;
|
|
|
background: rgba(0, 255, 0, 0.1);
|