Browse Source

添加河池市采样点,采样点也可以通过区域选择器过滤

yangtaodemon 1 month ago
parent
commit
d6d9f28730
1 changed files with 157 additions and 53 deletions
  1. 157 53
      src/views/menu/tencentMapView.vue

+ 157 - 53
src/views/menu/tencentMapView.vue

@@ -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);