mockFarmLayer.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import Style from "ol/style/Style";
  2. import Photo from "ol-ext/style/Photo";
  3. import { newPolymerFeature, newPoint } from "@/common/util";
  4. import Icon from "ol/style/Icon";
  5. import { Cluster, Vector as VectorSource } from "ol/source.js";
  6. import { Vector } from "ol/layer.js";
  7. import * as KMap from '@/utils/ol-map/KMap';
  8. import { Fill, Text, Circle, Stroke } from "ol/style.js";
  9. import { boundingExtent } from 'ol/extent.js';
  10. import { toLonLat } from 'ol/proj';
  11. import CircleStyle from 'ol/style/Circle.js';
  12. import {base_img_url2} from "@/api/config.js"
  13. import eventBus from "@/api/eventBus";
  14. import router from '@/router'
  15. /**
  16. * 行政区县级天气点位数据
  17. */
  18. class MockFarmLayer {
  19. constructor() {
  20. let that = this
  21. this.nameStyleCache = {}
  22. this.cloudFilenameCache = {}
  23. this.statusTitleStyleCache = {}
  24. this.textBgStyleCache = {}
  25. this.diseaseStyle = new Style({
  26. image: new Icon({
  27. src: require("@/assets/status/status_yj.png"),
  28. scale: 0.7,
  29. displacement: [2.5, 40],
  30. }),
  31. });
  32. this.pointStyle = new Style({
  33. renderer: function (coordinates, state) {
  34. let ctx = state.context;
  35. ctx.strokeStyle = 'black'; // 边框颜色
  36. ctx.lineWidth = 2; // 边框宽度
  37. ctx.fillStyle = 'rgba(29,28,28,0.8)'; // 填充颜色
  38. ctx.beginPath();
  39. ctx.ellipse(coordinates[0], coordinates[1], 7 * state.pixelRatio, 2 * state.pixelRatio, 0, 0, 2 * Math.PI);// 绘制椭圆
  40. ctx.fill();// 填充椭圆
  41. ctx.stroke();// 绘制椭圆边框
  42. },
  43. zIndex:-1
  44. });
  45. eventBus.on("warningMap:init", function (kmap) {
  46. that.initLayer(kmap)
  47. VE_API.mini_farm.weatherRiskVirtualFarmList().then(res => {
  48. if(res.code ===0){
  49. that.setData(res.data)
  50. }
  51. })
  52. })
  53. eventBus.on("weatherTime:changeTime", function ({date}) {
  54. VE_API.mini_farm.weatherRiskVirtualFarmList({date: "2025-"+date}).then(res => {
  55. if(res.code ===0){
  56. that.setData(res.data)
  57. }
  58. })
  59. })
  60. // eventBus.on("MockFarmLayer:click", function ({event, feature}) {
  61. // let targetSampleId = feature.get("targetSampleId")
  62. // let mockFarmId = feature.get("mockFarmId")
  63. // // let lonLat = event.map.getCoordinateFromPixel(event.pixel);
  64. // // console.log('纬度:', lonlat[1]);
  65. // router.push({path:'feature_album',query:{farmId:mockFarmId,sampleId:targetSampleId,timestamp: Date.now()}})
  66. // })
  67. }
  68. /*************************************************************************************************
  69. 图层初始化的函数
  70. *************************************************************************************************/
  71. initLayer(kmap){
  72. let that = this;
  73. this.vectorStyle = new KMap.VectorStyle()
  74. this.clusterSource = new VectorSource({})
  75. this.clusterLayer = new Vector({
  76. source: new Cluster({
  77. distance: 50,
  78. source: this.clusterSource,
  79. }),
  80. name: "MockFarmLayer",
  81. minZoom: 5,
  82. maxZoom: 21,
  83. zIndex: 1001,
  84. style: function (feature) {
  85. let f = that.selectFeature(feature)
  86. let disease = f.get("disease");
  87. let grow = f.get("grow");
  88. let phenology = "褪绿";
  89. let img = f.get("img");
  90. let name = f.get("name");
  91. let id = f.get("mapId");
  92. let styles = [that.pointStyle, that.cloudStyle(img), that.nameStyle(id, name)];
  93. that.setProperties(feature,f)
  94. let text = "";
  95. let fontColor = "#ffffff"
  96. if (disease) {
  97. text = disease;
  98. styles.push(that.textBgStyle("#EFEEEE","#EFEEEE"));
  99. fontColor = "#B6B6B6"
  100. } else if (grow) {
  101. if(grow === "露白"){
  102. styles.push(that.textBgStyle("#EFEEEE","#EFEEEE"));
  103. text = grow;
  104. fontColor = "#B6B6B6"
  105. }else{
  106. styles.push(that.textBgStyle("#FFFF00","#FFA500"));
  107. text = grow;
  108. fontColor = "#c1c1c1"
  109. }
  110. } else if (phenology) {
  111. styles.push(that.textBgStyle("#90EE90","#008000"));
  112. text = phenology;
  113. fontColor = "#f5f4f4"
  114. }
  115. styles.push(that.statusTitleStyle(text, -60, fontColor,"#ffffff00"));
  116. if (disease) {
  117. styles.push(that.diseaseStyle)
  118. }
  119. return styles;
  120. }
  121. });
  122. kmap.addLayer(this.clusterLayer);
  123. }
  124. /*************************************************************************************************
  125. 加载数据相关的函数
  126. *************************************************************************************************/
  127. setData(data){
  128. this.clusterSource.clear()
  129. let features = []
  130. for(let item of data){
  131. features.push(newPoint(item,"wkt","mock_farm_data"))
  132. }
  133. this.clusterSource.addFeatures(features)
  134. }
  135. /*************************************************************************************************
  136. 样式相关的函数
  137. *************************************************************************************************/
  138. /**
  139. *
  140. * @param startColor '#ffc91a'
  141. * @param endColor '#d2a106'
  142. * @returns {Style}
  143. */
  144. textBgStyle(startColor,endColor){
  145. let key = startColor + endColor
  146. let style = this.textBgStyleCache[key]
  147. if (!style) {
  148. style = new Style({
  149. renderer: function (coordinates, state) {
  150. let ctx = state.context;
  151. // 矩形的参数
  152. const x = coordinates[0]; // 矩形中心点的x坐标
  153. const y = coordinates[1] - 60 * state.pixelRatio; // 矩形中心点的y坐标
  154. const width = 50 * state.pixelRatio; // 矩形的宽度
  155. const height = 20 * state.pixelRatio; // 矩形的高度
  156. const cornerRadius = 4 * state.pixelRatio; // 圆角半径
  157. // 创建渐变
  158. const gradient = ctx.createLinearGradient(x - width / 2, y, x + width / 2, y);
  159. gradient.addColorStop(0, startColor); // 渐变起始颜色
  160. gradient.addColorStop(1, endColor); // 渐变结束颜色
  161. // 绘制圆角矩形
  162. ctx.beginPath();
  163. ctx.moveTo(x - width / 2 + cornerRadius, y - height / 2); // 左上角
  164. ctx.lineTo(x + width / 2 - cornerRadius, y - height / 2); // 上边
  165. ctx.arc(x + width / 2 - cornerRadius, y - height / 2 + cornerRadius, cornerRadius, -Math.PI / 2, 0); // 右上角
  166. ctx.lineTo(x + width / 2, y + height / 2 - cornerRadius); // 右边
  167. ctx.arc(x + width / 2 - cornerRadius, y + height / 2 - cornerRadius, cornerRadius, 0, Math.PI / 2); // 右下角
  168. ctx.lineTo(x - width / 2 + cornerRadius, y + height / 2); // 下边
  169. ctx.arc(x - width / 2 + cornerRadius, y + height / 2 - cornerRadius, cornerRadius, Math.PI / 2, Math.PI); // 左下角
  170. ctx.lineTo(x - width / 2, y - height / 2 + cornerRadius); // 左边
  171. ctx.arc(x - width / 2 + cornerRadius, y - height / 2 + cornerRadius, cornerRadius, Math.PI, -Math.PI / 2); // 左上角
  172. ctx.closePath();
  173. ctx.fillStyle = gradient; // 填充颜色
  174. ctx.fill();
  175. },
  176. zIndex:2
  177. })
  178. this.textBgStyleCache[key] = style
  179. }
  180. return style
  181. }
  182. statusTitleStyle(statusName,offsetY,color,strokeColor){
  183. let style = this.statusTitleStyleCache[statusName]
  184. if (!style) {
  185. style = new Style({
  186. text: new Text({
  187. text: statusName,
  188. offsetX: 0,
  189. offsetY: offsetY,
  190. font: "bold 12px sans-serif",
  191. fill: new Fill({ color }), // 字体颜色
  192. stroke: new Stroke({ color: strokeColor }), // 字体颜色
  193. }),
  194. zIndex:3
  195. });
  196. this.statusTitleStyleCache[statusName] = style
  197. }
  198. return style
  199. }
  200. /**
  201. * 农场名称样式
  202. * @param id
  203. * @param name
  204. * @returns {Style}
  205. */
  206. nameStyle(id, name) {
  207. let nameStyle = this.nameStyleCache[name]
  208. if (!nameStyle) {
  209. nameStyle = new Style({
  210. text: new Text({
  211. text: name,
  212. offsetX: 0,
  213. offsetY: 12,
  214. font: "bold 12px sans-serif",
  215. fill: new Fill({ color: "#2199f8" }), // 字体颜色
  216. stroke: new Stroke({ color: "#fff" }), // 字体颜色
  217. }),
  218. });
  219. this.nameStyleCache[name] = nameStyle
  220. }
  221. return nameStyle
  222. }
  223. /**
  224. * 农场照片样式
  225. * @param cloudFilename
  226. * @returns {Style}
  227. */
  228. cloudStyle(cloudFilename){
  229. let that= this
  230. let cloudStyle = this.cloudFilenameCache[cloudFilename]
  231. if (!cloudStyle) {
  232. let cloudUrl = `${cloudFilename}?imageView2/1/w/100`
  233. cloudStyle = new Style({
  234. image: new Photo({
  235. src: cloudUrl,
  236. radius: 20,
  237. kind:"anchored",
  238. shadow: 5,
  239. crop: true,
  240. displacement: [2.5, 20-4],
  241. stroke: new Stroke({
  242. width: 3,
  243. color: "#fff",
  244. }),
  245. onload: function () {
  246. that.clusterLayer &&
  247. that.clusterLayer.changed();
  248. },
  249. })
  250. })
  251. this.cloudFilenameCache[cloudFilename] = cloudStyle
  252. }
  253. return cloudStyle
  254. }
  255. /*************************************************************************************************
  256. 其他函数
  257. *************************************************************************************************/
  258. setProperties(feature,f) {
  259. let disease = f.get("disease");
  260. let cloudFilename = f.get("cloudFilename");
  261. let mockFarmId = f.get("mockFarmId");
  262. let id = f.get("mapId");
  263. let targetSampleId = f.get("targetSampleId");
  264. feature.set("id",id)
  265. feature.set("mockFarmId",mockFarmId)
  266. feature.set("targetSampleId",targetSampleId)
  267. }
  268. selectFeature(feature) {
  269. let fs = feature.get("features");
  270. if (fs.length === 1) {
  271. return fs[0];
  272. } else {
  273. // 优先返回有 disease 的项
  274. for (let item of fs) {
  275. if (item.get("disease")) {
  276. return item;
  277. }
  278. }
  279. // 其次返回有 grow 的项
  280. for (let item of fs) {
  281. if (item.get("grow")) {
  282. return item;
  283. }
  284. }
  285. // 如果都没有,返回第一个项
  286. return fs[0];
  287. }
  288. }
  289. }
  290. new MockFarmLayer()