use-g-map-cover.ts 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import { EFlightAreaType } from '../types/flight-area'
  2. import pin19be6b from '/@/assets/icons/pin-19be6b.svg'
  3. import pin212121 from '/@/assets/icons/pin-212121.svg'
  4. import pin2d8cf0 from '/@/assets/icons/pin-2d8cf0.svg'
  5. import pinb620e0 from '/@/assets/icons/pin-b620e0.svg'
  6. import pine23c39 from '/@/assets/icons/pin-e23c39.svg'
  7. import pineffbb00 from '/@/assets/icons/pin-ffbb00.svg'
  8. import { getRoot } from '/@/root'
  9. import rootStore from '/@/store'
  10. import { GeojsonCoordinate } from '/@/types/map'
  11. export function useGMapCover() {
  12. const root = getRoot()
  13. const AMap = root.$aMap
  14. const normalColor = '#2D8CF0'
  15. const store = rootStore
  16. const coverMap = store.state.coverMap
  17. const flightAreaColorMap = {
  18. [EFlightAreaType.DFENCE]: '#19be6b',
  19. [EFlightAreaType.NFZ]: '#ff0000',
  20. }
  21. const disableColor = '#b3b3b3'
  22. function AddCoverToMap(cover: any) {
  23. root.$map.add(cover)
  24. coverMap[cover.getExtData().id] = [cover]
  25. }
  26. function getPinIcon(color?: string) {
  27. const colorObj: {
  28. [key: number | string]: any
  29. } = {
  30. '2d8cf0': pin2d8cf0,
  31. '19be6b': pin19be6b,
  32. 212121: pin212121,
  33. b620e0: pinb620e0,
  34. e23c39: pine23c39,
  35. ffbb00: pineffbb00,
  36. }
  37. const iconName = (color?.replaceAll('#', '') || '').toLocaleLowerCase()
  38. return new AMap.Icon({
  39. image: colorObj[iconName],
  40. })
  41. }
  42. function init2DPin(name: string, coordinates: GeojsonCoordinate, color?: string, data?: {}) {
  43. const marker = new AMap.Marker({
  44. position: new AMap.LngLat(coordinates[0], coordinates[1]),
  45. title: name,
  46. icon: getPinIcon(color),
  47. extData: data
  48. })
  49. const text = new AMap.Text({
  50. position: new AMap.LngLat(coordinates[0], coordinates[1]),
  51. offset: new AMap.Pixel(-30, -30),
  52. text: name,
  53. style: {
  54. fontSize: 12,
  55. padding: 0,
  56. backgroundColor: 'transparent',
  57. borderColor: 'transparent',
  58. },
  59. extData: {
  60. ...data,
  61. id: data.id + '_text',
  62. },
  63. })
  64. AddCoverToMap(text)
  65. marker.on('click', function (e: any) {
  66. const options = marker.getOptions()
  67. const id = options.extData.id;
  68. store.commit('SET_MAP_CLICK_ID', id);
  69. })
  70. AddCoverToMap(marker)
  71. }
  72. function initPolyline(name: string, coordinates: GeojsonCoordinate[], color?: string, data?: {}) {
  73. const path = [] as GeojsonCoordinate[]
  74. coordinates.forEach(coordinate => {
  75. path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
  76. })
  77. const polyline = new AMap.Polyline({
  78. path: path,
  79. strokeColor: color || normalColor,
  80. strokeOpacity: 1,
  81. strokeWeight: 2,
  82. strokeStyle: 'solid',
  83. extData: data
  84. })
  85. const coordinatesList = coordinates[0];
  86. const text = new AMap.Text({
  87. position: new AMap.LngLat(coordinatesList[0], coordinatesList[1]),
  88. offset: new AMap.Pixel(-30, -30),
  89. text: name,
  90. style: {
  91. fontSize: 12,
  92. padding: 0,
  93. backgroundColor: 'transparent',
  94. borderColor: 'transparent',
  95. },
  96. extData: {
  97. ...data,
  98. id: data.id + '_text',
  99. },
  100. })
  101. AddCoverToMap(text)
  102. polyline.on('click', function () {
  103. const options = polyline.getOptions()
  104. const id = options.extData.id;
  105. store.commit('SET_MAP_CLICK_ID', id);
  106. })
  107. AddOverlayGroup(polyline)
  108. }
  109. function initPolygon(name: string, coordinates: GeojsonCoordinate[][], color?: string, data?: {}) {
  110. const path = [] as GeojsonCoordinate[]
  111. coordinates[0].forEach(coordinate => {
  112. path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
  113. })
  114. const polygon = new AMap.Polygon({
  115. path: path,
  116. strokeOpacity: 1,
  117. strokeWeight: 2,
  118. fillColor: color || normalColor,
  119. fillOpacity: 0.4,
  120. strokeColor: color || normalColor,
  121. extData: data
  122. })
  123. const coordinatesList = coordinates[0][0];
  124. const text = new AMap.Text({
  125. position: new AMap.LngLat(coordinatesList[0], coordinatesList[1]),
  126. offset: new AMap.Pixel(-30, -30),
  127. text: name,
  128. style: {
  129. fontSize: 12,
  130. padding: 0,
  131. backgroundColor: 'transparent',
  132. borderColor: 'transparent',
  133. },
  134. extData: {
  135. ...data,
  136. id: data.id + '_text',
  137. },
  138. })
  139. AddCoverToMap(text)
  140. polygon.on('click', function () {
  141. const options = polygon.getOptions()
  142. const id = options.extData.id;
  143. store.commit('SET_MAP_CLICK_ID', id);
  144. })
  145. AddOverlayGroup(polygon)
  146. }
  147. function AddOverlayGroup(overlayGroup: any) {
  148. root.$map.add(overlayGroup)
  149. const id = overlayGroup.getExtData().id
  150. coverMap[id] = [...(coverMap[id] || []), overlayGroup]
  151. }
  152. function removeCoverFromMap(id: string) {
  153. coverMap[id].forEach(cover => root.$map.remove(cover))
  154. coverMap[id] = []
  155. }
  156. function getElementFromMap(id: string): any[] {
  157. return coverMap[id]
  158. }
  159. function updatePinElement(id: string, name: string, coordinates: GeojsonCoordinate, color?: string) {
  160. init2DPin(name, coordinates, color, {
  161. id: id,
  162. name: name
  163. })
  164. }
  165. function updatePolylineElement(id: string, name: string, coordinates: GeojsonCoordinate[], color?: string) {
  166. initPolyline(name, coordinates, color, {
  167. id: id,
  168. name: name
  169. })
  170. }
  171. function updatePolygonElement(id: string, name: string, coordinates: GeojsonCoordinate[][], color?: string) {
  172. initPolygon(name, coordinates, color, {
  173. id: id,
  174. name: name
  175. })
  176. }
  177. function initTextInfo(content: string, coordinates: GeojsonCoordinate, id: string) {
  178. const info = new AMap.Text({
  179. text: content,
  180. position: new AMap.LngLat(coordinates[0], coordinates[1]),
  181. extData: { id: id, type: 'text' },
  182. anchor: 'top-center',
  183. style: {
  184. background: 'none',
  185. borderStyle: 'none',
  186. fontSize: '16px',
  187. },
  188. })
  189. AddOverlayGroup(info)
  190. }
  191. function initFlightAreaCircle(name: string, radius: number, position: GeojsonCoordinate, data: { id: string, type: EFlightAreaType, enable: boolean }) {
  192. const circle = new AMap.Circle({
  193. strokeColor: data.enable ? flightAreaColorMap[data.type] : disableColor,
  194. strokeOpacity: 1,
  195. strokeWeight: 6,
  196. extData: data,
  197. strokeStyle: 'dashed',
  198. strokeDasharray: EFlightAreaType.NFZ === data.type ? [10, 2] : [10, 1, 2],
  199. fillColor: flightAreaColorMap[data.type],
  200. fillOpacity: EFlightAreaType.NFZ === data.type && data.enable ? 0.3 : 0,
  201. radius: radius,
  202. center: new AMap.LngLat(position[0], position[1]),
  203. })
  204. AddOverlayGroup(circle)
  205. initTextInfo(name, position, data.id)
  206. }
  207. function updateFlightAreaCircle(id: string, name: string, radius: number, position: GeojsonCoordinate, enable: boolean, type: EFlightAreaType) {
  208. const elements = getElementFromMap(id)
  209. if (elements && elements.length > 0) {
  210. let textIndex = elements.findIndex(ele => ele.getExtData()?.type === 'text')
  211. if (textIndex === -1) {
  212. textIndex = 1
  213. initTextInfo(name, position, id)
  214. } else {
  215. const text = elements[textIndex]
  216. text.setText(name)
  217. text.setPosition(position)
  218. }
  219. const element = elements[textIndex ^ 1]
  220. const options = element.getOptions()
  221. options.fillOpacity = EFlightAreaType.NFZ === type && enable ? 0.3 : 0
  222. options.strokeColor = enable ? flightAreaColorMap[type] : disableColor
  223. options.radius = radius
  224. options.center = new AMap.LngLat(position[0], position[1])
  225. element.setOptions(options)
  226. } else {
  227. initFlightAreaCircle(name, radius, position, { id, type, enable })
  228. }
  229. }
  230. function calcPolygonPosition(coordinate: GeojsonCoordinate[]): GeojsonCoordinate {
  231. const index = coordinate.length - 1
  232. return [(coordinate[0][0] + coordinate[index][0]) / 2.0, (coordinate[0][1] + coordinate[index][1]) / 2]
  233. }
  234. function initFlightAreaPolygon(name: string, coordinates: GeojsonCoordinate[], data: { id: string, type: EFlightAreaType, enable: boolean }) {
  235. const path = [] as GeojsonCoordinate[]
  236. coordinates.forEach(coordinate => {
  237. path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
  238. })
  239. const polygon = new AMap.Polygon({
  240. path: path,
  241. strokeColor: data.enable ? flightAreaColorMap[data.type] : disableColor,
  242. strokeOpacity: 1,
  243. strokeWeight: 4,
  244. draggable: true,
  245. extData: data,
  246. strokeStyle: 'dashed',
  247. strokeDasharray: EFlightAreaType.NFZ === data.type ? [10, 2] : [10, 1, 2],
  248. fillColor: flightAreaColorMap[data.type],
  249. fillOpacity: EFlightAreaType.NFZ === data.type && data.enable ? 0.3 : 0,
  250. })
  251. AddOverlayGroup(polygon)
  252. initTextInfo(name, calcPolygonPosition(coordinates), data.id)
  253. }
  254. function updateFlightAreaPolygon(id: string, name: string, coordinates: GeojsonCoordinate[], enable: boolean, type: EFlightAreaType) {
  255. const elements = getElementFromMap(id)
  256. if (elements && elements.length > 0) {
  257. let textIndex = elements.findIndex(ele => ele.getExtData()?.type === 'text')
  258. if (textIndex === -1) {
  259. textIndex = 1
  260. initTextInfo(name, calcPolygonPosition(coordinates), id)
  261. } else {
  262. const text = elements[textIndex]
  263. text.setText(name)
  264. text.setPosition(calcPolygonPosition(coordinates))
  265. }
  266. const element = elements[textIndex ^ 1]
  267. const options = element.getOptions()
  268. const path = [] as GeojsonCoordinate[]
  269. coordinates.forEach(coordinate => {
  270. path.push(new AMap.LngLat(coordinate[0], coordinate[1]))
  271. })
  272. options.path = path
  273. options.fillOpacity = EFlightAreaType.NFZ === type && enable ? 0.3 : 0
  274. options.strokeColor = enable ? flightAreaColorMap[type] : disableColor
  275. element.setOptions(options)
  276. } else {
  277. initFlightAreaPolygon(name, coordinates, { id, type, enable })
  278. }
  279. }
  280. return {
  281. init2DPin,
  282. initPolyline,
  283. initPolygon,
  284. removeCoverFromMap,
  285. getElementFromMap,
  286. updatePinElement,
  287. updatePolylineElement,
  288. updatePolygonElement,
  289. initFlightAreaCircle,
  290. initFlightAreaPolygon,
  291. updateFlightAreaPolygon,
  292. updateFlightAreaCircle,
  293. calcPolygonPosition,
  294. }
  295. }