index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <div class="map-container">
  3. <div id="map" class="map"></div>
  4. <div v-if="hoverInfo" :style="hoverStyle" class="hover-info">
  5. <h3>{{hoverInfo.fieldName}}</h3>
  6. <div>
  7. <p><span>风场编号</span><span>{{hoverInfo.codeNumber}}</span></p>
  8. <p><span>空气密度</span><span>{{hoverInfo.density}}</span></p>
  9. <p><span>总额定容量</span><span>{{hoverInfo.ratedCapacityNumber}}</span></p>
  10. <p><span>经度</span><span>{{hoverInfo.longitude}}</span></p>
  11. <p><span>纬度</span><span>{{hoverInfo.latitude}}</span></p>
  12. <p><span>海拔高度</span><span>{{hoverInfo.elevationHeight}}</span></p>
  13. <p><span>最新分析时间</span><span> {{ $formatDate(hoverInfo.wfbrCreateTime) }}</span></p>
  14. </div>
  15. </div>
  16. <div v-if="hoverfengji" :style="hoverfengjiStyle" class="hover-fengji">
  17. <h3>{{hoverfengji.engineName}}</h3>
  18. <div>
  19. <p><span>风机编号</span><span>{{hoverfengji.engineCode}}</span></p>
  20. <p><span>额定容量</span><span>{{hoverfengji.ratedCapacity}}</span></p>
  21. <p><span>海拔高度</span><span>{{hoverfengji.elevationHeight}}</span></p>
  22. <p><span>轮毂高度</span><span>{{hoverfengji.hubHeight}}</span></p>
  23. <p><span>经度</span><span>{{hoverfengji.longitude}}</span></p>
  24. <p><span>维度</span><span>{{hoverfengji.latitude}}</span></p>
  25. <p>是否标杆风机 <span>{{hoverfengji.sightcing == 1 ? '是' : '否'}}</span></p>
  26. <p><span>额定风速</span><span>{{hoverfengji.rated_wind_speed}}</span></p>
  27. <p><span>切入风速</span><span>{{hoverfengji.ratedCutInWindspeed}}</span></p>
  28. <p><span>切出风速</span><span>{{hoverfengji.ratedCutOutWindspeed}}</span></p>
  29. </div>
  30. </div>
  31. <div v-if="hoverta" :style="hovertaStyle" class="hover-ta">
  32. <h3>{{hoverta.anemometerName}}</h3>
  33. <div>
  34. <p><span>测风塔编号</span><span>{{hoverta.anemometerCode}}</span></p>
  35. <p><span>经度</span><span>{{hoverta.longitude}}</span></p>
  36. <p><span>维度</span><span>{{hoverta.anemometerName}}</span></p>
  37. <p><span>状态</span><span>{{hoverta.latitude}}</span></p>
  38. <p><span>测风塔高度</span><span>{{hoverta.anemometerHeightStrings}}</span></p>
  39. </div>
  40. </div>
  41. </div>
  42. </template>
  43. <script>
  44. import "ol/ol.css";
  45. import { Map, View, Feature } from "ol";
  46. import TileLayer from "ol/layer/Tile.js";
  47. import { XYZ } from "ol/source";
  48. import { fromLonLat } from "ol/proj";
  49. import { Vector } from "ol/source";
  50. import { Vector as VectorLayer } from "ol/layer";
  51. import { Point } from "ol/geom";
  52. import { Icon, Style } from "ol/style";
  53. import ZoomSlider from "ol/control/ZoomSlider.js";
  54. import { defaults as defaultControls } from "ol/control.js";
  55. import icon01 from "../../assets/img/icon01.png";
  56. import icon02 from "../../assets/img/icon02.png";
  57. import icon03 from "../../assets/img/icon03.png";
  58. import icon04 from "../../assets/img/icon04.png";
  59. import icon05 from "../../assets/img/icon05.png";
  60. import defaultIcon from "../../assets/img/icon05.png";
  61. export default {
  62. props: {
  63. windEngineGroupByFieldCodeDetail: {
  64. type: Object,
  65. default: () => {
  66. return {};
  67. },
  68. },
  69. },
  70. name: "T-map",
  71. data() {
  72. return {
  73. hoverInfo: null,
  74. hoverStyle: {
  75. position: "absolute",
  76. left: "0px",
  77. top: "0px",
  78. },
  79. hoverfengji: null,
  80. hoverfengjiStyle: {
  81. position: "absolute",
  82. left: "0px",
  83. top: "0px",
  84. },
  85. hoverta: null,
  86. hovertaStyle: {
  87. position: "absolute",
  88. left: "0px",
  89. top: "0px",
  90. },
  91. };
  92. },
  93. watch: {
  94. windEngineGroupByFieldCodeDetail: {
  95. handler(data) {
  96. if (data) {
  97. }
  98. },
  99. deep: true, // 深度监听
  100. },
  101. },
  102. mounted() {
  103. this.map = new Map({
  104. target: "map",
  105. view: new View({
  106. projection: "EPSG:4326",
  107. center: fromLonLat([116.389, 39.903]), //地图中心
  108. zoom: 5, //默认缩放级别
  109. minZoom: 5, //最小缩放级别
  110. maxZoom: 12, //最大缩放级别
  111. extent: [
  112. 70.3671875, 18.14576369243164, 134.92927612304688, 55.667146064662596,
  113. ],
  114. }),
  115. layers: [
  116. new TileLayer({
  117. source: new XYZ({
  118. // url: "http://127.0.0.1:8010/tiles/{z}/{x}/{y}.png", //本地
  119. url: "http://192.168.50.235/tiles/{z}/{x}/{y}.png", //内外
  120. }),
  121. }),
  122. new VectorLayer({
  123. id: "marker",
  124. source: new Vector(),
  125. }),
  126. ],
  127. controls: defaultControls().extend([new ZoomSlider()]),
  128. });
  129. // console.log(this.map.getView().calculateExtent());
  130. this.initEvent();
  131. },
  132. methods: {
  133. /**
  134. * 地图上打点
  135. * @param data
  136. */
  137. addMarker(data = { point: [120.2, 30.35], val: "1" }) {
  138. console.log(data);
  139. const layer = this.map
  140. .getLayers()
  141. .getArray()
  142. .find((element) => {
  143. return element.get("id") === "marker";
  144. });
  145. const source = layer.getSource();
  146. const iconSrc = this.getIconForValue(data.val);
  147. const feature = new Feature({
  148. geometry: new Point(fromLonLat(data.point, "EPSG:4326")),
  149. name: "marker",
  150. data,
  151. });
  152. feature.setStyle(
  153. new Style({
  154. image: new Icon({
  155. src: iconSrc,
  156. scale: [0.3, 0.3],
  157. anchor: [0.5, 1],
  158. opacity: 1,
  159. }),
  160. })
  161. );
  162. source.addFeature(feature);
  163. },
  164. /**
  165. * 地图上打点
  166. * @param data
  167. */
  168. clearMarkers() {
  169. const layer = this.map
  170. .getLayers()
  171. .getArray()
  172. .find((element) => {
  173. return element.get("id") === "marker";
  174. });
  175. if (layer) {
  176. const source = layer.getSource();
  177. source.clear(); // 清空所有特征
  178. }
  179. },
  180. getIconForValue(val) {
  181. switch (val) {
  182. case "-1":
  183. case -1:
  184. return icon01;
  185. case 0:
  186. case "0":
  187. return icon02;
  188. case 1:
  189. case "1":
  190. return icon03;
  191. case "4":
  192. return icon04;
  193. case "5":
  194. return icon05;
  195. default:
  196. return defaultIcon;
  197. }
  198. },
  199. /**
  200. * 初始化地图事件
  201. */
  202. initEvent() {
  203. this.map.on("pointermove", (evt) => {
  204. const features = this.map.getFeaturesAtPixel(evt.pixel, {
  205. hitTolerance: 1,
  206. });
  207. if (features && features.length > 0) {
  208. const feature = features.at(0);
  209. const val = feature.get("data").val;
  210. if (val == "1") {
  211. this.hoverInfo = feature.get("data");
  212. this.hoverStyle.left = `${evt.pixel[0] + 10}px`;
  213. this.hoverStyle.top = `${evt.pixel[1] + 10}px`;
  214. } else if (val == "4") {
  215. this.hoverfengji = feature.get("data");
  216. this.hoverfengjiStyle.left = `${evt.pixel[0] + 10}px`;
  217. this.hoverfengjiStyle.top = `${evt.pixel[1] + 10}px`;
  218. this.currentFeatureData = feature.get("data"); // Store the feature data for click event
  219. } else if (val == "5") {
  220. this.hoverta = feature.get("data");
  221. this.hovertaStyle.left = `${evt.pixel[0] + 10}px`;
  222. this.hovertaStyle.top = `${evt.pixel[1] + 10}px`;
  223. this.currentFeatureData = feature.get("data"); // Store the feature data for click event
  224. } else {
  225. this.hoverInfo = null;
  226. this.hoverfengji = false;
  227. this.hoverta = false;
  228. this.currentFeatureData = null; // Ensure no stored feature data if val is not 3 or 4
  229. }
  230. } else {
  231. this.hoverInfo = null;
  232. this.hoverfengji = false;
  233. this.hoverta = false;
  234. this.currentFeatureData = null; // Ensure no stored feature data if there are no features
  235. }
  236. });
  237. this.map.on("click", (evt) => {
  238. const features = this.map.getFeaturesAtPixel(evt.pixel, {
  239. hitTolerance: 1,
  240. });
  241. if (features && features.length > 0) {
  242. const feature = features.at(0);
  243. this.$emit("feature-click", feature.get("data"));
  244. }
  245. // Check if there's stored feature data and if it's a val === "4" feature
  246. if (this.currentFeatureData && this.currentFeatureData.val === "4") {
  247. // Handle click event for val === "4"
  248. this.handleFeatureClick(this.currentFeatureData);
  249. }
  250. });
  251. },
  252. handleFeatureClick(featureData) {
  253. // Implement your logic to handle the click event for val === "4"
  254. // For example, emit an event or perform some action
  255. console.log("Feature with val === '4' clicked:", featureData);
  256. },
  257. /**
  258. * 平移缩放
  259. * @param data
  260. */
  261. moveAndZoom(data = { point: [120.2, 30.35], zoom: 15 }) {
  262. this.map.getView().animate({
  263. center: fromLonLat(data.point, "EPSG:4326"),
  264. zoom: data.zoom,
  265. duration: 2000,
  266. });
  267. },
  268. },
  269. };
  270. </script>
  271. <style scoped lang="scss">
  272. .map-container {
  273. position: relative;
  274. width: 100%;
  275. height: 100%;
  276. }
  277. .map {
  278. width: 100%;
  279. height: 100%;
  280. }
  281. .hover-info {
  282. position: absolute;
  283. color: white;
  284. padding: 0px;
  285. z-index: 100;
  286. h3 {
  287. background-color: #008080cc;
  288. width: 240px;
  289. padding: 5px 10px;
  290. font-size: 16px;
  291. }
  292. div {
  293. background-color: #00808097;
  294. width: 240px;
  295. font-size: 12px;
  296. p {
  297. padding: 5px 10px;
  298. display: flex;
  299. justify-content: space-between;
  300. }
  301. }
  302. }
  303. .hover-fengji {
  304. position: absolute;
  305. color: white;
  306. padding: 0px;
  307. z-index: 100;
  308. h3 {
  309. background-color: #027cb4cc;
  310. width: 240px;
  311. padding: 5px 10px;
  312. font-size: 16px;
  313. }
  314. div {
  315. background-color: #027cb49e;
  316. width: 240px;
  317. font-size: 12px;
  318. p {
  319. padding: 5px 10px;
  320. display: flex;
  321. justify-content: space-between;
  322. }
  323. }
  324. }
  325. .hover-ta {
  326. position: absolute;
  327. color: white;
  328. padding: 0px;
  329. z-index: 100;
  330. h3 {
  331. background-color: #d90019b2;
  332. width: 240px;
  333. padding: 5px 10px;
  334. font-size: 16px;
  335. }
  336. div {
  337. background-color: #d9001994;
  338. width: 240px;
  339. font-size: 12px;
  340. p {
  341. padding: 5px 10px;
  342. display: flex;
  343. justify-content: space-between;
  344. }
  345. }
  346. }
  347. </style>