Browse Source

feat:添加底图显示

wangsisi 1 week ago
parent
commit
a7361cd348

+ 120 - 0
src/utils/ol-map/StaticImgLayer.js

@@ -0,0 +1,120 @@
+
+import LTBaseObject from './KBaseObject'
+import Common from './Common'
+import Static from "ol/source/ImageStatic";
+import ImageLayer from "ol/layer/Image";
+/**
+ * @description LTMap.GeoJsonLayer GeoJsonLayer图层类
+*/
+class StaticImgLayer extends LTBaseObject{
+	/**
+	 * @description 构造函数
+	 * @param {String} url XYZ图层服务地址
+	 * @param {LTMap.Map} [mapInstance=null] map对象,单地图的时候可不传,多地图时候需要传
+	 * @memberof XYZLayer
+	 */
+	constructor(url,options,zIndex,mapInstance = null){
+    super(mapInstance)
+		const vm = this
+		vm.initStaticImgLayer(url,options,zIndex)
+  }
+	/**
+	 * @description 初始化静态图片图层
+	 */
+	initStaticImgLayer(url,options,zIndex){
+		var minZoom = Common.BaseLayerZoom[0];
+		var maxZoom = Common.BaseLayerZoom[1];
+		let opacity = 1;
+		if(options && options.opacity != undefined){
+			opacity = options.opacity
+		}
+		if(options && options.minZoom != undefined){
+			minZoom = options.minZoom
+		}
+		if(options && options.maxZoom != undefined){
+			maxZoom = options.maxZoom
+		}
+		if(options && options.zIndex != undefined){
+			zIndex = options.zIndex
+		}
+		const vm = this
+		vm.source = new Static({
+			url,
+			projection: 'EPSG:4326',
+			imageExtent: options.extent,
+		});
+
+		vm.layer = new ImageLayer({
+			source:vm.source,
+			maxZoom:maxZoom,
+			minZoom:minZoom,
+			opacity:opacity,
+			zIndex:zIndex,
+			extent:options.extent || [Infinity, -Infinity, -Infinity, Infinity]
+		})
+
+		if(options && options.padding != undefined){
+			vm.layer.set('padding',options.padding)
+		}
+
+		vm.map.addLayer(vm.layer)
+	}
+	setProperty(properties){
+		const vm = this;
+		vm.properties = properties;
+	}
+	getProperty(){
+		const vm = this;
+		return vm.properties?vm.properties:null;
+	}
+  /**
+	* @description 添加XYZ图层到地图
+	* @memberof XYZLayer
+	*/
+  add(){
+		const vm = this
+		if(!vm.state) {
+			vm.map.addLayer(vm.layer)
+			vm.state = true
+		}
+	}
+
+	/**
+	 * @description 从当前地图中移除XYZ图层
+	 * @memberof XYZLayer
+	 */
+	remove() {
+		const vm = this
+		if(vm.state) {
+			vm.map.removeLayer(vm.layer)
+			vm.state = false
+		}
+	}
+
+	/**
+	 * @description 显示XYZ图层数据
+	 * @memberof XYZLayer
+	 */
+	show(){
+		const vm = this
+		vm.layer.setVisible(true)
+	}
+
+	/**
+	 * @description 隐藏XYZ图层数据
+	 * @memberof XYZLayer
+	 */
+	hide(){
+		const vm = this
+		vm.layer.setVisible(false)
+	}
+
+	/**
+	 * @description 缩放到过滤后的地图要素对应范围
+	 * @memberof XYZLayer
+	 */
+	zoomTo() {
+    const vm = this
+	}
+}
+export default StaticImgLayer

+ 71 - 0
src/views/old_mini/agri_file/fileMap.js

@@ -1,6 +1,7 @@
 import * as KMap from "@/utils/ol-map/KMap";
 import * as util from "@/common/ol_common.js";
 import config from "@/api/config.js";
+import StaticImgLayer from "@/utils/ol-map/StaticImgLayer";
 import { Vector as VectorSource } from "ol/source.js";
 import Style from "ol/style/Style";
 import Text from "ol/style/Text";
@@ -16,6 +17,29 @@ import {
     getHeight,
 } from "ol/extent";
 
