| | |
| | | } |
| | | const showTypePanel = ref(false) |
| | | const suppressTypePanelOnce = ref(false) |
| | | const areaTypeStyleMap = { |
| | | '1': { |
| | | fill: Cesium.Color.fromBytes(25, 178, 230, 128), |
| | | outline: Cesium.Color.fromBytes(0, 251, 255, 255), |
| | | }, |
| | | '2': { |
| | | fill: Cesium.Color.fromBytes(255, 235, 59, 128), |
| | | outline: Cesium.Color.fromBytes(255, 235, 59, 255), |
| | | }, |
| | | '3': { |
| | | fill: Cesium.Color.fromBytes(247, 20, 20, 128), |
| | | outline: Cesium.Color.fromBytes(255, 0, 0, 255), |
| | | }, |
| | | } |
| | | let viewer |
| | | let drawManager |
| | | let editManager |
| | |
| | | ) |
| | | } |
| | | |
| | | function getAreaTypeStyle (areaType) { |
| | | return areaTypeStyleMap?.[String(areaType)] || { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | } |
| | | |
| | | function renderShapeList () { |
| | | if (!viewer || !visible.value || readonly.value) { |
| | | clearShapeDisplay() |
| | |
| | | |
| | | const positions = buildShapePositions(shape.points) |
| | | if (positions.length < 3) return |
| | | const style = getAreaTypeStyle(shape.areaType) |
| | | dataSource.entities.add({ |
| | | name: 'shape-display', |
| | | customData: { shapeId: shape.id, drawType: shape.drawType }, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(positions), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: style.fill, |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | |
| | | positions: positions.length ? [...positions, positions[0]] : positions, |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | material: style.outline, |
| | | }, |
| | | }) |
| | | }) |
| | |
| | | }) |
| | | applyPolygonMetrics(pointList) |
| | | if (!formData.value.areaType) { |
| | | const alarmAreaType = getAlarmAreaTypeKey() |
| | | if (alarmAreaType) { |
| | | formData.value.areaType = alarmAreaType |
| | | const detectAreaType = getDetectAreaTypeKey() |
| | | if (detectAreaType) { |
| | | formData.value.areaType = detectAreaType |
| | | } |
| | | } |
| | | if (!suppressTypePanelOnce.value) { |
| | |
| | | formData.value.latitude = center.geometry.coordinates[1] |
| | | } |
| | | |
| | | function getAlarmAreaTypeKey () { |
| | | function getDetectAreaTypeKey () { |
| | | const areaTypeOptions = Array.isArray(dictObj?.value?.areaType) |
| | | ? dictObj.value.areaType |
| | | : dictObj?.areaType |
| | | if (!Array.isArray(areaTypeOptions)) return '' |
| | | const target = areaTypeOptions.find(item => item?.dictValue === '报警区') |
| | | const target = areaTypeOptions.find(item => item?.dictKey === '1') |
| | | return target?.dictKey ?? '' |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | function updateActiveShapeAreaType (value) { |
| | | if (currentShapeType.value !== 'buffer') { |
| | | activeTool?.setStyle?.(getAreaTypeStyle(value)) |
| | | } |
| | | if (!activeShapeId.value) return |
| | | const targetIndex = shapeList.value.findIndex(item => item.id === activeShapeId.value) |
| | | if (targetIndex === -1) return |
| | |
| | | ...target, |
| | | areaType: value, |
| | | }) |
| | | renderShapeList() |
| | | } |
| | | |
| | | // Tool lifecycle |
| | |
| | | currentShapeType.value = type |
| | | activeToolMode.value = 'draw' |
| | | drawManager ||= new DrawManager(viewer) |
| | | activeTool = drawManager.start(type) |
| | | activeTool = drawManager.start(type, { style: getAreaTypeStyle(formData.value.areaType) }) |
| | | activeTool?.subscribe('getPolygonPositions', drawFinished) |
| | | } |
| | | |
| | |
| | | currentShapeType.value = type |
| | | activeToolMode.value = 'edit' |
| | | editManager ||= new EditManager(viewer) |
| | | activeTool = editManager.start(type, points) |
| | | activeTool = editManager.start(type, points, { style: getAreaTypeStyle(formData.value.areaType) }) |
| | | activeTool?.subscribe('getPolygonPositions', drawFinished) |
| | | } |
| | | |
| | |
| | | activeShapeId.value = activeShapeId.value || (shapeList.value[0]?.id ?? null) |
| | | startEdit(type, editPoints) |
| | | return |
| | | } |
| | | const defaultAreaType = getDetectAreaTypeKey() |
| | | if (defaultAreaType) { |
| | | formData.value.areaType = defaultAreaType |
| | | } |
| | | activeShapeId.value = null |
| | | startDraw(type) |
| | |
| | | if (activeToolMode.value === 'edit' && activeShapeId.value === row.id) return |
| | | activeShapeId.value = row.id |
| | | currentShapeType.value = row.drawType |
| | | formData.value.areaType = row.areaType |
| | | pointList = _.cloneDeep(row.points) |
| | | clearActiveTool() |
| | | const editPayload = row.drawType === 'buffer' ? { points: row.points, meta: row.meta } : row.points |
| | |
| | | import { ToolBase } from '../ToolBase' |
| | | import { buildEllipsePositions } from '../shapeUtils' |
| | | |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | export class DrawEllipseTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.semiMinor = 0 |
| | | this.isDrawing = false |
| | | this.drawStep = 0 |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start() { |
| | |
| | | ellipse: { |
| | | semiMajorAxis: new Cesium.CallbackProperty(() => this.semiMajor, false), |
| | | semiMinorAxis: new Cesium.CallbackProperty(() => this.semiMinor, false), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: true, |
| | | outlineColor: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | outlineColor: this.style.outline, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | |
| | | return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid) |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.ellipseEntity?.ellipse) { |
| | | this.ellipseEntity.ellipse.material = this.style.fill |
| | | this.ellipseEntity.ellipse.outlineColor = this.style.outline |
| | | } |
| | | } |
| | | |
| | | destroy() { |
| | | if (this.dataSource) { |
| | | this.dataSource.entities.removeAll() |
| | |
| | | import { ToolBase } from '../ToolBase' |
| | | |
| | | const POINT_ENTITY_NAME = 'draw-polygon-point' |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | export class DrawPolygonTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.floatPosition = null |
| | | this.isDrawing = false |
| | | this.lastMousePosition = null |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start() { |
| | |
| | | () => new Cesium.PolygonHierarchy(getPreviewPositions()), |
| | | false |
| | | ), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | show: new Cesium.CallbackProperty(() => getPreviewPositions().length >= 3, false), |
| | |
| | | }, false), |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | material: this.style.outline, |
| | | show: new Cesium.CallbackProperty(() => getPreviewPositions().length >= 2, false), |
| | | }, |
| | | }) |
| | |
| | | point: { |
| | | pixelSize: 12, |
| | | color: Cesium.Color.WHITE, |
| | | outlineColor: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | outlineColor: this.style.outline, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | |
| | | this.clearPreviewEntities() |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.polygonEntity?.polygon) { |
| | | this.polygonEntity.polygon.material = this.style.fill |
| | | } |
| | | if (this.polylineEntity?.polyline) { |
| | | this.polylineEntity.polyline.material = this.style.outline |
| | | } |
| | | if (this.dataSource) { |
| | | this.dataSource.entities.values |
| | | .filter(entity => entity?.name === POINT_ENTITY_NAME) |
| | | .forEach(entity => { |
| | | if (entity?.point) { |
| | | entity.point.outlineColor = this.style.outline |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | clearPreviewEntities() { |
| | | if (!this.dataSource) return |
| | | this.dataSource.entities.removeAll() |
| | |
| | | import { ToolBase } from '../ToolBase' |
| | | import { getBoundsFromCartesians, rectanglePositionsFromBounds } from '../shapeUtils' |
| | | |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | export class DrawRectangleTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.startPosition = null |
| | | this.endPosition = null |
| | | this.isDrawing = false |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start() { |
| | |
| | | this.rectangleEntity = this.dataSource.entities.add({ |
| | | polygon: { |
| | | hierarchy, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | |
| | | }, false), |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | material: this.style.outline, |
| | | }, |
| | | }) |
| | | } |
| | |
| | | return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid) |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.rectangleEntity?.polygon) { |
| | | this.rectangleEntity.polygon.material = this.style.fill |
| | | } |
| | | if (this.outlineEntity?.polyline) { |
| | | this.outlineEntity.polyline.material = this.style.outline |
| | | } |
| | | } |
| | | |
| | | destroy() { |
| | | if (this.dataSource) { |
| | | this.dataSource.entities.removeAll() |
| | |
| | | cartesianToLocal, |
| | | } from '../shapeUtils' |
| | | |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | const normalizePoints = points => |
| | | (points || []).map(point => ({ |
| | | lng: point.lng ?? point.longitude, |
| | |
| | | })) |
| | | |
| | | export class EditEllipseTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.majorEntity = null |
| | | this.minorEntity = null |
| | | this.ellipseEntity = null |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start(points = []) { |
| | |
| | | ellipse: { |
| | | semiMajorAxis: new Cesium.CallbackProperty(() => this.semiMajor, false), |
| | | semiMinorAxis: new Cesium.CallbackProperty(() => this.semiMinor, false), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: true, |
| | | outlineColor: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | outlineColor: this.style.outline, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | |
| | | return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid) |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.ellipseEntity?.ellipse) { |
| | | this.ellipseEntity.ellipse.material = this.style.fill |
| | | this.ellipseEntity.ellipse.outlineColor = this.style.outline |
| | | } |
| | | } |
| | | |
| | | disableMapControl() { |
| | | const controller = this.viewer.scene.screenSpaceCameraController |
| | | controller.enableRotate = false |
| | |
| | | import { ToolBase } from '../ToolBase' |
| | | |
| | | const POINT_ENTITY_NAME = 'edit-polygon-point' |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | const normalizePoints = points => |
| | | (points || []).map(point => ({ |
| | |
| | | })) |
| | | |
| | | export class EditPolygonTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.positions = [] |
| | | this.isDragging = false |
| | | this.draggedIndex = -1 |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start(points = []) { |
| | |
| | | () => new Cesium.PolygonHierarchy(this.positions), |
| | | false |
| | | ), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | show: new Cesium.CallbackProperty(() => this.positions.length >= 3, false), |
| | |
| | | }, false), |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | material: this.style.outline, |
| | | show: new Cesium.CallbackProperty(() => this.positions.length >= 2, false), |
| | | }, |
| | | }) |
| | |
| | | point: { |
| | | pixelSize: 12, |
| | | color: Cesium.Color.WHITE, |
| | | outlineColor: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | outlineColor: this.style.outline, |
| | | outlineWidth: 2, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | |
| | | return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid) |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.polygonEntity?.polygon) { |
| | | this.polygonEntity.polygon.material = this.style.fill |
| | | } |
| | | if (this.polylineEntity?.polyline) { |
| | | this.polylineEntity.polyline.material = this.style.outline |
| | | } |
| | | if (this.dataSource) { |
| | | this.dataSource.entities.values |
| | | .filter(entity => entity?.name === POINT_ENTITY_NAME) |
| | | .forEach(entity => { |
| | | if (entity?.point) { |
| | | entity.point.outlineColor = this.style.outline |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | disableMapControl() { |
| | | const controller = this.viewer.scene.screenSpaceCameraController |
| | | controller.enableRotate = false |
| | |
| | | import { ToolBase } from '../ToolBase' |
| | | import { getBoundsFromLngLats, rectanglePositionsFromBounds } from '../shapeUtils' |
| | | |
| | | const DEFAULT_STYLE = { |
| | | fill: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | } |
| | | const resolveStyle = style => ({ |
| | | fill: style?.fill || DEFAULT_STYLE.fill, |
| | | outline: style?.outline || DEFAULT_STYLE.outline, |
| | | }) |
| | | |
| | | const normalizePoints = points => |
| | | (points || []).map(point => ({ |
| | | lng: point.lng ?? point.longitude, |
| | |
| | | })) |
| | | |
| | | export class EditRectangleTool extends ToolBase { |
| | | constructor(viewer) { |
| | | constructor(viewer, options = {}) { |
| | | super(viewer) |
| | | this.tooltip = new MapTooltip(viewer) |
| | | this.dataSource = null |
| | |
| | | this.cornerEntities = [] |
| | | this.dragIndex = null |
| | | this.fixedCorner = null |
| | | this.style = resolveStyle(options?.style) |
| | | } |
| | | |
| | | start(points = []) { |
| | |
| | | this.rectangleEntity = this.dataSource.entities.add({ |
| | | polygon: { |
| | | hierarchy, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | material: this.style.fill, |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | |
| | | }, false), |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | material: this.style.outline, |
| | | }, |
| | | }) |
| | | this.createCorners() |
| | |
| | | return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid) |
| | | } |
| | | |
| | | setStyle(style) { |
| | | this.style = resolveStyle(style) |
| | | if (this.rectangleEntity?.polygon) { |
| | | this.rectangleEntity.polygon.material = this.style.fill |
| | | } |
| | | if (this.outlineEntity?.polyline) { |
| | | this.outlineEntity.polyline.material = this.style.outline |
| | | } |
| | | } |
| | | |
| | | disableMapControl() { |
| | | const controller = this.viewer.scene.screenSpaceCameraController |
| | | controller.enableRotate = false |