use-g-map-trajectory.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. // coverMap[id].forEach(cover => root.$map.remove(cover))
  13. // coverMap[id] = []
  14. // 绘制轨迹
  15. const drawTrajectory = (list: any[]) => {
  16. const paths = list.map(item => item.paths)
  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) => [2, 3].includes(item.type));
  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, index) => {
  53. return new AMap.Circle({
  54. center: new AMap.LngLat(item.paths[0], item.paths[1]),
  55. radius: 0.5, // 半径
  56. // strokeColor: 'white',
  57. fillColor: 'white',
  58. fillOpacity: 1,
  59. strokeWeight: 2,
  60. });
  61. })
  62. // 计算并显示每段线的距离
  63. const distances = [];
  64. const serialPaths = serialList.map(item => item.paths)
  65. for (let i = 0; i < serialPaths.length - 1; i++) {
  66. 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]));
  67. // 计算两个点之间的中点坐标
  68. const midLng = (serialPaths[i][0] + serialPaths[i + 1][0]) / 2;
  69. const midLat = (serialPaths[i][1] + serialPaths[i + 1][1]) / 2;
  70. const midPoint = new AMap.LngLat(midLng, midLat);
  71. // 在中点位置放置文本以显示距离
  72. const distanceText = new AMap.Text({
  73. position: midPoint,
  74. offset: new AMap.Pixel(-16, 10),
  75. text: `${distance.toFixed(1)} m`,// 距离
  76. style: {
  77. fontSize: '10px',
  78. color: '#FFFFFF',
  79. backgroundColor: 'rgba(0, 0, 0, 0.75)',
  80. borderColor: 'transparent',
  81. },
  82. });
  83. distances.push(distanceText);
  84. }
  85. root.$map.add([startMarker, polyline, ...text, ...circles, ...distances]);
  86. // 自动缩放地图到合适的视野级别
  87. root.$map.setFitView([startMarker, polyline]);
  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. // 绘制轨迹折线
  106. const polyline = new AMap.Polyline({
  107. path: paths,
  108. strokeColor: '#2D8CF0',
  109. showDir: true,// 显示路线白色方向箭头
  110. strokeOpacity: 1,// 轮廓线透明度
  111. strokeWeight: 6,//线宽
  112. strokeStyle: 'solid',
  113. })
  114. // const serialList = list.filter((item) => item.type === 1);
  115. // // 序号
  116. // const text = serialList.map((item, index) => {
  117. // return new AMap.Text({
  118. // position: new AMap.LngLat(item.paths[0], item.paths[1]),
  119. // offset: new AMap.Pixel(-8, -30),
  120. // text: index + 1,
  121. // style: {
  122. // backgroundColor: 'transparent',
  123. // borderColor: 'transparent',
  124. // }
  125. // })
  126. // })
  127. // // 序号下方圆形标记
  128. // const circles = serialList.map((item, index) => {
  129. // return new AMap.Circle({
  130. // center: new AMap.LngLat(item.paths[0], item.paths[1]),
  131. // radius: 0.5, // 半径
  132. // // strokeColor: 'white',
  133. // fillColor: 'white',
  134. // fillOpacity: 1,
  135. // strokeWeight: 2,
  136. // });
  137. // })
  138. // // 计算并显示每段线的距离
  139. // const distances = [];
  140. // const serialPaths = serialList.map(item => item.paths)
  141. // for (let i = 0; i < serialPaths.length - 1; i++) {
  142. // 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]));
  143. // // 计算两个点之间的中点坐标
  144. // const midLng = (serialPaths[i][0] + serialPaths[i + 1][0]) / 2;
  145. // const midLat = (serialPaths[i][1] + serialPaths[i + 1][1]) / 2;
  146. // const midPoint = new AMap.LngLat(midLng, midLat);
  147. // // 在中点位置放置文本以显示距离
  148. // const distanceText = new AMap.Text({
  149. // position: midPoint,
  150. // offset: new AMap.Pixel(-16, 10),
  151. // text: `${distance.toFixed(1)} m`,// 距离
  152. // style: {
  153. // fontSize: '10px',
  154. // color: '#FFFFFF',
  155. // backgroundColor: 'rgba(0, 0, 0, 0.75)',
  156. // borderColor: 'transparent',
  157. // },
  158. // });
  159. // distances.push(distanceText);
  160. // }
  161. const other = [polyline]
  162. // 获取起飞点
  163. const homeList = list.filter(item => item.type === 0);
  164. if (homeList.length) {
  165. const startPosition = homeList[0].paths;
  166. const startIcon = new AMap.Icon({
  167. size: new AMap.Size(30, 30),
  168. image: hardstandSrc,
  169. imageSize: new AMap.Size(30, 30)
  170. })
  171. const startMarker = new AMap.Marker({
  172. position: new AMap.LngLat(startPosition[0], startPosition[startPosition.length - 1]),
  173. icon: startIcon,
  174. offset: new AMap.Pixel(-20, -35),// 位置偏移
  175. })
  176. other.push(startMarker);
  177. }
  178. // // 绘制小飞机图标
  179. // if (list.length) {
  180. // const path = list[list.length - 1].paths;
  181. // const angle = deviceInfo.attitude_head;// 角度
  182. // const startIcon = new AMap.Icon({
  183. // size: new AMap.Size(40, 40),
  184. // image: droneIcon,
  185. // imageSize: new AMap.Size(40, 40)
  186. // })
  187. // const endMarker = new AMap.Marker({
  188. // position: new AMap.LngLat(path[0], path[path.length - 1]),
  189. // icon: startIcon,
  190. // offset: new AMap.Pixel(-20, -20),// 位置偏移
  191. // angle: angle,// 旋转角度
  192. // })
  193. // other.push(endMarker);
  194. // }
  195. root.$map.add(other)
  196. coverMap[sn] = [other]
  197. }
  198. return {
  199. drawTrajectory,
  200. drawDynamicTrajectory
  201. }
  202. }