+/** PNG 农场影像底图:extent 为 [minLon, minLat, maxLon, maxLat],仅以下农场有数据 */
+const FARM_BASE_IMAGE_LAYERS = [
+    {
+        name: "东莞市潢涌村水稻基地",
+        farmId: 320,
+        url: "https://birdseye-img.sysuimars.com/platform-rs/farm_320_20260314.png",
+        extent: [113.48318638854593, 22.90042586164938, 113.98019565717107, 23.36008435819883],
+    },
+    {
+        name: "莞荔园",
+        farmId: 319,
+        url: "https://birdseye-img.sysuimars.com/platform-rs/farm_319_20260314.png",
+        extent: [113.49887532172826, 22.74031995946140, 113.99520269126261, 23.19988233865987],
+    },
+];
+
+const FARM_BASE_IMAGE_FARM_IDS = new Set(FARM_BASE_IMAGE_LAYERS.map((item) => item.farmId));
+
+export function hasFarmBaseImage(farmId) {
+    if (farmId == null || farmId === "") return false;
+    return FARM_BASE_IMAGE_FARM_IDS.has(Number(farmId));
+}
+
 const WKT_FORMAT = new WKT();
 
 const RECORD_TYPE_STYLE = {
@@ -105,6 +129,9 @@ class FileMap {
         this._pending = null;
         this._fitTimer = null;
         this._renderToken = 0;
+        this.baseImageLayers = [];
+        this.baseImageVisible = false;
+        this.currentFarmId = null;
         const vectorStyle = new KMap.VectorStyle();
 
         this.recordPolygonLayer = new KMap.VectorLayer("fileRecordPolygonLayer", 1000, {
@@ -131,6 +158,49 @@ class FileMap {
         });
     }
 
+    initBaseImageLayers() {
+        FARM_BASE_IMAGE_LAYERS.forEach((item) => {
+            const imgLayer = new StaticImgLayer(
+                item.url,
+                {
+                    extent: item.extent,
+                    minZoom: 8,
+                    maxZoom: 22,
+                    opacity: 0.4,
+                },
+                4,
+                this.kmap,
+            );
+            this.baseImageLayers.push({ farmId: item.farmId, layer: imgLayer });
+        });
+        this.applyBaseImageVisibility();
+    }
+
+    applyBaseImageVisibility() {
+        const canShow = this.baseImageVisible && hasFarmBaseImage(this.currentFarmId);
+        this.baseImageLayers.forEach(({ farmId, layer }) => {
+            const shouldShow = canShow && farmId === this.currentFarmId;
+            if (shouldShow) {
+                layer.show();
+            } else {
+                layer.hide();
+            }
+        });
+    }
+
+    showBaseImageByFarmId(farmId) {
+        this.currentFarmId = farmId != null && farmId !== "" ? Number(farmId) : null;
+        if (!hasFarmBaseImage(this.currentFarmId)) {
+            this.baseImageVisible = false;
+        }
+        this.applyBaseImageVisibility();
+    }
+
+    toggleBaseImageLayers(visible = !this.baseImageVisible) {
+        this.baseImageVisible = visible && hasFarmBaseImage(this.currentFarmId);
+        this.applyBaseImageVisibility();
+    }
+
     initMap(centerWkt, target) {
         if (!target) return;
 
@@ -149,6 +219,7 @@ class FileMap {
 
         this.kmap = new KMap.Map(target, 16, center[0], center[1], null, 8, 22);
         this.kmap.addXYZLayer(config.base_img_url3 + "map/lby/{z}/{x}/{y}.png", { minZoom: 8, maxZoom: 22 }, 2);
+        this.initBaseImageLayers();
         this.kmap.addLayer(this.recordPolygonLayer.layer);
 
         if (this._pending) {

+ 7 - 1
src/views/old_mini/agri_file/index.vue

@@ -78,7 +78,7 @@ import { useStore } from "vuex";
 import weatherInfo from "@/components/weatherInfo.vue";
 import gardenList from "@/components/gardenList.vue";
 import fileFloat from "./components/fileFloat.vue";
-import FileMap, { RECORD_TAB_KEYS, recordsToCenterPoint } from "./fileMap.js";
+import FileMap, { RECORD_TAB_KEYS, recordsToCenterPoint, hasFarmBaseImage } from "./fileMap.js";
 import { useI18n } from "@/i18n";
 
 const { t, locale } = useI18n();
@@ -130,6 +130,7 @@ const activeMapTool = ref(0);
 
 const changeMapTool = (index) => {
     activeMapTool.value = index;
+    fileMap.toggleBaseImageLayers(index === 1 && hasFarmBaseImage(selectedGardenId.value));
 };
 
 const fileMap = new FileMap();
@@ -156,6 +157,8 @@ const initAgriFileMap = async () => {
     await nextTick();
     if (!mapContainer.value) return;
     fileMap.initMap(recordsToCenterPoint(getActiveRecords()), mapContainer.value);
+    fileMap.showBaseImageByFarmId(selectedGardenId.value);
+    fileMap.toggleBaseImageLayers(activeMapTool.value === 1 && hasFarmBaseImage(selectedGardenId.value));
 };
 
 const getFarmRecord = async () => {
@@ -205,6 +208,7 @@ const handleGardenLoaded = ({ hasFarm }) => {
 
 const handleGardenSelected = (garden) => {
     selectedGardenId.value = garden?.id ?? null;
+    fileMap.showBaseImageByFarmId(selectedGardenId.value);
     weatherInfoRef.value?.setSelectedGarden?.(garden);
 };
 
@@ -212,6 +216,8 @@ const farmVarietyName = ref(null);
 const changeGarden = (data) => {
     if (!data?.id) return;
     store.commit("home/SET_GARDEN_ID", data.id);
+    selectedGardenId.value = data.id;
+    fileMap.showBaseImageByFarmId(data.id);
     getFarmRecord();
     activeType.value = data.variety_name;
     farmVarietyName.value = data.variety_name;