mockFarmLayer.js 12 KB

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