| 
					
				 | 
			
			
				@@ -19,54 +19,118 @@ import { boundingExtent, getCenter } from "ol/extent.js"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import RegionLayer from "./map/regionLayer"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import eventBus from "@/api/eventBus"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import albumCarousel from "./album_compoents/albumCarousel.vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// import MockFarmLayer from "./map/mockFarmLayer"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { onMounted, ref } from "vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { useStore } from "vuex"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { unByKey } from "ol/Observable"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let store = useStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 选中样式(高亮) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// const selectedStyle = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         src: require("@/assets/images/map/status/active-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         scale: 0.6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let kmap = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const store = useStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const areaRef = ref(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// let mockFarmLayer = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let dragBox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const currentTree = ref(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isDrawing = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const mapPoint = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let kmap = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let treeClusterLayer = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let dragBox = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let listenKey = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let regionLayer = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let clusterSource = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 样式缓存优化 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 样式缓存优化 - 确保所有样式都正确初始化 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const styleCache = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    default: new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            radius: 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fill: new Fill({ color: "#ffffff00" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stroke: new Stroke({ color: "#fff", width: 1 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    selected: new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            src: require("@/assets/images/map/status/active-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            scale: 0.6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            crossOrigin: 'anonymous' // 添加crossOrigin属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    current: new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            src: require("@/assets/images/map/status/current-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            scale: 0.8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            crossOrigin: 'anonymous' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    renYang1: new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            radius: 12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fill: new Fill({ color: "#EEEEEE" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stroke: new Stroke({ color: "#fff", width: 1 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    renYang2: new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            radius: 12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fill: new Fill({ color: "#F0AC37" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stroke: new Stroke({ color: "#fff", width: 1 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clusterText: (size, isRenyang) => new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        text: new Text({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            text: size.toString(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            font: "bold 10px sans-serif", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fill: new Fill({ color: isRenyang === 1 ? "#000" : "#fff" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        zIndex: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    photoStyle: (src) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                image: new Photo({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    src: src, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    kind: "circle", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    radius: 22, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    shadow: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    crop: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    displacement: [0, 0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    stroke: new Stroke({ width: 2, color: "#fff" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                zIndex: 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.warn('Failed to create photo style:', e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    radius: 12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    fill: new Fill({ color: "#F0AC37" }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    stroke: new Stroke({ color: "#fff", width: 1 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const currentTree = ref(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 初始化地图 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const level = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const coordinate = util.wktCastGeom(store.getters.userinfo.location).getFirstCoordinate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    kmap = new KMap.Map(areaRef.value, level, coordinate[0], coordinate[1], null, 1, 22, "img", true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    regionLayer = new RegionLayer(kmap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const isDrawing = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 启用框选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const enableBoxSelect = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const data = mapPoint.value.filter((item) => !item.isRenyang); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    addCluster(data, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const data = mapPoint.value.filter(item => !item.isRenyang); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    updateClusterData(data, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isDrawing.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     dragBox = new DragBox({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        condition: platformModifierKeyOnly, // 按住 Ctrl 才可框选(可去掉) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        condition: platformModifierKeyOnly, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 添加键盘事件监听 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     window.addEventListener("keydown", handleKeyDown); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     window.addEventListener("keyup", handleKeyUp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     kmap.map.addInteraction(dragBox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // areaRef.value.style.cursor = 'crosshair'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dragBox.on("boxend", () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const extent = dragBox.getGeometry().getExtent(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        treeClusterLayer.layer.getSource().getSource().getFeatures().forEach((feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const isInside = feature.getGeometry().intersectsExtent(extent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (isInside) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // feature.setStyle(selectedStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                feature.set("highlight", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dragBox.on("boxend", handleBoxEnd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const handleKeyDown = (e) => { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -81,309 +145,272 @@ const handleKeyUp = (e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleBoxEnd = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const extent = dragBox.getGeometry().getExtent(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    treeClusterLayer.layer.getSource().getSource().getFeatures().forEach(feature => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 只对当前框选范围内且未被认养的树进行操作 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (feature.getGeometry().intersectsExtent(extent)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 累加选中状态(不会取消之前选中的) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!feature.get("isRenyang")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                feature.set("highlight", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    refreshClusterStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 停止框选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const stopBoxSelect = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    addCluster(mapPoint.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    updateClusterData(mapPoint.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     kmap.map.removeInteraction(dragBox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    isDrawing.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 移除事件监听 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isDrawing.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     window.removeEventListener("keydown", handleKeyDown); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     window.removeEventListener("keyup", handleKeyUp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function saveSelect(callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let sampleIds = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    treeClusterLayer.layer.getSource().getSource().getFeatures().forEach((feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 保存选择 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const saveSelect = (callback) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sampleIds = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    treeClusterLayer.layer.getSource().getSource().getFeatures().forEach(feature => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (feature.get("highlight")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sampleIds.push(feature.get("sampleId")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sampleIds.push(feature.get("sampleId")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const params = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sampleIds, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         isRenyang: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         farmId: Number(sessionStorage.getItem("currentFarmId")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    VE_API.manage_interface.batchOpenOrCloseSample(params).then(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        callback && callback() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    console.log('sampleIds', sampleIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let treeClusterLayer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let level = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let coordinate = util.wktCastGeom(store.getters.userinfo.location).getFirstCoordinate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    kmap = new KMap.Map(areaRef.value, level, coordinate[0], coordinate[1], null, 1, 22, "img", true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    regionLayer = new RegionLayer(kmap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // mockFarmLayer = new MockFarmLayer(kmap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // VE_API.info.contactsList().then(res => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //   if(res.code ===0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //     mockFarmLayer.setData(res.data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    VE_API.manage_interface.batchOpenOrCloseSample(params).then(() => {// 保存成功后刷新数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        callback?.(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let styleCache = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let listenKey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const mapPoint = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let clusterSource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// --------聚合----------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function addCluster(treeListData, distanceVal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!distanceVal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 更新集群数据而不重新渲染整个图层 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const updateClusterData = (treeListData, distanceVal = 20) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!treeListData || !Array.isArray(treeListData)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.error('Invalid data provided to updateClusterData'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (distanceVal === 20) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         mapPoint.value = treeListData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clearCluster(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let features = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 根据状态加上对应的图标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (let item of treeListData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const features = treeListData.map(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            item.wkt = item.geom 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let point = newPoint(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            features.push(point); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            item.wkt = item.geom; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return newPoint(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            console.error('err', err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.error('Error creating point:', err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }).filter(Boolean); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!treeClusterLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createClusterLayer(features, distanceVal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 只更新数据源而不重新创建图层 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clusterSource.getSource().clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clusterSource.getSource().addFeatures(features); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clusterSource.setDistance(distanceVal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!distanceVal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            zoomToFeatures(features); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const source = new VectorSource({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        features: features, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clusterSource = new Cluster({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        distance: distanceVal ? distanceVal : 20, // 集合范围 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // minDistance: 60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        source: source, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 创建集群图层 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const createClusterLayer = (features, distance) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const source = new VectorSource({ features }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clusterSource = new Cluster({ distance, source }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     treeClusterLayer = new KMap.VectorLayer("forest-cluster", 1000, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         minZoom: 15, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         source: clusterSource, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        style: (feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const size = feature.get("features").length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let testStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 只有一个数据,不需要聚合,直接使用第一项数据的图标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (size == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               let featureOne = feature.get("features")[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const key = featureOne.get('isRenyang')+"status" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let style = styleCache[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // let style = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    const highlight = featureOne.get("highlight"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    const currentTree = featureOne.get("currentTree"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (highlight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                src: require("@/assets/images/map/status/active-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                scale: 0.6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else if (currentTree) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                src: require("@/assets/images/map/status/current-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                scale: 0.8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                radius: featureOne.get("isRenyang") === 0 || !featureOne.get("isRenyang") ? 10 : 12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                fill: new Fill({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    color: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                        featureOne.get("isRenyang") === 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#ffffff00" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : featureOne.get("isRenyang") === 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#EEEEEE" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : featureOne.get("isRenyang") === 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#F0AC37" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : "#ffffff00", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stroke: new Stroke({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    color: "#fff", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    width: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // styleCache[key] = style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const imgIcon = featureOne.get('icon') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (imgIcon) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        //     src: imgIcon, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        //     scale: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        image: new Photo({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            src: imgIcon, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            kind: "circle", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            radius: 22, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            shadow: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            crop: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            displacement: [0, 0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            stroke: new Stroke({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                width: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                color: "#fff", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        zIndex: 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 多个点位聚合,循环处理得到图标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const featureObj = feature.get("features")[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // let pointId = featureObj.get('isRenyang') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // let style = styleCache[pointId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const imgIcon = featureObj.get('icon') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let style = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                testStyle = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    text: new Text({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        text: size + "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        offsetX: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        offsetY: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        font: "bold 10px sans-serif", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        fill: new Fill({ color: featureObj.get("isRenyang") === 1 ? "#000" : "#fff" }), // 字体颜色 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // stroke: new Stroke({ color: "green" }), // 字体颜色 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    zIndex: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const highlight = featureObj.get("highlight"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                const currentTree = featureObj.get("currentTree"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (highlight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            src: require("@/assets/images/map/status/active-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            scale: 0.6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else if (currentTree) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        image: new Icon({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            src: require("@/assets/images/map/status/current-icon.png"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            scale: 0.8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // 已认养--显示图标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (imgIcon) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            image: new Photo({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                src: imgIcon, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                kind: "circle", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                radius: 22, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                shadow: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                crop: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                displacement: [0, 0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stroke: new Stroke({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    width: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    color: "#fff", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            zIndex: 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        style = new Style({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            image: new Circle({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                radius: featureObj.get("isRenyang") === 0 || !featureObj.get("isRenyang") ? 10 : 12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                fill: new Fill({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    color: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                        featureObj.get("isRenyang") === 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#ffffff00" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : featureObj.get("isRenyang") === 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#EEEEEE" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : featureObj.get("isRenyang") === 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            ? "#F0AC37" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            : "#ffffff00", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stroke: new Stroke({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    color: "#fff", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    width: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // styleCache[pointId] = style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return [style, testStyle]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style: clusterStyleFunction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     kmap.addLayer(treeClusterLayer.layer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // if (!distance) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    zoomToFeatures(features); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setupMapClickHandler(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(!distanceVal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        zoomToFeatures(features) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 更新后的集群样式函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const clusterStyleFunction = (feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const size = feature.get("features").length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const features = feature.get("features"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!features || features.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new Style({}); // 返回空样式作为fallback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // kmap.getView().fit(this.treeClusterLayer.layer.getSource().getSource().getExtent(), { duration: 1000, padding: [120, 120, 200, 120] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 监听聚合点位的点击,点击后缩放到范围内 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    listenKey = kmap.on("click", (e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (treeClusterLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeClusterLayer.layer.getFeatures(e.pixel).then((clickedFeatures, layer) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let hasFeatures = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (clickedFeatures.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    const features = clickedFeatures[0].get("features"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (features.length > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        hasFeatures = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        kmap.getView().fit(extent, { duration: 1000, padding: [250, 250, 250, 250] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        const currentZoom = kmap.getView().getZoom(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (currentZoom > 17) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            // this.kmap.getView().setZoom(16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            // kmap.getView().animate({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            //     zoom: 14, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            //     duration: 0 // 动画持续时间,单位为毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            // }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            kmap.getView().setZoom(17) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (isDrawing.value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        features[0].set("highlight", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // features[0].setStyle(selectedStyle) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else if (!hasFeatures) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        resetCurrentTree() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        features[0].set("currentTree", true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        const fs = features[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        currentTree.value = features[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        console.log('hasFeatures', fs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        eventBus.emit("click:point", { farmId: Number(sessionStorage.getItem("currentFarmId")), sampleId: fs.get("sampleId"), data: fs.getProperties() }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // eventBus.emit("clickMapPoint", features[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (size === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return getSingleFeatureStyle(features[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return getClusterFeatureStyle(features[0], size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 更新后的获取单个要素样式函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getSingleFeatureStyle = (feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!feature) return new Style({}); // 防御性编程 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 有图标的使用照片样式优先 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const imgIcon = feature.get('icon'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (imgIcon) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return styleCache.photoStyle(imgIcon); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.warn('Failed to create photo style:', e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return styleCache.default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 高亮样式其次 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (feature.get("highlight")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return styleCache.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 当前树样式其次 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (feature.get("currentTree")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return styleCache.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 根据认养状态返回不同样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const isRenyang = feature.get("isRenyang"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch (isRenyang) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 1: return styleCache.renYang1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 2: return styleCache.renYang2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: return styleCache.default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 更新后的获取集群要素样式函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getClusterFeatureStyle = (feature, size) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!feature) return [styleCache.default]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const styles = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const baseStyle = getSingleFeatureStyle(feature); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 确保基础样式有效 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (baseStyle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        styles.push(baseStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 添加集群文字样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (size > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const textStyle = styleCache.clusterText(size, feature.get("isRenyang")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (textStyle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            styles.push(textStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return styles.length > 0 ? styles : [styleCache.default]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 刷新集群样式(不重新创建图层) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const refreshClusterStyle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (treeClusterLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeClusterLayer.layer.getSource().refresh(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 设置地图点击处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const setupMapClickHandler = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (listenKey) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        unByKey(listenKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    listenKey = kmap.on("click", (e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!treeClusterLayer) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeClusterLayer.layer.getFeatures(e.pixel).then((clickedFeatures) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!clickedFeatures.length) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const features = clickedFeatures[0].get("features"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (features.length > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                handleClusterClick(features); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                handleSingleFeatureClick(features[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 处理集群点击 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleClusterClick = (features) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const extent = boundingExtent(features.map(r => r.getGeometry().getCoordinates())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    kmap.getView().fit(extent, { duration: 1000, padding: [250, 250, 250, 250] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const currentZoom = kmap.getView().getZoom(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (currentZoom > 17) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        kmap.getView().setZoom(17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 处理单个要素点击 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleSingleFeatureClick = (feature) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (isDrawing.value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        feature.set("highlight", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        refreshClusterStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        resetCurrentTree(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        feature.set("currentTree", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentTree.value = feature; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        eventBus.emit("click:point", {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            farmId: Number(sessionStorage.getItem("currentFarmId")),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sampleId: feature.get("sampleId"),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data: feature.getProperties()  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 清除聚合图层,解除绑定 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function clearCluster() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 清除集群图层 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const clearCluster = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (treeClusterLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         treeClusterLayer.layer.getSource().getSource().clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        treeClusterLayer.layer.getSource().clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        kmap.removeLayer(treeClusterLayer.layer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         treeClusterLayer = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unByKey(listenKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function zoomToFeatures(features) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 缩放到要素范围 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const zoomToFeatures = (features) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const extent = boundingExtent(features.map(r => r.getGeometry().getCoordinates())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     kmap.getView().fit(extent, { duration: 500, padding: [80, 250, 100, 250] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // const center = getCenter(extent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // kmap.setCenter2(center); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function resetCurrentTree() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    currentTree.value && currentTree.value.set("currentTree", false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 重置当前树 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const resetCurrentTree = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (currentTree.value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentTree.value.set("currentTree", false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        refreshClusterStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-defineExpose({ addCluster, enableBoxSelect, stopBoxSelect, initAreaMap, resetCurrentTree, saveSelect }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 初始化区域地图 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const initAreaMap = (arr) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    regionLayer?.initData(arr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 分区 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let regionLayer = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function initAreaMap(arr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    regionLayer.initData(arr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+defineExpose({  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    addCluster: updateClusterData,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enableBoxSelect,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stopBoxSelect,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    initAreaMap,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    resetCurrentTree,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    saveSelect, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    refreshClusterStyle // 暴露刷新方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <style lang="less" scoped> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -391,4 +418,4 @@ function initAreaMap(arr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     height: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-</style> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</style> 
			 |