use-g-map-trajectory.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { getRoot } from '/@/root'
  2. import hardstandSrc from '/@/assets/icons/hardstand.png'
  3. import droneIcon from '/@/assets/icons/drone.png'
  4. import { wgs84togcj02 } from '../vendors/coordtransform'
  5. import rootStore from '/@/store'
  6. export function useGMapTrajectory() {
  7. const root = getRoot();
  8. let AMap = root.$aMap;
  9. const store = rootStore;
  10. const coverMap = store.state.coverMap;
  11. // 绘制轨迹
  12. const drawTrajectory = (list: any[]) => {
  13. const paths = list.map(item => item.paths);
  14. if (!paths.length) {
  15. return;
  16. }
  17. // 绘制起点图标
  18. const startPosition = paths[0];
  19. const startIcon = new AMap.Icon({
  20. size: new AMap.Size(30, 30),
  21. image: hardstandSrc,
  22. imageSize: new AMap.Size(30, 30)
  23. })
  24. const startMarker = new AMap.Marker({
  25. position: new AMap.LngLat(startPosition[0], startPosition[startPosition.length - 1]),
  26. icon: startIcon,
  27. offset: new AMap.Pixel(-20, -35),// 位置偏移
  28. })
  29. // 绘制轨迹折线
  30. const polyline = new AMap.Polyline({
  31. path: paths,
  32. strokeColor: '#2D8CF0',
  33. showDir: true,// 显示路线白色方向箭头
  34. strokeOpacity: 1,// 轮廓线透明度
  35. strokeWeight: 6,//线宽
  36. strokeStyle: 'solid',
  37. })
  38. const serialList = list.filter((item) => item.show_point);
  39. // 序号
  40. const text = serialList.map((item, index) => {
  41. return new AMap.Text({
  42. position: new AMap.LngLat(item.paths[0], item.paths[1]),
  43. offset: new AMap.Pixel(-8, -30),
  44. text: index + 1,
  45. style: {
  46. backgroundColor: 'transparent',
  47. borderColor: 'transparent',
  48. }
  49. })
  50. })
  51. // 序号下方圆形标记
  52. const circles = serialList.map((item) => {
  53. return new AMap.Circle({
  54. center: new AMap.LngLat(item.paths[0], item.paths[1]),
  55. radius: 0.5, // 半径
  56. fillColor: 'white',
  57. fillOpacity: 1,
  58. strokeWeight: 2,
  59. });
  60. })
  61. // 计算并显示每段线的距离
  62. const distances = [];
  63. const serialPaths = serialList.map(item => item.paths)
  64. for (let i = 0; i < serialPaths.length - 1; i++) {
  65. const distance = AMap.GeometryUtil.distance(new AMap.LngLat(serialPaths[i][0], serialPaths[i][1]), new AMap.LngLat(serialPaths[i + 1][0], serialPaths[i + 1][1]));
  66. // 计算两个点之间的中点坐标
  67. const midLng = (serialPaths[i][0] + serialPaths[i + 1][0]) / 2;
  68. const midLat = (serialPaths[i][1] + serialPaths[i + 1][1]) / 2;
  69. const midPoint = new AMap.LngLat(midLng, midLat);
  70. // 在中点位置放置文本以显示距离
  71. const distanceText = new AMap.Text({
  72. position: midPoint,
  73. offset: new AMap.Pixel(-16, 10),
  74. text: `${distance.toFixed(1)} m`,// 距离
  75. style: {
  76. fontSize: '10px',
  77. color: '#FFFFFF',
  78. backgroundColor: 'rgba(0, 0, 0, 0.75)',
  79. borderColor: 'transparent',
  80. },
  81. });
  82. distances.push(distanceText);
  83. }
  84. const other = [startMarker, polyline, ...text, ...circles, ...distances];
  85. root.$map.add(other);
  86. // 自动缩放地图到合适的视野级别
  87. root.$map.setFitView(other);
  88. }
  89. // 绘制动态轨迹
  90. const drawDynamicTrajectory = (sn: string, deviceInfo: any, host: any[]) => {
  91. if (coverMap[sn] && coverMap[sn].length) {// 如果地图已经画过了,先清除掉之前的绘画结果
  92. coverMap[sn].forEach(cover => root.$map.remove(cover))
  93. coverMap[sn] = []
  94. }
  95. const list = host.map((item: any) => {
  96. const data = {
  97. ...item,
  98. paths: wgs84togcj02(item.longitude, item.latitude),
  99. }
  100. delete data.latitude;
  101. delete data.longitude;
  102. return data;
  103. });
  104. const paths = list.map(item => item.paths);
  105. if (!paths.length) {
  106. return;
  107. }
  108. // 绘制轨迹折线
  109. const polyline = new AMap.Polyline({
  110. path: paths,
  111. strokeColor: '#2D8CF0',
  112. showDir: true,// 显示路线白色方向箭头
  113. strokeOpacity: 1,// 轮廓线透明度
  114. strokeWeight: 6,//线宽
  115. strokeStyle: 'solid',
  116. })
  117. const other = [polyline]
  118. // 获取起飞点
  119. const homeList = list.filter(item => item.type === 0);
  120. if (homeList.length) {
  121. const startPosition = homeList[0].paths;
  122. const startIcon = new AMap.Icon({
  123. size: new AMap.Size(30, 30),
  124. image: hardstandSrc,
  125. imageSize: new AMap.Size(30, 30)
  126. })
  127. const startMarker = new AMap.Marker({
  128. position: new AMap.LngLat(startPosition[0], startPosition[startPosition.length - 1]),
  129. icon: startIcon,
  130. offset: new AMap.Pixel(-20, -35),// 位置偏移
  131. })
  132. other.push(startMarker);
  133. }
  134. // 绘制小飞机图标
  135. if (list.length) {
  136. const path = list[list.length - 1].paths;
  137. const angle = deviceInfo.attitude_head;// 角度
  138. const startIcon = new AMap.Icon({
  139. size: new AMap.Size(40, 40),
  140. image: droneIcon,
  141. imageSize: new AMap.Size(40, 40)
  142. })
  143. const endMarker = new AMap.Marker({
  144. position: new AMap.LngLat(path[0], path[path.length - 1]),
  145. icon: startIcon,
  146. offset: new AMap.Pixel(-20, -20),// 位置偏移
  147. angle: angle,// 旋转角度
  148. })
  149. other.push(endMarker);
  150. }
  151. root.$map.add(other)
  152. coverMap[sn] = [other]
  153. }
  154. return {
  155. drawTrajectory,
  156. drawDynamicTrajectory
  157. }
  158. }