index.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import * as KMap from "@/utils/ol-map/KMap";
  2. import * as util from "@/common/ol_common.js";
  3. import config from "@/api/config.js";
  4. import Style from "ol/style/Style";
  5. import Photo from "ol-ext/style/Photo";
  6. import { Icon, Stroke } from "ol/style.js";
  7. import { newPoint } from "@/utils/map";
  8. const LABEL_FONT = "12px sans-serif";
  9. const LABEL_PADDING = [4, 10, 4, 10];
  10. const LABEL_RADIUS = 18;
  11. const LABEL_DPR = window.devicePixelRatio || 2;
  12. const PHOTO_RESIZE = "?imageView2/1/w/300/interlace/1";
  13. const DEFAULT_PHOTO =
  14. "https://birdseye-img-ali-cdn.sysuimars.com/sikong/fh_sync/71892baf-42b7-4d35-a763-2a420014d901/82d4e04b-df4e-4eef-b220-bd388f5f8299/media/71de4f44-235a-4274-ad5d-e5a0ce6f2abe/DJI_20260530085247_0222_V_code-ws0fsme6cx56.jpeg" + PHOTO_RESIZE;
  15. function getFeaturePhotoSrc(feature) {
  16. // const image = feature.get("beforeImage") || feature.get("afterImage") || feature.get("coverImage");
  17. // if (image?.cloud_filename) {
  18. // return config.base_img_url3 + image.cloud_filename + PHOTO_RESIZE;
  19. // }
  20. // const src = feature.get("mapPhotoUrl") || feature.get("coverImg") || feature.get("imgUrl");
  21. // if (src) {
  22. // return src.startsWith("http") ? src : config.base_img_url3 + src + PHOTO_RESIZE;
  23. // }
  24. return DEFAULT_PHOTO;
  25. }
  26. function createPillLabel(text) {
  27. const [paddingTop, paddingRight, paddingBottom, paddingLeft] = LABEL_PADDING;
  28. const canvas = document.createElement("canvas");
  29. const ctx = canvas.getContext("2d");
  30. const labelText = text || "";
  31. ctx.font = LABEL_FONT;
  32. const metrics = ctx.measureText(labelText);
  33. const textWidth = metrics.width;
  34. const textHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent || 12;
  35. const width = Math.ceil(textWidth + paddingLeft + paddingRight);
  36. const height = Math.ceil(textHeight + paddingTop + paddingBottom);
  37. canvas.width = Math.ceil(width * LABEL_DPR);
  38. canvas.height = Math.ceil(height * LABEL_DPR);
  39. ctx.scale(LABEL_DPR, LABEL_DPR);
  40. ctx.imageSmoothingEnabled = true;
  41. ctx.imageSmoothingQuality = "high";
  42. ctx.font = LABEL_FONT;
  43. ctx.beginPath();
  44. ctx.roundRect(0, 0, width, height, Math.min(LABEL_RADIUS, height / 2));
  45. // 深色胶囊标签,贴合页面深色主题
  46. ctx.fillStyle = "rgba(12, 12, 12, 0.78)";
  47. ctx.fill();
  48. ctx.strokeStyle = "rgba(255, 255, 255, 0.12)";
  49. ctx.lineWidth = 1;
  50. ctx.stroke();
  51. ctx.fillStyle = "#FFFFFF";
  52. ctx.textAlign = "center";
  53. ctx.textBaseline = "middle";
  54. ctx.fillText(labelText, Math.round(width / 2), Math.round(height / 2));
  55. return canvas.toDataURL();
  56. }
  57. /**
  58. * @description 地图层对象
  59. */
  60. class IndexMap {
  61. constructor() {
  62. let that = this;
  63. let vectorStyle = new KMap.VectorStyle();
  64. this.vectorStyle = vectorStyle;
  65. this.onlyName = false;
  66. this.labelStyleCache = {};
  67. this.borderStyle = new Style({
  68. image: new Icon({
  69. src: require("@/assets/img/home/garden-point.png"),
  70. scale: 0.3,
  71. onload: function () {
  72. that.gardenPointLayer.layer.changed();
  73. },
  74. danchor: [0.5,1],
  75. }),
  76. });
  77. this.gardenPointLayer = new KMap.VectorLayer("gardenPointLayer", 99, {
  78. minZoom: 6,
  79. maxZoom: 22,
  80. style: (feature) => {
  81. const labelText = this.onlyName ? feature.get("farmName") : ((feature.get("executeDate") + ' ' + feature.get("farmName")) || feature.get("mapInfo") || "");
  82. if (!this.labelStyleCache[labelText]) {
  83. this.labelStyleCache[labelText] = new Style({
  84. image: new Icon({
  85. src: createPillLabel(labelText),
  86. scale: 1 / LABEL_DPR,
  87. anchor: [0.5, 1],
  88. displacement: [0, 28],
  89. }),
  90. });
  91. }
  92. return [this.borderStyle, this.labelStyleCache[labelText]];
  93. },
  94. });
  95. }
  96. initMap(location, target, isCapital) {
  97. let level = 16;
  98. let coordinate = util.wktCastGeom(location).getFirstCoordinate();
  99. this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 6, 22, isCapital ? "img" : "vec");
  100. let xyz2 = config.base_img_url3 + "map/lby/{z}/{x}/{y}.png";
  101. this.kmap.addXYZLayer(xyz2, { minZoom: 6, maxZoom: 22 }, 2);
  102. this.kmap.addLayer(this.gardenPointLayer.layer);
  103. }
  104. initData(taskList, label, pointType = "point", onlyNameVal = false) {
  105. this.labelStyleCache = {};
  106. this.gardenPointLayer.source.clear();
  107. this.onlyName = onlyNameVal;
  108. if (taskList.length > 0) {
  109. for (let item of taskList) {
  110. item.mapInfo = label
  111. ? item[label]
  112. : (item.executeDeadlineDate || item.executeDate)?.replace(/^\d{4}-(\d{2})-(\d{2})$/, "$1.$2") +
  113. " " +
  114. item.farmWorkName;
  115. this.gardenPointLayer.source.addFeature(newPoint(item, pointType));
  116. }
  117. this.kmap.getView().fit(this.gardenPointLayer.source.getExtent(), { padding: [42, 20, 30, 20] });
  118. const finalZoom = this.kmap.getView().getZoom();
  119. if (finalZoom > 18) {
  120. this.kmap.getView().setZoom(18);
  121. }
  122. }
  123. }
  124. }
  125. export default IndexMap;