You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.9 KiB
155 lines
4.9 KiB
import { message, notification } from 'ant-design-vue' |
|
import { MapDoodleEnum } from '/@/types/map-enum' |
|
import { getRoot } from '/@/root' |
|
import { PostFlightAreaBody, saveFlightArea } from '/@/api/flight-area' |
|
import { generateCircleContent, generatePolyContent } from '/@/utils/map-layer-utils' |
|
import { GeojsonCoordinate } from '/@/utils/genjson' |
|
import { gcj02towgs84, wgs84togcj02 } from '/@/vendors/coordtransform.js' |
|
import { uuidv4 } from '/@/utils/uuid' |
|
import { CommonHostWs } from '/@/websocket' |
|
import { FlightAreasDroneLocation } from '/@/types/flight-area' |
|
import rootStore from '/@/store' |
|
import { h } from 'vue' |
|
import { useGMapCover } from '/@/hooks/use-g-map-cover' |
|
import moment from 'moment' |
|
import { DATE_FORMAT } from '/@/utils/constants' |
|
|
|
export function useFlightArea () { |
|
const root = getRoot() |
|
const store = rootStore |
|
const coverMap = store.state.coverMap |
|
|
|
let useGMapCoverHook = useGMapCover() |
|
|
|
const MIN_RADIUS = 10 |
|
function checkCircle (obj: any): boolean { |
|
if (obj.getRadius() < MIN_RADIUS) { |
|
message.error(`The radius must be greater than ${MIN_RADIUS}m.`) |
|
root.$map.remove(obj) |
|
return false |
|
} |
|
return true |
|
} |
|
|
|
function checkPolygon (obj: any): boolean { |
|
const path: any[][] = obj.getPath() |
|
if (path.length < 3) { |
|
message.error('The path of the polygon cannot be crossed.') |
|
root.$map.remove(obj) |
|
return false |
|
} |
|
// root.$aMap.GeometryUtil.doesLineLineIntersect() |
|
return true |
|
} |
|
|
|
function setExtData (obj: any) { |
|
let ext = obj.getExtData() |
|
const id = uuidv4() |
|
const name = `${ext.type}-${moment().format(DATE_FORMAT)}` |
|
ext = Object.assign({}, ext, { id, name }) |
|
obj.setExtData(ext) |
|
return ext |
|
} |
|
function createFlightArea (obj: any) { |
|
const ext = obj.getExtData() |
|
const data = { |
|
id: ext.id, |
|
type: ext.type, |
|
name: ext.name, |
|
} |
|
let coordinates: GeojsonCoordinate | GeojsonCoordinate[][] |
|
let content |
|
switch (ext.mapType) { |
|
case 'circle': |
|
content = generateCircleContent(obj.getCenter(), obj.getRadius()) |
|
coordinates = getWgs84(content.geometry.coordinates as GeojsonCoordinate) |
|
break |
|
case 'polygon': |
|
content = generatePolyContent(obj.getPath()).content |
|
coordinates = [getWgs84(content.geometry.coordinates[0] as GeojsonCoordinate[])] |
|
break |
|
default: |
|
message.error(`Invalid type: ${obj.mapType}`) |
|
root.$map.remove(obj) |
|
return |
|
} |
|
content.geometry.coordinates = coordinates |
|
|
|
saveFlightArea(Object.assign({}, data, { content }) as PostFlightAreaBody).then(res => { |
|
if (res.code !== 0) { |
|
useGMapCoverHook.removeCoverFromMap(ext.id) |
|
} |
|
}).finally(() => root.$map.remove(obj)) |
|
} |
|
|
|
function getDrawFlightAreaCallback (obj: any) { |
|
useGMapCoverHook = useGMapCover() |
|
const ext = setExtData(obj) |
|
switch (ext.mapType) { |
|
case MapDoodleEnum.CIRCLE: |
|
if (!checkCircle(obj)) { |
|
return |
|
} |
|
break |
|
case MapDoodleEnum.POLYGON: |
|
if (!checkPolygon(obj)) { |
|
return |
|
} |
|
break |
|
default: |
|
break |
|
} |
|
createFlightArea(obj) |
|
} |
|
|
|
const getWgs84 = <T extends GeojsonCoordinate | GeojsonCoordinate[]>(coordinate: T): T => { |
|
if (coordinate[0] instanceof Array) { |
|
return (coordinate as GeojsonCoordinate[]).map(c => gcj02towgs84(c[0], c[1])) as T |
|
} |
|
return gcj02towgs84(coordinate[0], coordinate[1]) |
|
} |
|
|
|
const getGcj02 = <T extends GeojsonCoordinate | GeojsonCoordinate[]>(coordinate: T): T => { |
|
if (coordinate[0] instanceof Array) { |
|
return (coordinate as GeojsonCoordinate[]).map(c => wgs84togcj02(c[0], c[1])) as T |
|
} |
|
return wgs84togcj02(coordinate[0], coordinate[1]) |
|
} |
|
|
|
const onFlightAreaDroneLocationWs = (data: CommonHostWs<FlightAreasDroneLocation>) => { |
|
const nearArea = data.host.drone_locations.filter(val => !val.is_in_area) |
|
const inArea = data.host.drone_locations.filter(val => val.is_in_area) |
|
notification.warning({ |
|
key: `flight-area-${data.sn}`, |
|
message: `Drone(${data.sn}) flight area information`, |
|
description: h('div', |
|
[ |
|
h('div', [ |
|
h('span', { class: 'fz18' }, 'In the flight area: '), |
|
h('ul', [ |
|
...inArea.map(val => h('li', `There are ${val.area_distance} meters from the edge of the area(${coverMap[val.area_id][1]?.getText() || val.area_id}).`)) |
|
]) |
|
]), |
|
h('div', [ |
|
h('span', { class: 'fz18' }, 'Near the flight area: '), |
|
h('ul', [ |
|
...nearArea.map(val => h('li', `There are ${val.area_distance} meters from the edge of the area(${coverMap[val.area_id][1]?.getText() || val.area_id}).`)) |
|
]) |
|
]) |
|
]), |
|
duration: null, |
|
style: { |
|
width: '420px', |
|
marginTop: '-8px', |
|
marginLeft: '-28px', |
|
} |
|
}) |
|
} |
|
|
|
return { |
|
getDrawFlightAreaCallback, |
|
getGcj02, |
|
getWgs84, |
|
onFlightAreaDroneLocationWs, |
|
} |
|
}
|
|
|