shuhao 2 miesięcy temu
rodzic
commit
9acc8a3625

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "html2canvas": "^1.4.1",
     "jquery": "^3.6.3",
     "jsts": "^2.9.3",
+    "mitt": "^3.0.1",
     "moment": "^2.29.4",
     "normalize.css": "^8.0.1",
     "npm": "^9.2.0",

+ 2 - 0
src/api/config.js

@@ -6,9 +6,11 @@ let djiCloudBase = "https://djiapi.sysuimars.com/";
 
 module.exports = {
     base_url :server + "site/",
+    base_dev_url :server + "mini/",
     base_url_python: pythonServe,
     server_mock :serverMock + "site/",
     dji_cloud_base :djiCloudBase,
+    mini_key:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
     image_url:server+"images/",
     base_img_url2 : "https://birdseye-img-ali-cdn.sysuimars.com/",
     base_img_url3 : "https://birdseye-img.sysuimars.com/",

+ 5 - 0
src/api/eventBus.js

@@ -0,0 +1,5 @@
+import mitt from 'mitt';
+
+const eventBus = mitt();
+
+export default eventBus;

+ 48 - 0
src/api/modules/mini_farm.js

@@ -0,0 +1,48 @@
+const config = require("../config")
+
+module.exports = {
+    list: {
+        url: config.base_dev_url + "farm/list",
+        type: "get",
+    },
+    weatherRiskVirtualFarmList: {
+        url: config.base_dev_url + "farm/weatherRiskVirtualFarmList?key="+config.mini_key,
+        type: "get",
+    },
+    getTimeLine: {
+        url: config.base_dev_url + "fairyland/getNodesByFarmId",
+        type: "get",
+    },
+    getReportData: {
+        url: config.base_dev_url + "fairyland/predict",
+        type: "post",
+    },
+    getCataclysmTimeLine: {
+        url: config.base_dev_url + "fairyland/getDisasterNodesByFarmId",
+        type: "get",
+    },
+    getCataclysmReportData: {
+        url: config.base_dev_url + "fairyland/disasterPredict",
+        type: "post",
+    },
+    getDisasterJudgment: {
+        url: config.base_dev_url + "fairyland/disasterJudgment",
+        type: "post",
+    },
+    fetchFarmDetail: {
+        url: config.base_dev_url + "farm/getById",
+        type: "get",
+    },
+    fetchFarmWorkList: {
+        url: config.base_dev_url + "farm/farm_work_list",
+        type: "get",
+    },
+    fetchFarmImgs: {
+        url: config.base_dev_url + "image/list",
+        type: "post",
+    },
+    getLiveStart: {
+        url: config.base_dev_url + "farm/liveStart",
+        type: "get",
+    },
+}

+ 153 - 0
src/common/util.js

@@ -0,0 +1,153 @@
+import VectorSource from 'ol/source/Vector.js';
+import WKT from 'ol/format/WKT.js';
+import Feature from 'ol/Feature.js';
+import VectorLayer from 'ol/layer/Vector.js';
+import Draw from "ol/interaction/Draw";
+import Text from "ol/style/Text";
+import Icon from "ol/style/Icon";
+import {Circle, Fill, Stroke, Style} from 'ol/style.js';
+
+export function getRadius(zoom){
+    if(zoom >= 20){
+        return 120;
+    }
+    if(zoom >= 19){
+        return 70;
+    }
+    if(zoom >= 18){
+        return 30;
+    }
+    if(zoom >= 17){
+        return 15;
+    }
+    return 10;
+}
+
+export function getScale(zoom){
+    if(zoom >= 20){
+        return 0.8;
+    }
+    if(zoom >= 19){
+        return 0.4;
+    }
+    if(zoom >= 18){
+        return 0.2;
+    }
+    if(zoom >= 17){
+        return 0.1;
+    }
+    return 0.1;
+}
+
+export function isShow(zoom,id){
+
+    if(zoom > 18){
+        return true;
+    }
+    if(zoom >= 18){
+        return mo(id, 4)
+    }
+    if(zoom >= 17){
+        return mo(id, 5)
+    }
+    return  mo(id, 5)
+}
+export function mo(id,midu){
+    return id % midu == 0
+}
+
+export const colors = ["#9EFE0C","#FEC30C","#FE760C","#FE0B0C","#0DCAFE","#A80BFF","#E4FE0C","#1A0BFF"];
+export const imgs = ["point6.png","point1.png","point2.png","point3.png","point4.png","point5.png","point6.png","point7.png","point8.png"]
+export const pz = ["未知","白糖罂","桂味","井岗红糯","糯米糍","岭丰糯","进奉","冰荔","妃子笑"]
+
+export function getIndex(name){
+    let i = 0;
+    for(let item of pz){
+        if(name === item){
+            return i;
+        }
+        i++;
+    }
+}
+
+/**
+ *
+ * @param data
+ * @param geomField 形状的字段
+ * @param sign 标识
+ * @returns {Feature<{geometry: any}>}
+ */
+export const newPoint = (data, geomField, sign)=>{
+    let point = new WKT().readGeometry(data[geomField])
+    let feature = new Feature({
+        geometry: point
+    });
+    feature.setId(data.id)
+    feature.set("nodeType",sign)
+    for(let key in data){
+        if(key != geomField && data[key]){
+            feature.set(key,data[key])
+        }
+    }
+    return feature;
+}
+
+export const newGeomPoint = (data)=>{
+    let point = new WKT().readGeometry(data["geom"])
+    let feature = new Feature({
+        geometry: point
+    });
+    feature.setId(data.id)
+    feature.set("nodeType","tree")
+    for(let key in data){
+        if(key != "geom" && data[key]){
+            feature.set(key,data[key])
+        }
+    }
+    return feature;
+}
+
+export const newPolymerFeature = (data)=>{
+    let geom = new WKT().readGeometry(data["wkt"])
+    let feature = new Feature({
+        geometry: geom
+    });
+    feature.set("nodeType","polymer");
+    feature.setId(data.id)
+    for(let key in data){
+        if(key != "wkt"){
+            feature.set(key,data[key])
+        }
+    }
+    return feature;
+}
+
+export const newAreaFeature = (data)=>{
+    let geom = new WKT().readGeometry(data["geom"])
+    let feature = new Feature({
+        geometry: geom
+    });
+    feature.set("nodeType","area");
+    feature.setId(data.id)
+    for(let key in data){
+        if(key != "geom"){
+            feature.set(key,data[key])
+        }
+    }
+    return feature;
+}
+export const pointToFormat = (pointString)=> {
+    let geom = new WKT().readGeometry(pointString)
+        const longitude = geom.getCoordinates()[0];
+        const latitude = geom.getCoordinates()[1];
+        // 转换为度的格式
+        const formattedLongitude = `${longitude.toFixed(0)}°E`;
+        const formattedLatitude = `${latitude.toFixed(0)}°N`;
+
+        const result = `${formattedLongitude},${formattedLatitude}`;
+        console.log(result); // 输出: 111.011490207°E,21.7739355047°N
+        return result
+
+}
+
+

+ 1 - 0
src/views/home/index.vue

@@ -65,6 +65,7 @@ import { useRouter } from "vue-router";
 import SamplePointLayer from "./map/samplePointLayer";
 import {useStore} from "vuex";
 import RegionLayer from "./map/regionLayer";
+import "./map/mockFarmLayer"
 let store = useStore()
 const components = {
   homePage,

+ 2 - 1
src/views/home/map/homeMap.js

@@ -7,7 +7,7 @@ import VectorLayer from "ol/layer/Vector.js";
 import WKT from "ol/format/WKT.js";
 import ScaleLine from "ol/control/ScaleLine";
 import { useRouter } from "vue-router";
-
+import eventBus from "@/api/eventBus";
 /**
  * @description 地图层对象
  */
@@ -22,6 +22,7 @@ class HomeMap {
     let level = 16;
     let coordinate = util.wktCastGeom(location).getFirstCoordinate();
     this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 6, 22);
+    eventBus.emit('homeMap:init', this.kmap);
   }
 }
 

