mockFarmLayer.js 11 KB

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