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