+ 292 - 0
src/views/home/map/mockFarmLayer.js

@@ -0,0 +1,292 @@
+import Style from "ol/style/Style";
+import Photo from "ol-ext/style/Photo";
+import { newPolymerFeature, newPoint } from "@/common/util";
+import Icon from "ol/style/Icon";
+import { Cluster, Vector as VectorSource } from "ol/source.js";
+import { Vector } from "ol/layer.js";
+import * as KMap from '@/utils/ol-map/KMap';
+import { Fill, Text, Circle, Stroke } from "ol/style.js";
+import { boundingExtent } from 'ol/extent.js';
+import { toLonLat } from 'ol/proj';
+import CircleStyle from 'ol/style/Circle.js';
+import {base_img_url2} from "@/api/config.js"
+import eventBus from "@/api/eventBus";
+import router from '@/router'
+/**
+ * 行政区县级天气点位数据
+ */
+class MockFarmLayer {
+    constructor() {
+        let that = this
+        this.nameStyleCache = {}
+        this.cloudFilenameCache = {}
+        this.statusTitleStyleCache = {}
+        this.textBgStyleCache = {}
+        this.diseaseStyle = new Style({
+            image: new Icon({
+                src: require("@/assets/status/status_yj.png"),
+                scale: 0.7,
+                displacement: [2.5, 40],
+            }),
+        });
+        this.pointStyle = new Style({
+            renderer: function (coordinates, state) {
+                let ctx = state.context;
+                ctx.strokeStyle = 'black'; // 边框颜色
+                ctx.lineWidth = 2; // 边框宽度
+                ctx.fillStyle = 'rgba(29,28,28,0.8)'; // 填充颜色
+                ctx.beginPath();
+                ctx.ellipse(coordinates[0], coordinates[1], 7 * state.pixelRatio, 2 * state.pixelRatio, 0, 0, 2 * Math.PI);// 绘制椭圆
+                ctx.fill();// 填充椭圆
+                ctx.stroke();// 绘制椭圆边框
+            },
+            zIndex:-1
+        });
+        eventBus.on("homeMap:init", function (kmap) {
+            that.initLayer(kmap)
+            VE_API.farm.weatherRiskVirtualFarmList().then(res => {
+                if(res.code ===0){
+                    that.setData(res.data)
+                }
+            })
+        })
+        eventBus.on("MockFarmLayer:click", function ({event, feature}) {
+            let targetSampleId = feature.get("targetSampleId")
+            let mockFarmId = feature.get("mockFarmId")
+            // let lonLat = event.map.getCoordinateFromPixel(event.pixel);
+            // console.log('纬度:', lonlat[1]);
+            router.push({path:'feature_album',query:{farmId:mockFarmId,sampleId:targetSampleId,timestamp: Date.now()}})
+        })
+    }
+
+
+    /*************************************************************************************************
+     图层初始化的函数
+     *************************************************************************************************/
+    initLayer(kmap){
+        let that = this;
+        this.vectorStyle = new KMap.VectorStyle()
+        this.clusterSource = new VectorSource({})
+        this.clusterLayer = new Vector({
+            source: new Cluster({
+                distance: 50,
+                source: this.clusterSource,
+            }),
+            name: "MockFarmLayer",
+            minZoom: 6,
+            maxZoom: 21,
+            zIndex: 1001,
+            style: function (feature) {
+                let f = that.selectFeature(feature)
+                let disease = f.get("disease");
+                let grow = f.get("grow");
+                let phenology = "褪绿";
+                let img = f.get("img");
+                let name = f.get("name");
+                let id = f.get("mapId");
+                let styles = [that.pointStyle, that.cloudStyle(img), that.nameStyle(id, name)];
+                that.setProperties(feature,f)
+                let text = "";
+                let fontColor = "#ffffff"
+                if (disease) {
+                    text = disease;
+                    styles.push(that.textBgStyle("#EFEEEE","#EFEEEE"));
+                    fontColor = "#B6B6B6"
+                } else if (grow) {
+                    if(grow === "露白"){
+                        styles.push(that.textBgStyle("#EFEEEE","#EFEEEE"));
+                        text = grow;
+                        fontColor = "#B6B6B6"
+                    }else{
+                        styles.push(that.textBgStyle("#FFFF00","#FFA500"));
+                        text = grow;
+                        fontColor = "#c1c1c1"
+                    }
+
+                } else if (phenology) {
+                    styles.push(that.textBgStyle("#90EE90","#008000"));
+                    text = phenology;
+                    fontColor = "#f5f4f4"
+                }
+                styles.push(that.statusTitleStyle(text, -60, fontColor,"#ffffff00"));
+                if (disease) {
+                    styles.push(that.diseaseStyle)
+                }
+                return styles;
+            }
+        });
+        kmap.addLayer(this.clusterLayer);
+    }
+    /*************************************************************************************************
+     加载数据相关的函数
+     *************************************************************************************************/
+    setData(data){
+        this.clusterSource.clear()
+        let features = []
+        for(let item of data){
+            features.push(newPoint(item,"wkt","mock_farm_data"))
+        }
+        this.clusterSource.addFeatures(features)
+    }
+    /*************************************************************************************************
+        样式相关的函数
+     *************************************************************************************************/
+    /**
+     *
+     * @param startColor '#ffc91a'
+     * @param endColor '#d2a106'
+     * @returns {Style}
+     */
+    textBgStyle(startColor,endColor){
+        let key = startColor + endColor
+        let style = this.textBgStyleCache[key]
+        if (!style) {
+            style = new Style({
+                renderer: function (coordinates, state) {
+                    let ctx = state.context;
+                    // 矩形的参数
+                    const x = coordinates[0]; // 矩形中心点的x坐标
+                    const y = coordinates[1] - 60 * state.pixelRatio; // 矩形中心点的y坐标
+                    const width = 50 * state.pixelRatio; // 矩形的宽度
+                    const height = 20 * state.pixelRatio; // 矩形的高度
+                    const cornerRadius = 4 * state.pixelRatio; // 圆角半径
+                    // 创建渐变
+                    const gradient = ctx.createLinearGradient(x - width / 2, y, x + width / 2, y);
+                    gradient.addColorStop(0, startColor);   // 渐变起始颜色
+                    gradient.addColorStop(1, endColor);  // 渐变结束颜色
+                    // 绘制圆角矩形
+                    ctx.beginPath();
+                    ctx.moveTo(x - width / 2 + cornerRadius, y - height / 2); // 左上角
+                    ctx.lineTo(x + width / 2 - cornerRadius, y - height / 2); // 上边
+                    ctx.arc(x + width / 2 - cornerRadius, y - height / 2 + cornerRadius, cornerRadius, -Math.PI / 2, 0); // 右上角
+                    ctx.lineTo(x + width / 2, y + height / 2 - cornerRadius); // 右边
+                    ctx.arc(x + width / 2 - cornerRadius, y + height / 2 - cornerRadius, cornerRadius, 0, Math.PI / 2); // 右下角
+                    ctx.lineTo(x - width / 2 + cornerRadius, y + height / 2); // 下边
+                    ctx.arc(x - width / 2 + cornerRadius, y + height / 2 - cornerRadius, cornerRadius, Math.PI / 2, Math.PI); // 左下角
+                    ctx.lineTo(x - width / 2, y - height / 2 + cornerRadius); // 左边
+                    ctx.arc(x - width / 2 + cornerRadius, y - height / 2 + cornerRadius, cornerRadius, Math.PI, -Math.PI / 2); // 左上角
+                    ctx.closePath();
+                    ctx.fillStyle = gradient;                // 填充颜色
+                    ctx.fill();
+                },
+                zIndex:2
+            })
+            this.textBgStyleCache[key] = style
+        }
+        return style
+    }
+
+
+    statusTitleStyle(statusName,offsetY,color,strokeColor){
+        let style = this.statusTitleStyleCache[statusName]
+        if (!style) {
+            style = new Style({
+                text: new Text({
+                    text: statusName,
+                    offsetX: 0,
+                    offsetY: offsetY,
+                    font: "bold 12px sans-serif",
+                    fill: new Fill({ color }), // 字体颜色
+                    stroke: new Stroke({ color: strokeColor }), // 字体颜色
+                }),
+                zIndex:3
+            });
+            this.statusTitleStyleCache[statusName] = style
+        }
+        return style
+    }
+    /**
+     * 农场名称样式
+     * @param id
+     * @param name
+     * @returns {Style}
+     */
+    nameStyle(id, name) {
+        let nameStyle = this.nameStyleCache[name]
+        if (!nameStyle) {
+            nameStyle = new Style({
+                text: new Text({
+                    text: name,
+                    offsetX: 0,
+                    offsetY: 12,
+                    font: "bold 12px sans-serif",
+                    fill: new Fill({ color: "#2199f8" }), // 字体颜色
+                    stroke: new Stroke({ color: "#fff" }), // 字体颜色
+                }),
+            });
+            this.nameStyleCache[name] = nameStyle
+        }
+        return nameStyle
+    }
+
+    /**
+     * 农场照片样式
+     * @param cloudFilename
+     * @returns {Style}
+     */
+    cloudStyle(cloudFilename){
+        let that= this
+        let cloudStyle = this.cloudFilenameCache[cloudFilename]
+        if (!cloudStyle) {
+            let cloudUrl = `${cloudFilename}?imageView2/1/w/100`
+            cloudStyle = new Style({
+                image: new Photo({
+                    src: cloudUrl,
+                    radius: 20,
+                    kind:"anchored",
+                    shadow: 5,
+                    crop: true,
+                    displacement: [2.5, 20-4],
+                    stroke: new Stroke({
+                        width: 3,
+                        color: "#fff",
+                    }),
+                    onload: function () {
+                        that.clusterLayer &&
+                        that.clusterLayer.changed();
+                    },
+                })
+            })
+            this.cloudFilenameCache[cloudFilename] = cloudStyle
+        }
+        return cloudStyle
+    }
+
+    /*************************************************************************************************
+     其他函数
+     *************************************************************************************************/
+    setProperties(feature,f) {
+        let disease = f.get("disease");
+        let cloudFilename = f.get("cloudFilename");
+        let mockFarmId = f.get("mockFarmId");
+        let id = f.get("mapId");
+        let targetSampleId = f.get("targetSampleId");
+        feature.set("id",id)
+        feature.set("mockFarmId",mockFarmId)
+        feature.set("targetSampleId",targetSampleId)
+    }
+    selectFeature(feature) {
+        let fs = feature.get("features");
+        if (fs.length === 1) {
+            return fs[0];
+        } else {
+            // 优先返回有 disease 的项
+            for (let item of fs) {
+                if (item.get("disease")) {
+                    return item;
+                }
+            }
+            // 其次返回有 grow 的项
+            for (let item of fs) {
+                if (item.get("grow")) {
+                    return item;
+                }
+            }
+            // 如果都没有,返回第一个项
+            return fs[0];
+        }
+    }
+
+}
+
+new MockFarmLayer()

Plik diff jest za duży
+ 191 - 431
yarn.lock


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików