| | |
| | | import * as Cesium from 'cesium' |
| | | import { flyVisual } from '@/utils/cesium/mapUtil' |
| | | import _, { cloneDeep, throttle } from 'lodash' |
| | | import * as turf from '@turf/turf' |
| | | import '@/utils/drawPolygon/drawPolygon.css' |
| | |
| | | constructor() { |
| | | // Cesium 视图对象 |
| | | this.viewer = null |
| | | this.polygonHeight = 120 |
| | | // 当前绘制的多边形 |
| | | this.curPolygon = null |
| | | // 绘制模式标识 |
| | |
| | | this.polygonEntity = null |
| | | // 存储端点的 DataSource |
| | | this.editPolygonDataSource = null |
| | | this.editPolyhedronDataSource = null |
| | | this.editPolygonPointDataSource = null |
| | | // 鼠标事件处理器 |
| | | this.handler = null |
| | |
| | | DEFAULT_POLYGON: Cesium.Color.fromBytes(45, 140, 240, 99), // 默认面颜色 |
| | | DEFAULT_LINE: Cesium.Color.fromBytes(45, 140, 240, 255), // 默认边界线颜色 |
| | | ERROR_POLYGON: Cesium.Color.fromCssColorString('rgba(255, 0, 0, .3)'), // 错误(自交)面颜色 |
| | | ERROR_LINE: Cesium.Color.fromCssColorString('rgba(255, 0, 0, 1)') // 错误(自交)线颜色 |
| | | ERROR_LINE: Cesium.Color.fromCssColorString('rgba(255, 0, 0, 1)'), // 错误(自交)线颜色 |
| | | // 新增多变体(立体)颜色:橙色,透明度 0.3 |
| | | DEFAULT_POLYHEDRON: Cesium.Color.fromCssColorString('rgba(255, 165, 0, 0.3)') |
| | | }; |
| | | |
| | | // ============ 发布订阅机制 ============ |
| | |
| | | notify (key, data) { |
| | | this.listeners |
| | | .filter(subscriber => subscriber.key === key) |
| | | .forEach(subscriber => subscriber.listener(data)) |
| | | .forEach(subscriber => { |
| | | subscriber.listener(data) |
| | | }) |
| | | } |
| | | |
| | | setPolygonHeight (height) { |
| | | this.polygonHeight = height |
| | | } |
| | | |
| | | // ============ 绘制相关 ============ |
| | |
| | | this.viewer?.dataSources.add(this.editPolygonDataSource) |
| | | } |
| | | |
| | | if (!this.editPolyhedronDataSource) { |
| | | this.editPolyhedronDataSource = new Cesium.CustomDataSource('editPolyhedronDataSource') |
| | | this.viewer?.dataSources.add(this.editPolyhedronDataSource) |
| | | } |
| | | |
| | | if (!this.editPolygonPointDataSource) { |
| | | this.editPolygonPointDataSource = new Cesium.CustomDataSource('editPolygonPointDataSource') |
| | | this.viewer?.dataSources.add(this.editPolygonPointDataSource) |
| | |
| | | |
| | | // 清空之前的点 |
| | | this.editPolygonDataSource?.entities.removeAll() |
| | | this.editPolyhedronDataSource?.entities.removeAll() |
| | | this.editPolygonPointDataSource?.entities.removeAll() |
| | | } |
| | | |
| | |
| | | false |
| | | ) |
| | | }, |
| | | }) |
| | | |
| | | this.editPolyhedronDataSource.entities.add({ |
| | | polygon: { |
| | | hierarchy: new Cesium.CallbackProperty(() => this.curPolygon, false), |
| | | material: DrawPolygon.COLORS.DEFAULT_POLYHEDRON, |
| | | outline: false, |
| | | outlineWidth: 2, |
| | | height: 0, |
| | | extrudedHeight: new Cesium.CallbackProperty(() => { |
| | | let heights = this.curPolygon.positions.map(item => { |
| | | // 获取点的位置 |
| | | const cartographic = Cesium.Cartographic.fromCartesian(item) |
| | | // 获取地形高度 |
| | | const terrainHeight = this.viewer.scene.globe.getHeight(cartographic) || 0 |
| | | |
| | | |
| | | return terrainHeight |
| | | }) |
| | | |
| | | return Math.max(...heights) + Number(this.polygonHeight) |
| | | }, false), |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | this.editPolygonDataSource = null |
| | | } |
| | | |
| | | if (this.editPolyhedronDataSource) { |
| | | this.editPolyhedronDataSource.entities.removeAll() |
| | | this.editPolyhedronDataSource = null |
| | | } |
| | | |
| | | if (this.editPolygonPointDataSource) { |
| | | this.editPolygonPointDataSource.entities.removeAll() |
| | | this.editPolygonPointDataSource = null |
| | |
| | | this.initHandler(viewer) |
| | | this.startDrawing() |
| | | |
| | | positions.forEach(item => { |
| | | let disposePosition = positions.map(item => Cesium.Cartesian3.fromDegrees(Number(item.lng), Number(item.lat), Number(item.height))) |
| | | |
| | | disposePosition.forEach(item => { |
| | | this.addPosition( |
| | | Cesium.Cartesian3.fromDegrees(Number(item.lng), Number(item.lat), Number(item.height)), |
| | | item, |
| | | false |
| | | ) |
| | | }) |
| | | |
| | | this.notify('getPolygonPositions', disposePosition) |
| | | |
| | | // 视角飞入区域 |
| | | const newBox = boxTransformScale(positions.map(item => [item.lng, item.lat]), 5) |
| | | viewer.camera.flyTo({ |
| | | destination: Cesium.Rectangle.fromDegrees(...newBox), |
| | | offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90), 0), |
| | | duration: 0.5, |
| | | flyVisual({ |
| | | positionsData: positions.map(item => [item.lng, item.lat]), |
| | | viewer, |
| | | pitch: -60, |
| | | multiple: 6 |
| | | }) |
| | | |
| | | |
| | | this.drawingMode = false |
| | | this.editingMode = true |
| | |
| | | * 销毁实例,释放资源 |
| | | */ |
| | | destroy () { |
| | | this.prompt.destroy() |
| | | if (!this.viewer) return |
| | | |
| | | this.removeMenuPopup() |