From ade03bc747e412bdb220f02b1040eb0c8c97d904 Mon Sep 17 00:00:00 2001 From: cbwu <504-wuchengbo@htsdfp.com> Date: Sat, 13 Apr 2024 11:03:29 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8B=86=E5=88=86=E5=87=A0?= =?UTF-8?q?=E4=BD=95=E5=AF=B9=E8=B1=A1=E7=B1=BB=E7=9A=84=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=B1=BB=E5=9E=8B=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc.json | 18 +- src/types/entityoptions.ts | 26 ++ src/utils/getAssets.ts | 22 +- src/utils/map/camera.ts | 40 +- src/utils/map/coordinate.ts | 100 ++--- src/utils/map/draw/drawPoint.ts | 100 ++--- src/utils/map/draw/drawPolyline.ts | 394 +++++++++--------- src/utils/map/draw/editGeometry.ts | 498 +++++++++++------------ src/utils/map/drawer.ts | 370 ++++++++--------- src/utils/map/geocomputation.ts | 326 +++++++-------- src/utils/map/geometry/baseGeometry.ts | 285 ++++++------- src/utils/map/geometry/billboard.ts | 72 ++-- src/utils/map/geometry/pointEntity.ts | 126 +++--- src/utils/map/geometry/polygonEntity.ts | 112 ++--- src/utils/map/geometry/polylineEntity.ts | 96 ++--- src/utils/map/sceneViewer.ts | 226 +++++----- 16 files changed, 1412 insertions(+), 1399 deletions(-) create mode 100644 src/types/entityoptions.ts diff --git a/.prettierrc.json b/.prettierrc.json index 10b1be6..e379141 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,9 +1,9 @@ -{ - "singleQuote": true, - "semi": false, - "bracketSpacing": true, - "htmlWhitespaceSensitivity": "ignore", - "endOfLine": "auto", - "trailingComma": "all", - "tabWidth": 2 -} +{ + "singleQuote": true, + "semi": false, + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "ignore", + "endOfLine": "lf", + "trailingComma": "all", + "tabWidth": 2 +} diff --git a/src/types/entityoptions.ts b/src/types/entityoptions.ts new file mode 100644 index 0000000..c27fc86 --- /dev/null +++ b/src/types/entityoptions.ts @@ -0,0 +1,26 @@ +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-04-13 10:36:06 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:56:26 + * @Description: + */ +import { Color, Cartesian2 } from 'cesium' +export interface EntityOptions { + id?: string + name?: string + show?: boolean + pixelSize?: number + outlineColor?: Color + color?: Color + fillColor?: Color + fill?: boolean + width?: number + outlineWidth?: number + text?: string + font?: string + pixelOffset?: Cartesian2 + image?: string + imageWidth?: number + imageHeight?: number +} diff --git a/src/utils/getAssets.ts b/src/utils/getAssets.ts index 4460007..ffecf2f 100644 --- a/src/utils/getAssets.ts +++ b/src/utils/getAssets.ts @@ -1,11 +1,11 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-04-10 11:21:35 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-10 11:29:01 - * @Description: 获取静态资源文件 - */ -// 获取地图assets静态资源 -export const getMapAssetsFile = (url: string) => { - return new URL(`../assets/map/${url}`, import.meta.url).href -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-04-10 11:21:35 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-10 11:29:01 + * @Description: 获取静态资源文件 + */ +// 获取地图assets静态资源 +export const getMapAssetsFile = (url: string) => { + return new URL(`../assets/map/${url}`, import.meta.url).href +} diff --git a/src/utils/map/camera.ts b/src/utils/map/camera.ts index bb7f44f..1517f2a 100644 --- a/src/utils/map/camera.ts +++ b/src/utils/map/camera.ts @@ -1,20 +1,20 @@ -// 场景相机相关操作 -import { Viewer, Cartesian3, Math } from 'cesium' -/** - * 将三维球定位到中国 - * @param viewer :Viewer对象 - */ -function flyToChina(viewer: Viewer) { - viewer.camera.flyTo({ - destination: Cartesian3.fromDegrees(103.84, 31.15, 10350000), - orientation: { - heading: Math.toRadians(0), - pitch: Math.toRadians(-90), - roll: Math.toRadians(0), - }, - complete: function callback() { - // 定位完成之后的回调函数 - }, - }) -} -export { flyToChina } +// 场景相机相关操作 +import { Viewer, Cartesian3, Math } from 'cesium' +/** + * 将三维球定位到中国 + * @param viewer :Viewer对象 + */ +function flyToChina(viewer: Viewer) { + viewer.camera.flyTo({ + destination: Cartesian3.fromDegrees(103.84, 31.15, 10350000), + orientation: { + heading: Math.toRadians(0), + pitch: Math.toRadians(-90), + roll: Math.toRadians(0), + }, + complete: function callback() { + // 定位完成之后的回调函数 + }, + }) +} +export { flyToChina } diff --git a/src/utils/map/coordinate.ts b/src/utils/map/coordinate.ts index 899a6b1..9e1a7cf 100644 --- a/src/utils/map/coordinate.ts +++ b/src/utils/map/coordinate.ts @@ -1,50 +1,50 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-22 09:11:54 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-01 09:21:17 - * @Description: 坐标系转化 - */ -import { Cartesian2, Viewer, Math, Cartographic, Cartesian3 } from 'cesium' - -/** - * 屏幕坐标转笛卡尔坐标 - * @param viewer - * @param windowPosition :屏幕二维坐标 - * @returns :笛卡尔坐标 - */ -function cartesian2ToCartesian3(viewer: Viewer, windowPosition: Cartesian2) { - const ray = viewer.camera.getPickRay(windowPosition) - if (ray != undefined) { - return viewer.scene.globe.pick(ray, viewer.scene) - } else return undefined -} -/** - * 屏幕坐标转地理坐标 - * @param viewer - * @param windowPosition :屏幕坐标 - * @returns :WGS84坐标 - */ -function cartesian2ToWGS84(viewer: Viewer, windowPosition: Cartesian2) { - const cartesian3 = cartesian2ToCartesian3(viewer, windowPosition) - if (cartesian3 != undefined) { - return cartesian3ToWGS84(cartesian3) - } else return [] -} -/** - * 笛卡尔坐标转WGS84坐标 - * @param pos 笛卡尔坐标 - * @returns 经纬度坐标 - */ -function cartesian3ToWGS84(pos: Cartesian3) { - if (pos) { - const cartographic = Cartographic.fromCartesian(pos) - const lon = Math.toDegrees(cartographic.longitude) // 经度 - const lat = Math.toDegrees(cartographic.latitude) // 纬度 - const alt = cartographic.height // 高度 - return [lon, lat, alt] - } - return [] -} - -export { cartesian2ToCartesian3, cartesian2ToWGS84, cartesian3ToWGS84 } +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-22 09:11:54 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:49:36 + * @Description: 坐标系转化 + */ +import { Cartesian2, Viewer, Math, Cartographic, Cartesian3 } from 'cesium' + +/** + * 屏幕坐标转笛卡尔坐标 + * @param viewer + * @param windowPosition :屏幕二维坐标 + * @returns :笛卡尔坐标 + */ +function cartesian2ToCartesian3(viewer: Viewer, windowPosition: Cartesian2) { + const ray = viewer.camera.getPickRay(windowPosition) + if (ray != undefined) { + return viewer.scene.globe.pick(ray, viewer.scene) + } else return undefined +} +/** + * 屏幕坐标转地理坐标 + * @param viewer + * @param windowPosition :屏幕坐标 + * @returns :WGS84坐标 + */ +function cartesian2ToWGS84(viewer: Viewer, windowPosition: Cartesian2) { + const cartesian3 = cartesian2ToCartesian3(viewer, windowPosition) + if (cartesian3 != undefined) { + return cartesian3ToWGS84(cartesian3) + } else return [] +} +/** + * 笛卡尔坐标转WGS84坐标 + * @param pos 笛卡尔坐标 + * @returns 经纬度坐标 + */ +function cartesian3ToWGS84(pos: Cartesian3) { + if (pos) { + const cartographic = Cartographic.fromCartesian(pos) + const lon = Math.toDegrees(cartographic.longitude) // 经度 + const lat = Math.toDegrees(cartographic.latitude) // 纬度 + const alt = cartographic.height // 高度 + return [lon, lat, alt] + } + return [] +} + +export { cartesian2ToCartesian3, cartesian2ToWGS84, cartesian3ToWGS84 } diff --git a/src/utils/map/draw/drawPoint.ts b/src/utils/map/draw/drawPoint.ts index 37ad10d..ea7b92b 100644 --- a/src/utils/map/draw/drawPoint.ts +++ b/src/utils/map/draw/drawPoint.ts @@ -1,50 +1,50 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-27 09:51:04 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-10 15:54:02 - * @Description: 绘制点类 - */ -import { - Viewer, - ScreenSpaceEventHandler, - Cartesian3, - Color, - ScreenSpaceEventType, - Entity, - DataSource, -} from 'cesium' -import { BillBoard } from '../geometry/billboard' -import { cartesian2ToCartesian3 } from '../coordinate' -export default class DrawPoint { - viewer: Viewer - handler: ScreenSpaceEventHandler - markerLayer: DataSource - constructor(viewer: Viewer) { - this.viewer = viewer - this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) - this.markerLayer = viewer.dataSources.getByName('Marker')[0] - } - //开始绘制 - public start() { - this.handler.setInputAction( - this.leftClickCallBack, - ScreenSpaceEventType.LEFT_CLICK, - ) - } - //结束绘制 - public end() { - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) - this.handler.destroy() - } - //左键Click事件 - private leftClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) - if (cartesian3) { - this.markerLayer.entities.add(new BillBoard(cartesian3)) - this.viewer.scene.requestRender() - } - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-27 09:51:04 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:46:43 + * @Description: 绘制点类 + */ +import { + Viewer, + ScreenSpaceEventHandler, + Cartesian3, + Color, + ScreenSpaceEventType, + Entity, + DataSource, +} from 'cesium' +import { BillBoard } from '../geometry/billboard' +import { cartesian2ToCartesian3 } from '../coordinate' +export default class DrawPoint { + viewer: Viewer + handler: ScreenSpaceEventHandler + markerLayer: DataSource + constructor(viewer: Viewer) { + this.viewer = viewer + this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) + this.markerLayer = viewer.dataSources.getByName('Marker')[0] + } + //开始绘制 + public start() { + this.handler.setInputAction( + this.leftClickCallBack, + ScreenSpaceEventType.LEFT_CLICK, + ) + } + //结束绘制 + public end() { + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) + this.handler.destroy() + } + //左键Click事件 + private leftClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) + if (cartesian3) { + this.markerLayer.entities.add(new BillBoard(cartesian3)) + this.viewer.scene.requestRender() + } + } +} diff --git a/src/utils/map/draw/drawPolyline.ts b/src/utils/map/draw/drawPolyline.ts index df931e7..c61d76f 100644 --- a/src/utils/map/draw/drawPolyline.ts +++ b/src/utils/map/draw/drawPolyline.ts @@ -1,197 +1,197 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-27 08:43:44 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 09:06:27 - * @Description: 绘制Polyline类 - */ -import { - Viewer, - ScreenSpaceEventHandler, - Cartesian3, - Color, - ScreenSpaceEventType, - Entity, - CallbackProperty, - PolylineDashMaterialProperty, -} from 'cesium' -import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' -// import { PointEntity, PolylineEntity } from '@/utils/map/geometry' -import { PolylineEntity } from '../geometry/polylineEntity' -import { PointEntity } from '@/utils/map/geometry/pointEntity' -import EditGeometry from '@/utils/map/draw/editGeometry' -type EntityOptions = { - id?: string - name?: string - show?: boolean - pixelSize?: number - color?: Color - fillColor?: Color - fill?: boolean - width?: number - outlineWidth?: number -} -export default class CreatePolyline { - viewer: Viewer - handler: ScreenSpaceEventHandler - polyline: PolylineEntity | null - dashLine: Entity | null - trackingLine: Entity | null - trackingLinePositions: Cartesian3[] = [] - controlPoints: Entity[] | null - modifyPoint: any = null - clickedGeometry: Entity | null = null - moveSelectedPoint: PointEntity | null = null - positions: Cartesian3[] = [] - bMove: boolean = false - bLongClick: boolean = false - clickTimeout: any - // layer: CustomDataSource - defaultStyle: EntityOptions = { - // id: 'Polyline' + String(PolylineEntity.id), - // name: 'Polyline' + String(PolylineEntity.id + 1), - show: true, - width: 2, - color: Color.GREEN, - } - constructor(viewer: Viewer, options?: EntityOptions) { - this.viewer = viewer - this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) - this.polyline = null - this.trackingLine = null - this.dashLine = null - - this.controlPoints = [] - this.defaultStyle = { ...this.defaultStyle, ...options } - } - // 开始绘制 - public start() { - // 左单击加点 - this.handler.setInputAction( - this.leftClickCallBack, - ScreenSpaceEventType.LEFT_CLICK, - ) - // 移动动态绘制 - this.handler.setInputAction( - this.moveCallBack, - ScreenSpaceEventType.MOUSE_MOVE, - ) - // 左双击结束 - this.handler.setInputAction( - this.leftDoubleClickCallBack, - ScreenSpaceEventType.LEFT_DOUBLE_CLICK, - ) - // 右击回退上一步 - this.handler.setInputAction( - this.rightClickCallBack, - ScreenSpaceEventType.RIGHT_CLICK, - ) - } - public end() { - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) - } - //左单击回调事件 - private leftClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - const pickedObject = this.viewer.scene.pick(event.position) - // console.log(pickedObject) - if (pickedObject) { - //点击同一位置,返回 - if ( - pickedObject.id.id === - this.polyline?.controlPointsID[this.positions.length - 1] - ) { - return - // console.log('********click the same point') - } - } - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) - if (cartesian3 != undefined) { - if (!this.polyline) { - this.polyline = new PolylineEntity(this.positions) - this.dashLine = this.createTrackingLine(this.positions) - this.viewer.entities.add(this.dashLine) - this.viewer.dataSources.add(this.polyline) - } - this.polyline.addPoint(cartesian3) - this.trackingLinePositions[0] = cartesian3 - this.bMove = true - - this.viewer.scene.requestRender() //刷新 - } - } - // 移动回调事件 - private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { - if (this.bMove) { - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) - if (cartesian3 != undefined) { - //更新追踪线坐标 - this.trackingLinePositions[1] = cartesian3 - if (!this.trackingLine) { - //创建追踪线对象 - this.trackingLine = this.createTrackingLine( - this.trackingLinePositions, - ) - this.viewer.entities.add(this.trackingLine) - } - } - this.viewer.scene.requestRender() //刷新 - } - } - // 左双击回调事件 - private leftDoubleClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - // 清除可能已经设置的单击定时器 - // clearTimeout(this.clickTimeout) - if (!this.polyline) return - console.log('**************************** double click') - this.bMove = false - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) - if (cartesian3 != undefined) { - // 移除追踪线 - if (!this.trackingLine) { - this.viewer.entities.remove(this.trackingLine!) - } - } - - this.clearEvent() - console.log('end:' + this.positions.length.toString()) - console.log(this.positions) - //结束绘制进入编辑模式 - this.polyline.removeControlPoints() - const editTool = new EditGeometry(this.viewer, this.polyline.geometry!) - editTool.start() - } - // 右击回调事件 - private rightClickCallBack = () => { - if (!this.controlPoints) return - if (this.controlPoints.length > 1) { - const lastPoint = this.positions.pop() - this.positions[this.positions.length - 1] = lastPoint! - this.viewer.entities.remove(this.controlPoints.pop() as Entity) - } - } - clearEvent() { - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) - this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) - } - //创建追踪线 - createTrackingLine(positions: Cartesian3[]) { - return new Entity({ - polyline: { - positions: new CallbackProperty(() => { - return positions - }, false), - width: 2, - material: new PolylineDashMaterialProperty({ - color: Color.GREEN, - dashLength: 15, //短划线长度 - }), - clampToGround: true, - }, - }) - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-27 08:43:44 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:46:58 + * @Description: 绘制Polyline类 + */ +import { + Viewer, + ScreenSpaceEventHandler, + Cartesian3, + Color, + ScreenSpaceEventType, + Entity, + CallbackProperty, + PolylineDashMaterialProperty, +} from 'cesium' +import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' +// import { PointEntity, PolylineEntity } from '@/utils/map/geometry' +import { PolylineEntity } from '../geometry/polylineEntity' +import { PointEntity } from '@/utils/map/geometry/pointEntity' +import EditGeometry from '@/utils/map/draw/editGeometry' +type EntityOptions = { + id?: string + name?: string + show?: boolean + pixelSize?: number + color?: Color + fillColor?: Color + fill?: boolean + width?: number + outlineWidth?: number +} +export default class CreatePolyline { + viewer: Viewer + handler: ScreenSpaceEventHandler + polyline: PolylineEntity | null + dashLine: Entity | null + trackingLine: Entity | null + trackingLinePositions: Cartesian3[] = [] + controlPoints: Entity[] | null + modifyPoint: any = null + clickedGeometry: Entity | null = null + moveSelectedPoint: PointEntity | null = null + positions: Cartesian3[] = [] + bMove: boolean = false + bLongClick: boolean = false + clickTimeout: any + // layer: CustomDataSource + defaultStyle: EntityOptions = { + // id: 'Polyline' + String(PolylineEntity.id), + // name: 'Polyline' + String(PolylineEntity.id + 1), + show: true, + width: 2, + color: Color.GREEN, + } + constructor(viewer: Viewer, options?: EntityOptions) { + this.viewer = viewer + this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) + this.polyline = null + this.trackingLine = null + this.dashLine = null + + this.controlPoints = [] + this.defaultStyle = { ...this.defaultStyle, ...options } + } + // 开始绘制 + public start() { + // 左单击加点 + this.handler.setInputAction( + this.leftClickCallBack, + ScreenSpaceEventType.LEFT_CLICK, + ) + // 移动动态绘制 + this.handler.setInputAction( + this.moveCallBack, + ScreenSpaceEventType.MOUSE_MOVE, + ) + // 左双击结束 + this.handler.setInputAction( + this.leftDoubleClickCallBack, + ScreenSpaceEventType.LEFT_DOUBLE_CLICK, + ) + // 右击回退上一步 + this.handler.setInputAction( + this.rightClickCallBack, + ScreenSpaceEventType.RIGHT_CLICK, + ) + } + public end() { + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) + } + //左单击回调事件 + private leftClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + const pickedObject = this.viewer.scene.pick(event.position) + // console.log(pickedObject) + if (pickedObject) { + //点击同一位置,返回 + if ( + pickedObject.id.id === + this.polyline?.controlPointsID[this.positions.length - 1] + ) { + return + // console.log('********click the same point') + } + } + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) + if (cartesian3 != undefined) { + if (!this.polyline) { + this.polyline = new PolylineEntity(this.positions) + this.dashLine = this.createTrackingLine(this.positions) + this.viewer.entities.add(this.dashLine) + this.viewer.dataSources.add(this.polyline) + } + this.polyline.addPoint(cartesian3) + this.trackingLinePositions[0] = cartesian3 + this.bMove = true + + this.viewer.scene.requestRender() //刷新 + } + } + // 移动回调事件 + private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { + if (this.bMove) { + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) + if (cartesian3 != undefined) { + //更新追踪线坐标 + this.trackingLinePositions[1] = cartesian3 + if (!this.trackingLine) { + //创建追踪线对象 + this.trackingLine = this.createTrackingLine( + this.trackingLinePositions, + ) + this.viewer.entities.add(this.trackingLine) + } + } + this.viewer.scene.requestRender() //刷新 + } + } + // 左双击回调事件 + private leftDoubleClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + // 清除可能已经设置的单击定时器 + // clearTimeout(this.clickTimeout) + if (!this.polyline) return + console.log('**************************** double click') + this.bMove = false + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) + if (cartesian3 != undefined) { + // 移除追踪线 + if (!this.trackingLine) { + this.viewer.entities.remove(this.trackingLine!) + } + } + + this.clearEvent() + console.log('end:' + this.positions.length.toString()) + console.log(this.positions) + //结束绘制进入编辑模式 + this.polyline.removeControlPoints() + const editTool = new EditGeometry(this.viewer, this.polyline.geometry!) + editTool.start() + } + // 右击回调事件 + private rightClickCallBack = () => { + if (!this.controlPoints) return + if (this.controlPoints.length > 1) { + const lastPoint = this.positions.pop() + this.positions[this.positions.length - 1] = lastPoint! + this.viewer.entities.remove(this.controlPoints.pop() as Entity) + } + } + clearEvent() { + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) + this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) + } + //创建追踪线 + createTrackingLine(positions: Cartesian3[]) { + return new Entity({ + polyline: { + positions: new CallbackProperty(() => { + return positions + }, false), + width: 2, + material: new PolylineDashMaterialProperty({ + color: Color.GREEN, + dashLength: 15, //短划线长度 + }), + clampToGround: true, + }, + }) + } +} diff --git a/src/utils/map/draw/editGeometry.ts b/src/utils/map/draw/editGeometry.ts index 1467e63..06cfb0b 100644 --- a/src/utils/map/draw/editGeometry.ts +++ b/src/utils/map/draw/editGeometry.ts @@ -1,249 +1,249 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-27 11:06:45 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-02 11:05:20 - * @Description: 编辑几何体类。操作逻辑 - */ -import { - Viewer, - ScreenSpaceEventHandler, - PointGraphics, - PolylineGraphics, - Cartesian3, - ConstantProperty, - ScreenSpaceEventType, - Entity, - ConstantPositionProperty, - defined, -} from 'cesium' -import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' -import { getClosestPoint, isOnLineSegment } from '@/utils/map/geocomputation' -import { PointEntity } from '@/utils/map/geometry/pointEntity' -export default class EditGeometry { - viewer: Viewer - editHandler: ScreenSpaceEventHandler - geometry: Entity //要编辑的几何对象 - oldPositions: Cartesian3[] = [] //存储未修改前的坐标 - positions: Cartesian3[] = [] //要编辑的几个对象坐标 - controlPointsID: string[] = [] - controlPoint: PointEntity | null = null - clickedGeometry: Entity | null = null - clickDownPosition: Cartesian3 | null = null - moveSelectedPoint: PointEntity | null = null - bDrag: boolean = false //拖动标识 - bLongClick: boolean = false //长按标识 - clickTimeout: any - - constructor(viewer: Viewer, editGeometry: Entity) { - this.viewer = viewer - this.editHandler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) - this.geometry = editGeometry - this.positions = editGeometry.polyline?.positions?.getValue( - this.viewer.clock.currentTime, - ) - this.oldPositions = this.positions - // 创建控制点 - this.positions.forEach((value, index) => { - this.createPoint(value, index) - }) - } - public start() { - this.editHandler.setInputAction( - this.leftDownClickCallBack, - ScreenSpaceEventType.LEFT_DOWN, - ) - this.editHandler.setInputAction( - this.moveCallBack, - ScreenSpaceEventType.MOUSE_MOVE, - ) - this.editHandler.setInputAction( - this.leftUpClickCallBack, - ScreenSpaceEventType.LEFT_UP, - ) - } - //左键点击回调 - private leftClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - const pickedObject = this.viewer.scene.pick(event.position) - // 点中控制点 - if ( - defined(pickedObject) && - defined(pickedObject.id) && - pickedObject.id.point instanceof PointGraphics - ) { - console.log('You clicked a point entity.') - this.controlPoint = pickedObject.id - console.log(this.controlPoint?.subId) - this.bDrag = true - this.forbidDrawWorld(true) - } - } - //左键按下回调 - private leftDownClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - // 清除可能已经设置的单击定时器 - clearTimeout(this.clickTimeout) - // 判断是不是长按 - this.clickTimeout = setTimeout(() => { - this.bLongClick = true - }, 100) - const pickedObject = this.viewer.scene.pick(event.position) - //点中实体对象 - if (defined(pickedObject) && defined(pickedObject.id)) { - // 记录点击的几何对象及位置 - this.clickedGeometry = pickedObject.id - this.clickDownPosition = this.viewer.scene.pickPosition(event.position) - // // 判断是否同一实体 - // if (this.geometry != pickedObject.id) { - // this.geometry = pickedObject.id - // if ( - // pickedObject instanceof PolylineGraphics && - // pickedObject.positions - // ) { - // this.oldPositions = this.geometry!.polyline!.positions?.getValue( - // this.viewer.clock.currentTime, - // ) - // } - // } - // 点中控制点 - if (pickedObject.id.point instanceof PointGraphics) { - console.log('You clicked a point entity.') - this.controlPoint = pickedObject.id - console.log(this.controlPoint?.subId) - this.bDrag = true - this.forbidDrawWorld(true) - } - } - } - //移动回调 - private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { - const pickedObject = this.viewer.scene.pick(event.endPosition) - // 悬停控制点放大 - if ( - pickedObject && - pickedObject.id && - pickedObject.id.point instanceof PointGraphics - ) { - if (pickedObject.id.point instanceof PointGraphics) { - if ( - this.moveSelectedPoint == null || - this.moveSelectedPoint.id !== pickedObject.id.id - ) { - this.moveSelectedPoint = pickedObject.id - this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( - this.moveSelectedPoint!.options.pixelSize! + 2, - ) - // console.log(this.moveSelectedPoint) - } - this.viewer.scene.requestRender() //刷新 - } - } else { - // 离开控制点恢复原始大小 - if (this.moveSelectedPoint) { - this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( - this.moveSelectedPoint!.options.pixelSize! - 2, - ) - this.moveSelectedPoint = null - this.viewer.scene.requestRender() //刷新 - } - } - - if (!this.controlPoint || !this.bDrag) return - console.log('************************left down') - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) - if (cartesian3) { - // 修改节点坐标 - this.modifyPoint(cartesian3, this.controlPoint.subId) - // this.geometry?.modifyPoint(cartesian3, this.controlPoint.subId) - this.viewer.scene.requestRender() //刷新 - } - } - //左键松开回调 - private leftUpClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - clearTimeout(this.clickTimeout) - // 单击添加点 - if ( - !this.bLongClick && - this.clickedGeometry?.polyline instanceof PolylineGraphics - ) { - console.log('点中线,加点') - this.addPoint() - } - this.bLongClick = false - this.bDrag = false - this.forbidDrawWorld(false) - } - // 左键双击回调 - private leftDoubleClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - // this.geometry. - } - // Viewer操作控制 - forbidDrawWorld(isForbid: boolean) { - this.viewer.scene.screenSpaceCameraController.enableRotate = !isForbid - this.viewer.scene.screenSpaceCameraController.enableTilt = !isForbid - this.viewer.scene.screenSpaceCameraController.enableTranslate = !isForbid - this.viewer.scene.screenSpaceCameraController.enableInputs = !isForbid - } - // 添加点 - addPoint() { - for (let i = 0; i < this.positions.length - 1; ++i) { - if ( - isOnLineSegment( - this.positions[i], - this.positions[i + 1], - this.clickDownPosition!, - ) - ) { - // 修改线坐标 - const pt = getClosestPoint( - this.positions[i], - this.positions[i + 1], - this.clickDownPosition!, - ) - this.positions.splice(i + 1, 0, pt) - // 新建控制点 - this.createPoint(pt, i + 1) - // 修改控制点的subid - for (let index = i + 2; index < this.controlPointsID.length; ++index) { - const point = this.geometry.entityCollection.getById( - this.controlPointsID[index], - ) as PointEntity - point!.subId = point!.subId + 1 - } - return - } - } - } - /** - * 修改某点的坐标 - * @param pos 修改点的坐标 - * @param index 修改点的位置 - */ - modifyPoint(pos: Cartesian3, index: number) { - // 修改线坐标 - this.positions.splice(index, 1, pos) - // 修改控制点坐标 - this.controlPoint!.position = new ConstantPositionProperty(pos) - } - /** - * 新加一个点 - * @param pos 点的坐标 - * @param index 插入的位置,0起步 - */ - createPoint(pos: Cartesian3, index: number) { - // if (this.geometry) { - const point = new PointEntity(pos) - point.parent = this.geometry - point.subId = index - this.geometry.entityCollection.add(point) - this.controlPointsID.splice(index, 0, point.id) - // } - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-27 11:06:45 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:47:09 + * @Description: 编辑几何体类。操作逻辑 + */ +import { + Viewer, + ScreenSpaceEventHandler, + PointGraphics, + PolylineGraphics, + Cartesian3, + ConstantProperty, + ScreenSpaceEventType, + Entity, + ConstantPositionProperty, + defined, +} from 'cesium' +import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' +import { getClosestPoint, isOnLineSegment } from '@/utils/map/geocomputation' +import { PointEntity } from '@/utils/map/geometry/pointEntity' +export default class EditGeometry { + viewer: Viewer + editHandler: ScreenSpaceEventHandler + geometry: Entity //要编辑的几何对象 + oldPositions: Cartesian3[] = [] //存储未修改前的坐标 + positions: Cartesian3[] = [] //要编辑的几个对象坐标 + controlPointsID: string[] = [] + controlPoint: PointEntity | null = null + clickedGeometry: Entity | null = null + clickDownPosition: Cartesian3 | null = null + moveSelectedPoint: PointEntity | null = null + bDrag: boolean = false //拖动标识 + bLongClick: boolean = false //长按标识 + clickTimeout: any + + constructor(viewer: Viewer, editGeometry: Entity) { + this.viewer = viewer + this.editHandler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) + this.geometry = editGeometry + this.positions = editGeometry.polyline?.positions?.getValue( + this.viewer.clock.currentTime, + ) + this.oldPositions = this.positions + // 创建控制点 + this.positions.forEach((value, index) => { + this.createPoint(value, index) + }) + } + public start() { + this.editHandler.setInputAction( + this.leftDownClickCallBack, + ScreenSpaceEventType.LEFT_DOWN, + ) + this.editHandler.setInputAction( + this.moveCallBack, + ScreenSpaceEventType.MOUSE_MOVE, + ) + this.editHandler.setInputAction( + this.leftUpClickCallBack, + ScreenSpaceEventType.LEFT_UP, + ) + } + //左键点击回调 + private leftClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + const pickedObject = this.viewer.scene.pick(event.position) + // 点中控制点 + if ( + defined(pickedObject) && + defined(pickedObject.id) && + pickedObject.id.point instanceof PointGraphics + ) { + console.log('You clicked a point entity.') + this.controlPoint = pickedObject.id + console.log(this.controlPoint?.subId) + this.bDrag = true + this.forbidDrawWorld(true) + } + } + //左键按下回调 + private leftDownClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + // 清除可能已经设置的单击定时器 + clearTimeout(this.clickTimeout) + // 判断是不是长按 + this.clickTimeout = setTimeout(() => { + this.bLongClick = true + }, 100) + const pickedObject = this.viewer.scene.pick(event.position) + //点中实体对象 + if (defined(pickedObject) && defined(pickedObject.id)) { + // 记录点击的几何对象及位置 + this.clickedGeometry = pickedObject.id + this.clickDownPosition = this.viewer.scene.pickPosition(event.position) + // // 判断是否同一实体 + // if (this.geometry != pickedObject.id) { + // this.geometry = pickedObject.id + // if ( + // pickedObject instanceof PolylineGraphics && + // pickedObject.positions + // ) { + // this.oldPositions = this.geometry!.polyline!.positions?.getValue( + // this.viewer.clock.currentTime, + // ) + // } + // } + // 点中控制点 + if (pickedObject.id.point instanceof PointGraphics) { + console.log('You clicked a point entity.') + this.controlPoint = pickedObject.id + console.log(this.controlPoint?.subId) + this.bDrag = true + this.forbidDrawWorld(true) + } + } + } + //移动回调 + private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { + const pickedObject = this.viewer.scene.pick(event.endPosition) + // 悬停控制点放大 + if ( + pickedObject && + pickedObject.id && + pickedObject.id.point instanceof PointGraphics + ) { + if (pickedObject.id.point instanceof PointGraphics) { + if ( + this.moveSelectedPoint == null || + this.moveSelectedPoint.id !== pickedObject.id.id + ) { + this.moveSelectedPoint = pickedObject.id + this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( + this.moveSelectedPoint!.options.pixelSize! + 2, + ) + // console.log(this.moveSelectedPoint) + } + this.viewer.scene.requestRender() //刷新 + } + } else { + // 离开控制点恢复原始大小 + if (this.moveSelectedPoint) { + this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( + this.moveSelectedPoint!.options.pixelSize! - 2, + ) + this.moveSelectedPoint = null + this.viewer.scene.requestRender() //刷新 + } + } + + if (!this.controlPoint || !this.bDrag) return + console.log('************************left down') + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) + if (cartesian3) { + // 修改节点坐标 + this.modifyPoint(cartesian3, this.controlPoint.subId) + // this.geometry?.modifyPoint(cartesian3, this.controlPoint.subId) + this.viewer.scene.requestRender() //刷新 + } + } + //左键松开回调 + private leftUpClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + clearTimeout(this.clickTimeout) + // 单击添加点 + if ( + !this.bLongClick && + this.clickedGeometry?.polyline instanceof PolylineGraphics + ) { + console.log('点中线,加点') + this.addPoint() + } + this.bLongClick = false + this.bDrag = false + this.forbidDrawWorld(false) + } + // 左键双击回调 + private leftDoubleClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + // this.geometry. + } + // Viewer操作控制 + forbidDrawWorld(isForbid: boolean) { + this.viewer.scene.screenSpaceCameraController.enableRotate = !isForbid + this.viewer.scene.screenSpaceCameraController.enableTilt = !isForbid + this.viewer.scene.screenSpaceCameraController.enableTranslate = !isForbid + this.viewer.scene.screenSpaceCameraController.enableInputs = !isForbid + } + // 添加点 + addPoint() { + for (let i = 0; i < this.positions.length - 1; ++i) { + if ( + isOnLineSegment( + this.positions[i], + this.positions[i + 1], + this.clickDownPosition!, + ) + ) { + // 修改线坐标 + const pt = getClosestPoint( + this.positions[i], + this.positions[i + 1], + this.clickDownPosition!, + ) + this.positions.splice(i + 1, 0, pt) + // 新建控制点 + this.createPoint(pt, i + 1) + // 修改控制点的subid + for (let index = i + 2; index < this.controlPointsID.length; ++index) { + const point = this.geometry.entityCollection.getById( + this.controlPointsID[index], + ) as PointEntity + point!.subId = point!.subId + 1 + } + return + } + } + } + /** + * 修改某点的坐标 + * @param pos 修改点的坐标 + * @param index 修改点的位置 + */ + modifyPoint(pos: Cartesian3, index: number) { + // 修改线坐标 + this.positions.splice(index, 1, pos) + // 修改控制点坐标 + this.controlPoint!.position = new ConstantPositionProperty(pos) + } + /** + * 新加一个点 + * @param pos 点的坐标 + * @param index 插入的位置,0起步 + */ + createPoint(pos: Cartesian3, index: number) { + // if (this.geometry) { + const point = new PointEntity(pos) + point.parent = this.geometry + point.subId = index + this.geometry.entityCollection.add(point) + this.controlPointsID.splice(index, 0, point.id) + // } + } +} diff --git a/src/utils/map/drawer.ts b/src/utils/map/drawer.ts index 9a73f82..d720755 100644 --- a/src/utils/map/drawer.ts +++ b/src/utils/map/drawer.ts @@ -1,185 +1,185 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-15 08:43:26 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 10:30:36 - * @FilePath: \GCSMap\src\utils\drawer.ts - * @Description: 矢量要素绘制工具类 - */ -import { - Viewer, - ScreenSpaceEventHandler, - ScreenSpaceEventType, - CustomDataSource, - Cartesian3, - CallbackProperty, - PolygonHierarchy, - Color, -} from 'cesium' -import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' -import { - PointEntity, - PolylineEntity, - PolygonEntity, -} from '@/utils/map/geometry' -class Drawer { - viewer: Viewer - type: string - handler: ScreenSpaceEventHandler - layer: CustomDataSource - polyline: PolylineEntity | null - polygon: PolygonEntity | null - positions: Cartesian3[] = [] - n_Points: number - bMove: boolean - clickTimeout: any - constructor(viewer: Viewer, type: string) { - this.viewer = viewer - this.type = type - this.handler = new ScreenSpaceEventHandler(this.viewer.canvas) - this.polyline = null - this.polygon = null - this.n_Points = 0 - this.bMove = false - this.positions = [] - this.clickTimeout = null - if (viewer.dataSources.getByName(type).length === 0) { - this.layer = new CustomDataSource(type) - viewer.dataSources.add(this.layer) - } else { - this.layer = viewer.dataSources.getByName(type)[0] - } - } - // 开始绘制 - public start() { - // 左单击加点 - this.handler.setInputAction( - this.leftClickCallBack, - ScreenSpaceEventType.LEFT_CLICK, - ) - // 移动动态绘制 - this.handler.setInputAction( - this.moveCallBack, - ScreenSpaceEventType.MOUSE_MOVE, - ) - // 左双击结束 - this.handler.setInputAction( - this.leftDoubleClickCallBack, - ScreenSpaceEventType.LEFT_DOUBLE_CLICK, - ) - } - public end() { - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) - } - //左单击回调事件 - private leftClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - // 清除可能已经设置的单击定时器 - clearTimeout(this.clickTimeout) - console.log('**************************** click') - // 设置一个新的定时器,用于判断是单击还是双击 - this.clickTimeout = setTimeout(() => { - console.log('**************************** run') - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) - if (cartesian3 != undefined) { - if (this.bMove) { - this.positions.pop() - this.bMove = false - } - this.positions.push(cartesian3) - this.createGeometry(this.type) - // 创建控制点 - const point = new PointEntity( - this.positions[this.positions.length - 1], - { - color: Color.WHITE, - pixelSize: 6, - }, - ) - point.parent = this.polygon! - this.layer.entities.add(point) - - this.viewer.scene.requestRender() //刷新 - } - }, 100) - } - // 移动回调事件 - private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) - if (cartesian3 != undefined) { - if (this.positions.length >= 1) { - if (!this.bMove) { - this.positions.push(cartesian3) - this.bMove = true - } else { - this.positions[this.positions.length - 1] = cartesian3 - } - if (this.type === 'Polygon') { - // 多边形创建临时线 - if (this.positions.length === 2) { - this.createGeometry('Polyline') - } - if (this.positions.length > 2) { - this.polyline!.show = false - } - } - } - this.viewer.scene.requestRender() //刷新 - } - } - // 左双击回调事件 - private leftDoubleClickCallBack = ( - event: ScreenSpaceEventHandler.PositionedEvent, - ) => { - // 清除可能已经设置的单击定时器 - clearTimeout(this.clickTimeout) - console.log('**************************** double click') - const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) - if (cartesian3 != undefined) { - this.positions.pop() - this.positions.push(cartesian3) - } - - this.clearEvent() - console.log('end:' + this.positions.length.toString()) - console.log(this.positions) - } - clearEvent() { - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) - this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) - this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) - } - // 创建几何体 - createGeometry(type: string) { - switch (type) { - case 'Polyline': - if (this.polyline == null) { - this.polyline = new PolylineEntity( - new CallbackProperty(() => { - return this.positions - }, false), - ) - this.layer.entities.add(this.polyline) - // this.viewer.entities.add(this.polyline) - } - break - case 'Polygon': - if (this.polygon == null) { - this.polygon = new PolygonEntity( - new CallbackProperty(() => { - return new PolygonHierarchy(this.positions) - }, false), - ) - this.layer.entities.add(this.polygon) - // this.viewer.entities.add(this.polygon) - console.log('Polygon created!') - } - break - default: - break - } - } -} - -export { Drawer } +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-15 08:43:26 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:49:27 + * @FilePath: \GCSMap\src\utils\drawer.ts + * @Description: 矢量要素绘制工具类 + */ +import { + Viewer, + ScreenSpaceEventHandler, + ScreenSpaceEventType, + CustomDataSource, + Cartesian3, + CallbackProperty, + PolygonHierarchy, + Color, +} from 'cesium' +import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' +import { + PointEntity, + PolylineEntity, + PolygonEntity, +} from '@/utils/map/geometry' +class Drawer { + viewer: Viewer + type: string + handler: ScreenSpaceEventHandler + layer: CustomDataSource + polyline: PolylineEntity | null + polygon: PolygonEntity | null + positions: Cartesian3[] = [] + n_Points: number + bMove: boolean + clickTimeout: any + constructor(viewer: Viewer, type: string) { + this.viewer = viewer + this.type = type + this.handler = new ScreenSpaceEventHandler(this.viewer.canvas) + this.polyline = null + this.polygon = null + this.n_Points = 0 + this.bMove = false + this.positions = [] + this.clickTimeout = null + if (viewer.dataSources.getByName(type).length === 0) { + this.layer = new CustomDataSource(type) + viewer.dataSources.add(this.layer) + } else { + this.layer = viewer.dataSources.getByName(type)[0] + } + } + // 开始绘制 + public start() { + // 左单击加点 + this.handler.setInputAction( + this.leftClickCallBack, + ScreenSpaceEventType.LEFT_CLICK, + ) + // 移动动态绘制 + this.handler.setInputAction( + this.moveCallBack, + ScreenSpaceEventType.MOUSE_MOVE, + ) + // 左双击结束 + this.handler.setInputAction( + this.leftDoubleClickCallBack, + ScreenSpaceEventType.LEFT_DOUBLE_CLICK, + ) + } + public end() { + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) + } + //左单击回调事件 + private leftClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + // 清除可能已经设置的单击定时器 + clearTimeout(this.clickTimeout) + console.log('**************************** click') + // 设置一个新的定时器,用于判断是单击还是双击 + this.clickTimeout = setTimeout(() => { + console.log('**************************** run') + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) + if (cartesian3 != undefined) { + if (this.bMove) { + this.positions.pop() + this.bMove = false + } + this.positions.push(cartesian3) + this.createGeometry(this.type) + // 创建控制点 + const point = new PointEntity( + this.positions[this.positions.length - 1], + { + color: Color.WHITE, + pixelSize: 6, + }, + ) + point.parent = this.polygon! + this.layer.entities.add(point) + + this.viewer.scene.requestRender() //刷新 + } + }, 100) + } + // 移动回调事件 + private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) + if (cartesian3 != undefined) { + if (this.positions.length >= 1) { + if (!this.bMove) { + this.positions.push(cartesian3) + this.bMove = true + } else { + this.positions[this.positions.length - 1] = cartesian3 + } + if (this.type === 'Polygon') { + // 多边形创建临时线 + if (this.positions.length === 2) { + this.createGeometry('Polyline') + } + if (this.positions.length > 2) { + this.polyline!.show = false + } + } + } + this.viewer.scene.requestRender() //刷新 + } + } + // 左双击回调事件 + private leftDoubleClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { + // 清除可能已经设置的单击定时器 + clearTimeout(this.clickTimeout) + console.log('**************************** double click') + const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) + if (cartesian3 != undefined) { + this.positions.pop() + this.positions.push(cartesian3) + } + + this.clearEvent() + console.log('end:' + this.positions.length.toString()) + console.log(this.positions) + } + clearEvent() { + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) + this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) + this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) + } + // 创建几何体 + createGeometry(type: string) { + switch (type) { + case 'Polyline': + if (this.polyline == null) { + this.polyline = new PolylineEntity( + new CallbackProperty(() => { + return this.positions + }, false), + ) + this.layer.entities.add(this.polyline) + // this.viewer.entities.add(this.polyline) + } + break + case 'Polygon': + if (this.polygon == null) { + this.polygon = new PolygonEntity( + new CallbackProperty(() => { + return new PolygonHierarchy(this.positions) + }, false), + ) + this.layer.entities.add(this.polygon) + // this.viewer.entities.add(this.polygon) + console.log('Polygon created!') + } + break + default: + break + } + } +} + +export { Drawer } diff --git a/src/utils/map/geocomputation.ts b/src/utils/map/geocomputation.ts index 0777547..9608bf4 100644 --- a/src/utils/map/geocomputation.ts +++ b/src/utils/map/geocomputation.ts @@ -1,163 +1,163 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-22 15:42:49 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-01 14:05:43 - * @Description: 地理计算 - */ -import { - Cartesian3, - Cartographic, - EllipsoidGeodesic, - Math as Cesium_Math, - Matrix4, - Transforms, -} from 'cesium' -/** - * 计算空间中一点到一条直线的最短距离的交点(在不考虑地球曲率的情况下) - * @param lineStart 直线的起点:[longitude1, latitude1, height1] - * @param lineEnd 直线的终点:[longitude2, latitude2, height2] - * @param point 空间中的点:[[longitude3, latitude3, height3]] - * @returns 最近的交点 - */ -function getClosestPoint( - lineStart: Cartesian3, - lineEnd: Cartesian3, - point: Cartesian3, -): Cartesian3 { - // 计算直线方向向量 - const lineDirection = new Cartesian3() - Cartesian3.subtract(lineEnd, lineStart, lineDirection) - Cartesian3.normalize(lineDirection, lineDirection) - - // 计算点到直线起点的向量 - const pointToStart = new Cartesian3() - Cartesian3.subtract(point, lineStart, pointToStart) - - // 计算投影长度,即点到直线的向量在直线方向向量上的分量长度 - const projectionLength = Cartesian3.dot(pointToStart, lineDirection) - - // 使用标量乘法和向量加法确定交点 - const closestPoint = new Cartesian3() - Cartesian3.multiplyByScalar(lineDirection, projectionLength, closestPoint) - Cartesian3.add(lineStart, closestPoint, closestPoint) - return closestPoint -} - -/** - * 判断一个点是否在直线上(在不考虑地球曲率的情况下) - * @param lineStart 直线的起点:[longitude1, latitude1, height1] - * @param lineEnd 直线的起点:[longitude2, latitude2, height2] - * @param pointToCheck 直线的起点:[longitude3, latitude3, height3] - * @param tolerance 容差 - * @returns 是否在线段上 - */ -function isOnLineSegment( - lineStart: Cartesian3, - lineEnd: Cartesian3, - pointToCheck: Cartesian3, - tolerance: number = Cesium_Math.EPSILON1, -): boolean { - const dist_AP = Cartesian3.distance(lineStart, pointToCheck) - const dist_BP = Cartesian3.distance(lineEnd, pointToCheck) - const dist_AB = Cartesian3.distance(lineStart, lineEnd) - - const isCollinear = Math.abs(dist_AP + dist_BP - dist_AB) < tolerance - return isCollinear - /* - const startToEnd = new Cartesian3() - const startToPoint = new Cartesian3() - const endToPoint = new Cartesian3() - - // 计算向量 - Cartesian3.subtract(lineEnd, lineStart, startToEnd) - Cartesian3.subtract(pointToCheck, lineStart, startToPoint) - Cartesian3.subtract(pointToCheck, lineEnd, endToPoint) - - // 判断共线 - const cross = Cartesian3.cross(startToEnd, startToPoint, new Cartesian3()) - console.log('cross:' + Cartesian3.magnitude(cross).toString()) - // Math.EPSILON6 是一个非常小的值,用来防止浮点数计算的误差 - const isCollinear = Cartesian3.magnitude(cross) < tolerance - - // 判断点是否在线段之间 - let isBetween = false - if (isCollinear) { - const dotProduct1 = Cartesian3.dot(startToEnd, startToPoint) - const dotProduct2 = Cartesian3.dot(startToEnd, endToPoint) - isBetween = dotProduct1 >= 0 && dotProduct2 <= 0 - } - return isBetween - */ -} - -/** - * 计算距离,单位米 - * @param p1 起点 - * @param p2 终点 - */ -function getDistance(p1: Cartesian3, p2: Cartesian3): number { - let point1cartographic = Cartographic.fromCartesian(p1) - let point2cartographic = Cartographic.fromCartesian(p2) - /**根据经纬度计算出距离**/ - let geodesic = new EllipsoidGeodesic() - geodesic.setEndPoints(point1cartographic, point2cartographic) - return geodesic.surfaceDistance / 1000 -} - -/** - * 计算方位角,单位度 - * @param p1 起点 - * @param p2 终点 - * @param digits 保留小数位数,默认为保留1位小数 - */ -function getAzimuth(p1: Cartesian3, p2: Cartesian3, digits = 1): string { - // 建立局部坐标系:北为y,东为x,p1为原点 - const localMatrix = Transforms.eastNorthUpToFixedFrame(p1) - //求世界坐标到局部坐标的变换矩阵 - const worldToLocalMatrix = Matrix4.inverse(localMatrix, new Matrix4()) - //p1在局部坐标系的位置,即局部坐标原点 - const localPosition1 = Matrix4.multiplyByPoint( - worldToLocalMatrix, - p1, - new Cartesian3(), - ) - //p2在局部坐标系的位置 - const localPosition2 = Matrix4.multiplyByPoint( - worldToLocalMatrix, - p2, - new Cartesian3(), - ) - //弧度 - const angle = Math.atan2( - localPosition2.x - localPosition1.x, - localPosition2.y - localPosition1.y, - ) - //转为角度 - let theta = angle * (180 / Math.PI) - theta = theta < 0 ? theta + 360 : theta - return theta.toFixed(digits) -} - -/** - * 计算多边形面积,单位平方米 - * @param vertexs 多边形顶点数组 - */ -function getPolygonArea(vertexs: Cartesian3[]) { - let area = 0 - for (let i = 0; i < vertexs.length; i++) { - let j = (i + 1) % vertexs.length - area += vertexs[i].x * vertexs[j].y - area -= vertexs[i].y * vertexs[j].x - } - area /= 2 - return Math.abs(area) -} - -export { - getClosestPoint, - isOnLineSegment, - getDistance, - getAzimuth, - getPolygonArea, -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-22 15:42:49 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:49:17 + * @Description: 地理计算 + */ +import { + Cartesian3, + Cartographic, + EllipsoidGeodesic, + Math as Cesium_Math, + Matrix4, + Transforms, +} from 'cesium' +/** + * 计算空间中一点到一条直线的最短距离的交点(在不考虑地球曲率的情况下) + * @param lineStart 直线的起点:[longitude1, latitude1, height1] + * @param lineEnd 直线的终点:[longitude2, latitude2, height2] + * @param point 空间中的点:[[longitude3, latitude3, height3]] + * @returns 最近的交点 + */ +function getClosestPoint( + lineStart: Cartesian3, + lineEnd: Cartesian3, + point: Cartesian3, +): Cartesian3 { + // 计算直线方向向量 + const lineDirection = new Cartesian3() + Cartesian3.subtract(lineEnd, lineStart, lineDirection) + Cartesian3.normalize(lineDirection, lineDirection) + + // 计算点到直线起点的向量 + const pointToStart = new Cartesian3() + Cartesian3.subtract(point, lineStart, pointToStart) + + // 计算投影长度,即点到直线的向量在直线方向向量上的分量长度 + const projectionLength = Cartesian3.dot(pointToStart, lineDirection) + + // 使用标量乘法和向量加法确定交点 + const closestPoint = new Cartesian3() + Cartesian3.multiplyByScalar(lineDirection, projectionLength, closestPoint) + Cartesian3.add(lineStart, closestPoint, closestPoint) + return closestPoint +} + +/** + * 判断一个点是否在直线上(在不考虑地球曲率的情况下) + * @param lineStart 直线的起点:[longitude1, latitude1, height1] + * @param lineEnd 直线的起点:[longitude2, latitude2, height2] + * @param pointToCheck 直线的起点:[longitude3, latitude3, height3] + * @param tolerance 容差 + * @returns 是否在线段上 + */ +function isOnLineSegment( + lineStart: Cartesian3, + lineEnd: Cartesian3, + pointToCheck: Cartesian3, + tolerance: number = Cesium_Math.EPSILON1, +): boolean { + const dist_AP = Cartesian3.distance(lineStart, pointToCheck) + const dist_BP = Cartesian3.distance(lineEnd, pointToCheck) + const dist_AB = Cartesian3.distance(lineStart, lineEnd) + + const isCollinear = Math.abs(dist_AP + dist_BP - dist_AB) < tolerance + return isCollinear + /* + const startToEnd = new Cartesian3() + const startToPoint = new Cartesian3() + const endToPoint = new Cartesian3() + + // 计算向量 + Cartesian3.subtract(lineEnd, lineStart, startToEnd) + Cartesian3.subtract(pointToCheck, lineStart, startToPoint) + Cartesian3.subtract(pointToCheck, lineEnd, endToPoint) + + // 判断共线 + const cross = Cartesian3.cross(startToEnd, startToPoint, new Cartesian3()) + console.log('cross:' + Cartesian3.magnitude(cross).toString()) + // Math.EPSILON6 是一个非常小的值,用来防止浮点数计算的误差 + const isCollinear = Cartesian3.magnitude(cross) < tolerance + + // 判断点是否在线段之间 + let isBetween = false + if (isCollinear) { + const dotProduct1 = Cartesian3.dot(startToEnd, startToPoint) + const dotProduct2 = Cartesian3.dot(startToEnd, endToPoint) + isBetween = dotProduct1 >= 0 && dotProduct2 <= 0 + } + return isBetween + */ +} + +/** + * 计算距离,单位米 + * @param p1 起点 + * @param p2 终点 + */ +function getDistance(p1: Cartesian3, p2: Cartesian3): number { + let point1cartographic = Cartographic.fromCartesian(p1) + let point2cartographic = Cartographic.fromCartesian(p2) + /**根据经纬度计算出距离**/ + let geodesic = new EllipsoidGeodesic() + geodesic.setEndPoints(point1cartographic, point2cartographic) + return geodesic.surfaceDistance / 1000 +} + +/** + * 计算方位角,单位度 + * @param p1 起点 + * @param p2 终点 + * @param digits 保留小数位数,默认为保留1位小数 + */ +function getAzimuth(p1: Cartesian3, p2: Cartesian3, digits = 1): string { + // 建立局部坐标系:北为y,东为x,p1为原点 + const localMatrix = Transforms.eastNorthUpToFixedFrame(p1) + //求世界坐标到局部坐标的变换矩阵 + const worldToLocalMatrix = Matrix4.inverse(localMatrix, new Matrix4()) + //p1在局部坐标系的位置,即局部坐标原点 + const localPosition1 = Matrix4.multiplyByPoint( + worldToLocalMatrix, + p1, + new Cartesian3(), + ) + //p2在局部坐标系的位置 + const localPosition2 = Matrix4.multiplyByPoint( + worldToLocalMatrix, + p2, + new Cartesian3(), + ) + //弧度 + const angle = Math.atan2( + localPosition2.x - localPosition1.x, + localPosition2.y - localPosition1.y, + ) + //转为角度 + let theta = angle * (180 / Math.PI) + theta = theta < 0 ? theta + 360 : theta + return theta.toFixed(digits) +} + +/** + * 计算多边形面积,单位平方米 + * @param vertexs 多边形顶点数组 + */ +function getPolygonArea(vertexs: Cartesian3[]) { + let area = 0 + for (let i = 0; i < vertexs.length; i++) { + let j = (i + 1) % vertexs.length + area += vertexs[i].x * vertexs[j].y + area -= vertexs[i].y * vertexs[j].x + } + area /= 2 + return Math.abs(area) +} + +export { + getClosestPoint, + isOnLineSegment, + getDistance, + getAzimuth, + getPolygonArea, +} diff --git a/src/utils/map/geometry/baseGeometry.ts b/src/utils/map/geometry/baseGeometry.ts index 5aab807..58fb8ab 100644 --- a/src/utils/map/geometry/baseGeometry.ts +++ b/src/utils/map/geometry/baseGeometry.ts @@ -1,142 +1,143 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-28 16:22:58 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 14:57:49 - * @Description: 几何类抽象基类 - */ -import { - // EntityCollection, - Entity, - Cartesian3, - Color, - ConstantPositionProperty, - CustomDataSource, -} from 'cesium' -import { PointEntity, EntityOptions } from './pointEntity' -export abstract class BaseGeometry extends CustomDataSource { - static ID: number - // abstract subId: number - geometry: Entity | null = null - positions: Cartesian3[] = [] - controlPointsID: string[] = [] //存储 - options: EntityOptions = { - // id: 'Point' + String(PointEntity.ID), - // name: 'Point' + String(PointEntity.ID + 1), - show: true, - // pixelSize: 10, - width: 2, - color: Color.GREEN, - outlineWidth: 0, - } - - constructor() { - super() - } - /** - * 新增一个节点,默认插入在尾部, - * @param pos 点坐标 - * @param index 插入的位置,0起步 - * @bAddControlPoint 是否添加控制点 - */ - public addPoint( - pos: Cartesian3, - index: number = -1, - bAddControlPoint: boolean = true, - ) { - if (index === -1) { - //插入尾部 - this.positions.push(pos) - if (bAddControlPoint) - this.createControlPoint(pos, this.positions.length - 1) - } else if (index >= 0 && index < this.positions.length) { - this.positions.splice(index, 0, pos) - if (bAddControlPoint) this.createControlPoint(pos, index) - } else { - return - } - } - /** - * 移除点 - * @param index 移除点的位置 - * @returns - */ - public removePoint(index: number = -1) { - if (index === -1 || index === this.positions.length - 1) { - //移除尾部元素 - this.positions.pop() - } else if (index >= 0 && index < this.positions.length) { - this.positions.splice(index, 1) - } else { - return - } - //移除控制点 - this.removeControlPoint(index) - } - /** - * 修改某点的坐标 - * @param pos 修改点的坐标 - * @param index 修改点的位置 - */ - public modifyPoint(pos: Cartesian3, index: number) { - if (index === -1) { - index = this.positions.length - 1 - } - if (index >= 0 && index < this.positions.length) { - this.positions.splice(index, 1, pos) - if (this.controlPointsID[index]) { - //修改控制点坐标 - const point = this.entities.getById(this.controlPointsID[index]) - if (point) { - point.position = new ConstantPositionProperty(pos) - } - } - } - } - /** - * 新加一个点 - * @param pos 点的坐标 - * @param index 插入的位置,0起步 - */ - public createControlPoint(pos: Cartesian3, index: number) { - // if (this.geometry) { - const point = new PointEntity(pos) - point.parent = this.geometry! - point.subId = index - this.entities.add(point) - this.controlPointsID.splice(index, 0, point.id) - // } - } - /** - * 移除控制点 - * @param index 控制点下标号 - */ - public removeControlPoint(index: number) { - if (index === -1) index = this.controlPointsID.length - 1 - if (this.controlPointsID[index]) { - this.entities.removeById(this.controlPointsID[index]) - this.controlPointsID.splice(index, 1) - } - } - /** - * 清空所有控制点 - */ - removeControlPoints() { - this.controlPointsID.forEach((value) => { - this.entities.removeById(value) - }) - this.controlPointsID = [] - } - /** - * 设置控制点是否显示 - * @param index 控制点下标号 - * @param bShow 是否显示 - */ - showControlPoint(index: number, bShow: boolean) { - if (index === -1) index = this.controlPointsID.length - 1 - if (this.controlPointsID[index]) { - const point = this.entities.getById(this.controlPointsID[index]) - if (point) point.show = bShow - } - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-28 16:22:58 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:45:37 + * @Description: 几何类抽象基类 + */ +import { + // EntityCollection, + Entity, + Cartesian3, + Color, + ConstantPositionProperty, + CustomDataSource, +} from 'cesium' +import { PointEntity } from './pointEntity' +import { EntityOptions } from '@/types/entityoptions' +export abstract class BaseGeometry extends CustomDataSource { + static ID: number + // abstract subId: number + geometry: Entity | null = null + positions: Cartesian3[] = [] + controlPointsID: string[] = [] //存储 + options: EntityOptions = { + // id: 'Point' + String(PointEntity.ID), + // name: 'Point' + String(PointEntity.ID + 1), + show: true, + // pixelSize: 10, + width: 2, + color: Color.GREEN, + outlineWidth: 0, + } + + constructor() { + super() + } + /** + * 新增一个节点,默认插入在尾部, + * @param pos 点坐标 + * @param index 插入的位置,0起步 + * @bAddControlPoint 是否添加控制点 + */ + public addPoint( + pos: Cartesian3, + index: number = -1, + bAddControlPoint: boolean = true, + ) { + if (index === -1) { + //插入尾部 + this.positions.push(pos) + if (bAddControlPoint) + this.createControlPoint(pos, this.positions.length - 1) + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 0, pos) + if (bAddControlPoint) this.createControlPoint(pos, index) + } else { + return + } + } + /** + * 移除点 + * @param index 移除点的位置 + * @returns + */ + public removePoint(index: number = -1) { + if (index === -1 || index === this.positions.length - 1) { + //移除尾部元素 + this.positions.pop() + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1) + } else { + return + } + //移除控制点 + this.removeControlPoint(index) + } + /** + * 修改某点的坐标 + * @param pos 修改点的坐标 + * @param index 修改点的位置 + */ + public modifyPoint(pos: Cartesian3, index: number) { + if (index === -1) { + index = this.positions.length - 1 + } + if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1, pos) + if (this.controlPointsID[index]) { + //修改控制点坐标 + const point = this.entities.getById(this.controlPointsID[index]) + if (point) { + point.position = new ConstantPositionProperty(pos) + } + } + } + } + /** + * 新加一个点 + * @param pos 点的坐标 + * @param index 插入的位置,0起步 + */ + public createControlPoint(pos: Cartesian3, index: number) { + // if (this.geometry) { + const point = new PointEntity(pos) + point.parent = this.geometry! + point.subId = index + this.entities.add(point) + this.controlPointsID.splice(index, 0, point.id) + // } + } + /** + * 移除控制点 + * @param index 控制点下标号 + */ + public removeControlPoint(index: number) { + if (index === -1) index = this.controlPointsID.length - 1 + if (this.controlPointsID[index]) { + this.entities.removeById(this.controlPointsID[index]) + this.controlPointsID.splice(index, 1) + } + } + /** + * 清空所有控制点 + */ + removeControlPoints() { + this.controlPointsID.forEach((value) => { + this.entities.removeById(value) + }) + this.controlPointsID = [] + } + /** + * 设置控制点是否显示 + * @param index 控制点下标号 + * @param bShow 是否显示 + */ + showControlPoint(index: number, bShow: boolean) { + if (index === -1) index = this.controlPointsID.length - 1 + if (this.controlPointsID[index]) { + const point = this.entities.getById(this.controlPointsID[index]) + if (point) point.show = bShow + } + } +} diff --git a/src/utils/map/geometry/billboard.ts b/src/utils/map/geometry/billboard.ts index aa36efc..aa09d8e 100644 --- a/src/utils/map/geometry/billboard.ts +++ b/src/utils/map/geometry/billboard.ts @@ -1,36 +1,36 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-04-10 08:53:12 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-11 09:09:38 - * @Description: 广告牌对象 - */ -import { Entity, Cartesian3, Cartesian2, Color, HeightReference } from 'cesium' -import { getMapAssetsFile } from '@/utils/getAssets' -export class BillBoard extends Entity { - static ID: number = 0 - public subId: number = 0 //用于作为其他几何体的控制点时标记节点号 - constructor(position: Cartesian3) { - super({ - position: position, - billboard: { - show: true, - image: getMapAssetsFile('marker.svg'), - width: 32, - height: 32, - scale: 1, - // 设置实体贴地 - heightReference: HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: Number.POSITIVE_INFINITY, // 可能会提高在不同角度下的清晰度 - }, - label: { - text: 'Maker1', - font: '32px sans-serif', - scale: 0.5, - pixelOffset: new Cartesian2(45, -5), - heightReference: HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: Number.POSITIVE_INFINITY, // 可能会提高在不同角度下的清晰度 - }, - }) - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-04-10 08:53:12 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:45:00 + * @Description: 广告牌对象 + */ +import { Entity, Cartesian3, Cartesian2, Color, HeightReference } from 'cesium' +import { getMapAssetsFile } from '@/utils/getAssets' +export class BillBoard extends Entity { + static ID: number = 0 + public subId: number = 0 //用于作为其他几何体的控制点时标记节点号 + constructor(position: Cartesian3) { + super({ + position: position, + billboard: { + show: true, + image: getMapAssetsFile('marker.svg'), + width: 32, + height: 32, + scale: 1, + // 设置实体贴地 + heightReference: HeightReference.CLAMP_TO_GROUND, + disableDepthTestDistance: Number.POSITIVE_INFINITY, // 可能会提高在不同角度下的清晰度 + }, + label: { + text: 'Maker1', + font: '32px sans-serif', + scale: 0.5, + pixelOffset: new Cartesian2(45, -5), + heightReference: HeightReference.CLAMP_TO_GROUND, + disableDepthTestDistance: Number.POSITIVE_INFINITY, // 可能会提高在不同角度下的清晰度 + }, + }) + } +} diff --git a/src/utils/map/geometry/pointEntity.ts b/src/utils/map/geometry/pointEntity.ts index de0a02e..626b151 100644 --- a/src/utils/map/geometry/pointEntity.ts +++ b/src/utils/map/geometry/pointEntity.ts @@ -1,70 +1,56 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-28 16:35:33 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 15:43:49 - * @Description: 封装的点几何类 - */ -import { - Entity, - Cartesian3, - Color, - PointGraphics, - PositionProperty, - LabelGraphics, - Cartesian2, - CallbackProperty, - Property, -} from 'cesium' -type EntityOptions = { - id?: string - name?: string - show?: boolean - pixelSize?: number - outlineColor?: Color - color?: Color - fillColor?: Color - fill?: boolean - width?: number - outlineWidth?: number - text?: string - font?: string - pixelOffset?: Cartesian2 -} -// 点 -class PointEntity extends Entity { - static ID: number = 0 - public subId: number = 0 //用于作为其他几何体的控制点时标记节点号 - options: EntityOptions = { - id: 'Point' + String(PointEntity.ID), - name: 'Point' + String(PointEntity.ID + 1), - show: true, - pixelSize: 8, - color: Color.WHITE, - outlineColor: Color.GREEN, - outlineWidth: 0, - } - constructor(position: Cartesian3, options?: EntityOptions) { - super({ - position: position, - }) - this.options = { ...this.options, ...options } - //点对象 - this.point = new PointGraphics({ - pixelSize: this.options.pixelSize, - color: this.options.color, - outlineColor: this.options.outlineColor, - outlineWidth: this.options.outlineWidth, - }) - // 标注对象 - this.label = new LabelGraphics({ - text: this.options.text, - font: this.options.font, - pixelOffset: this.options.pixelOffset, - }) - - PointEntity.ID++ - } -} - -export { PointEntity, type EntityOptions } +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-28 16:35:33 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:46:19 + * @Description: 封装的点几何类 + */ +import { + Entity, + Cartesian3, + Color, + PointGraphics, + PositionProperty, + LabelGraphics, + Cartesian2, + CallbackProperty, + Property, +} from 'cesium' +import { EntityOptions } from '@/types/entityoptions' +// 点 +class PointEntity extends Entity { + static ID: number = 0 + public subId: number = 0 //用于作为其他几何体的控制点时标记节点号 + options: EntityOptions = { + id: 'Point' + String(PointEntity.ID), + name: 'Point' + String(PointEntity.ID + 1), + show: true, + pixelSize: 8, + color: Color.WHITE, + outlineColor: Color.GREEN, + outlineWidth: 0, + } + constructor(position: Cartesian3, options?: EntityOptions) { + super({ + position: position, + }) + this.options = { ...this.options, ...options } + //点对象 + this.point = new PointGraphics({ + pixelSize: this.options.pixelSize, + color: this.options.color, + outlineColor: this.options.outlineColor, + outlineWidth: this.options.outlineWidth, + }) + // 标注对象 + this.label = new LabelGraphics({ + text: this.options.text, + font: this.options.font, + pixelOffset: this.options.pixelOffset, + }) + + PointEntity.ID++ + } +} + +export { PointEntity } diff --git a/src/utils/map/geometry/polygonEntity.ts b/src/utils/map/geometry/polygonEntity.ts index 4a29c73..b73ca01 100644 --- a/src/utils/map/geometry/polygonEntity.ts +++ b/src/utils/map/geometry/polygonEntity.ts @@ -1,56 +1,56 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-04-11 09:26:56 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 15:34:45 - * @Description: 封装的Polygon对象 - */ -import { - Entity, - Cartesian3, - Color, - CallbackProperty, - PolygonHierarchy, -} from 'cesium' -import { BaseGeometry } from './baseGeometry' -import { type EntityOptions } from './pointEntity' -export class PolygonEntity extends BaseGeometry { - static ID: number = 0 - // positions: Cartesian3[] = [] - controlPointsID: string[] = [] - options: EntityOptions = { - id: 'Polygon' + String(PolygonEntity.ID), - name: 'Polygon' + String(PolygonEntity.ID + 1), - show: true, - width: 2, - color: Color.RED, - fillColor: Color.RED.withAlpha(0.5), - fill: true, - } - constructor(ptArr: Cartesian3[], options?: EntityOptions) { - super() - this.positions = ptArr - this.options = { ...this.options, ...options } - this.geometry = new Entity({ - show: this.options.show, - name: this.options.name, - polygon: { - hierarchy: new CallbackProperty(() => { - return new PolygonHierarchy(this.positions) - }, false), - material: this.options.fillColor, //填充颜色 - fill: this.options.fill, //是否填充 - outline: true, - // outlineWidth: this.options.width, //线宽 - outlineColor: this.options.color, //线颜色 - }, - }) - this.entities.add(this.geometry) - // 添加控制点 - ptArr.forEach((pt, index) => { - this.createControlPoint(pt, index) - }) - - PolygonEntity.ID++ - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-04-11 09:26:56 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:45:27 + * @Description: 封装的Polygon对象 + */ +import { + Entity, + Cartesian3, + Color, + CallbackProperty, + PolygonHierarchy, +} from 'cesium' +import { BaseGeometry } from './baseGeometry' +import { EntityOptions } from '@/types/entityoptions' +export class PolygonEntity extends BaseGeometry { + static ID: number = 0 + // positions: Cartesian3[] = [] + controlPointsID: string[] = [] + options: EntityOptions = { + id: 'Polygon' + String(PolygonEntity.ID), + name: 'Polygon' + String(PolygonEntity.ID + 1), + show: true, + width: 2, + color: Color.RED, + fillColor: Color.RED.withAlpha(0.5), + fill: true, + } + constructor(ptArr: Cartesian3[], options?: EntityOptions) { + super() + this.positions = ptArr + this.options = { ...this.options, ...options } + this.geometry = new Entity({ + show: this.options.show, + name: this.options.name, + polygon: { + hierarchy: new CallbackProperty(() => { + return new PolygonHierarchy(this.positions) + }, false), + material: this.options.fillColor, //填充颜色 + fill: this.options.fill, //是否填充 + outline: true, + // outlineWidth: this.options.width, //线宽 + outlineColor: this.options.color, //线颜色 + }, + }) + this.entities.add(this.geometry) + // 添加控制点 + ptArr.forEach((pt, index) => { + this.createControlPoint(pt, index) + }) + + PolygonEntity.ID++ + } +} diff --git a/src/utils/map/geometry/polylineEntity.ts b/src/utils/map/geometry/polylineEntity.ts index bb07f25..5a4aa26 100644 --- a/src/utils/map/geometry/polylineEntity.ts +++ b/src/utils/map/geometry/polylineEntity.ts @@ -1,48 +1,48 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-28 16:49:02 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-12 14:27:12 - * @Description: 封装的Polyline类 - */ -import { Entity, Cartesian3, Color, CallbackProperty } from 'cesium' -import { BaseGeometry } from './baseGeometry' -import { type EntityOptions } from './pointEntity' -export class PolylineEntity extends BaseGeometry { - static ID: number = 0 - // positions: Cartesian3[] = [] - controlPointsID: string[] = [] - options: EntityOptions = { - // id: 'Polyline' + String(PolylineEntity.ID), - name: 'Polyline' + String(PolylineEntity.ID + 1), - show: true, - width: 3, - color: Color.GREEN, - } - constructor(ptArr: Cartesian3[], options?: EntityOptions) { - super() - this.options = { ...this.options, ...options } - // console.log(this.options) - this.positions = ptArr - // console.log(this.positions) - // 创建线实体对象 - this.geometry = new Entity({ - name: this.options.name, - polyline: { - positions: new CallbackProperty(() => { - return this.positions - }, false), - show: this.options.show, - width: this.options.width, - material: this.options.color, - }, - }) - this.entities.add(this.geometry) - // 添加控制点 - ptArr.forEach((pt, index) => { - this.createControlPoint(pt, index) - }) - - PolylineEntity.ID++ - } -} +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-28 16:49:02 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:45:17 + * @Description: 封装的Polyline类 + */ +import { Entity, Cartesian3, Color, CallbackProperty } from 'cesium' +import { BaseGeometry } from './baseGeometry' +import { EntityOptions } from '@/types/entityoptions' +export class PolylineEntity extends BaseGeometry { + static ID: number = 0 + // positions: Cartesian3[] = [] + controlPointsID: string[] = [] + options: EntityOptions = { + // id: 'Polyline' + String(PolylineEntity.ID), + name: 'Polyline' + String(PolylineEntity.ID + 1), + show: true, + width: 3, + color: Color.GREEN, + } + constructor(ptArr: Cartesian3[], options?: EntityOptions) { + super() + this.options = { ...this.options, ...options } + // console.log(this.options) + this.positions = ptArr + // console.log(this.positions) + // 创建线实体对象 + this.geometry = new Entity({ + name: this.options.name, + polyline: { + positions: new CallbackProperty(() => { + return this.positions + }, false), + show: this.options.show, + width: this.options.width, + material: this.options.color, + }, + }) + this.entities.add(this.geometry) + // 添加控制点 + ptArr.forEach((pt, index) => { + this.createControlPoint(pt, index) + }) + + PolylineEntity.ID++ + } +} diff --git a/src/utils/map/sceneViewer.ts b/src/utils/map/sceneViewer.ts index ddffcfb..de407d8 100644 --- a/src/utils/map/sceneViewer.ts +++ b/src/utils/map/sceneViewer.ts @@ -1,113 +1,113 @@ -/* - * @Author: cbwu 504-wuchengbo@htsdfp.com - * @Date: 2024-03-13 09:32:21 - * @LastEditors: cbwu - * @LastEditTime: 2024-04-10 14:02:37 - * @Description: - */ -// Viewer初始化 -import { - Viewer, - TileMapServiceImageryProvider, - ScreenSpaceEventType, - ImageryLayer, - RequestScheduler, - SceneMode, - Rectangle, - buildModuleUrl, -} from 'cesium' -import CesiumNavigation from 'cesium-navigation-es6' - -//离线地球底图 -const earth_native = TileMapServiceImageryProvider.fromUrl( - // 'node_modules/cesium/Build/CesiumUnminified/Assets/Textures/NaturalEarthII', - buildModuleUrl('Assets/Textures/NaturalEarthII'), -) -/** - * Viewer初始化 - * @param container :id或HTML对象 - * @returns :viewer对象 - */ -function initViewer(container: string | Element): Viewer { - //未联网状态加载默认本地底图,保证地球有底图显示 - const viewer = new Viewer(container as HTMLElement, { - infoBox: false, //是否显示点击要素之后显示的信息 - homeButton: false, //是否显示Home按钮 - navigationHelpButton: false, //是否显示帮助信息控件 - timeline: false, //是否显示时间线控件 - animation: false, //是否显示动画控件 - sceneModePicker: true, //是否显示投影方式控件 - sceneMode: SceneMode.SCENE3D, //设置场景模式,3D球体 - // terrain: Cesium.Terrain.fromWorldTerrain(), - baseLayerPicker: false, //是否显示图层选择控件 - requestRenderMode: true, //启用请求渲染模式 - scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存 - fullscreenButton: false, //右下角 全屏控件 - orderIndependentTranslucency: false, - contextOptions: { webgl: { alpha: true } }, - maximumRenderTimeChange: Infinity, // 无操作时自动渲染帧率,设为数字会消耗性能,Infinity为无操作不渲染 - // mapProjection: new Cesium.WebMercatorProjection(), - baseLayer: ImageryLayer.fromProviderAsync(earth_native, {}), - }) - //去除cesium logo,隐藏版本信息 - const creditContainer = viewer.cesiumWidget.creditContainer as HTMLDivElement - creditContainer.style.display = 'none' - // 开启深度检测 - viewer.scene.globe.depthTestAgainstTerrain = false - // 水雾特效 - viewer.scene.globe.showGroundAtmosphere = true - // 设置更高的缩放惯性以使缩放操作更平滑 - viewer.scene.screenSpaceCameraController.inertiaZoom = 0.9 - // 限制相机缩放 - viewer.scene.screenSpaceCameraController.minimumZoomDistance = 200 //相机的高度的最小值 - viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10350000 //相机高度的最大值 - // 设置设备像素比,可能会影响渲染性能 - // viewer.resolutionScale = window.devicePixelRatio - // 视图重绘后确保清晰度 - viewer.scene.preRender.addEventListener(function () { - if (viewer.resolutionScale !== window.devicePixelRatio) { - viewer.resolutionScale = window.devicePixelRatio - } - }) - // 去掉entity的点击事件(双击、单击) - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - ScreenSpaceEventType.LEFT_DOUBLE_CLICK, - ) - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - ScreenSpaceEventType.LEFT_CLICK, - ) - return viewer -} - -/** - * 性能优化 - * @param viewer :场景Viewer - */ -function perfViewer(viewer: Viewer) { - // 抗锯齿 - // 是否支持图像渲染像素化处理 - // if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) { - // viewer.resolutionScale = window.devicePixelRatio - // } - viewer.scene.postProcessStages.fxaa.enabled = true - // 关闭太阳,月亮,天空盒,雾等相关特效 - viewer.scene.moon.show = false - viewer.scene.fog.enabled = false - viewer.scene.sun.show = false - viewer.scene.skyBox.show = false - // 优化加载WMTS图层速度 - RequestScheduler.maximumRequestsPerServer = 18 // 设置cesium请求调度器的最大并发数量 - RequestScheduler.throttleRequests = false //关闭请求调度器的请求节流 -} - -function showNavigator(viewer: Viewer) { - const options: any = {} - // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle - options.defaultResetView = Rectangle.fromDegrees(80, 22, 130, 50) - options.enableCompass = true //罗盘组件 true启用,false禁用 - options.enableCompassOuterRing = true //罗盘外环组件 true启用,false禁用 - options.enableZoomControls = true //缩放组件 true启用,false禁用 - options.enableDistanceLegend = true //比例尺组件 true启用,false禁用 - new CesiumNavigation(viewer, options) -} -export { initViewer, perfViewer, showNavigator } +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-13 09:32:21 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-13 10:49:06 + * @Description: + */ +// Viewer初始化 +import { + Viewer, + TileMapServiceImageryProvider, + ScreenSpaceEventType, + ImageryLayer, + RequestScheduler, + SceneMode, + Rectangle, + buildModuleUrl, +} from 'cesium' +import CesiumNavigation from 'cesium-navigation-es6' + +//离线地球底图 +const earth_native = TileMapServiceImageryProvider.fromUrl( + // 'node_modules/cesium/Build/CesiumUnminified/Assets/Textures/NaturalEarthII', + buildModuleUrl('Assets/Textures/NaturalEarthII'), +) +/** + * Viewer初始化 + * @param container :id或HTML对象 + * @returns :viewer对象 + */ +function initViewer(container: string | Element): Viewer { + //未联网状态加载默认本地底图,保证地球有底图显示 + const viewer = new Viewer(container as HTMLElement, { + infoBox: false, //是否显示点击要素之后显示的信息 + homeButton: false, //是否显示Home按钮 + navigationHelpButton: false, //是否显示帮助信息控件 + timeline: false, //是否显示时间线控件 + animation: false, //是否显示动画控件 + sceneModePicker: true, //是否显示投影方式控件 + sceneMode: SceneMode.SCENE3D, //设置场景模式,3D球体 + // terrain: Cesium.Terrain.fromWorldTerrain(), + baseLayerPicker: false, //是否显示图层选择控件 + requestRenderMode: true, //启用请求渲染模式 + scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存 + fullscreenButton: false, //右下角 全屏控件 + orderIndependentTranslucency: false, + contextOptions: { webgl: { alpha: true } }, + maximumRenderTimeChange: Infinity, // 无操作时自动渲染帧率,设为数字会消耗性能,Infinity为无操作不渲染 + // mapProjection: new Cesium.WebMercatorProjection(), + baseLayer: ImageryLayer.fromProviderAsync(earth_native, {}), + }) + //去除cesium logo,隐藏版本信息 + const creditContainer = viewer.cesiumWidget.creditContainer as HTMLDivElement + creditContainer.style.display = 'none' + // 开启深度检测 + viewer.scene.globe.depthTestAgainstTerrain = false + // 水雾特效 + viewer.scene.globe.showGroundAtmosphere = true + // 设置更高的缩放惯性以使缩放操作更平滑 + viewer.scene.screenSpaceCameraController.inertiaZoom = 0.9 + // 限制相机缩放 + viewer.scene.screenSpaceCameraController.minimumZoomDistance = 200 //相机的高度的最小值 + viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10350000 //相机高度的最大值 + // 设置设备像素比,可能会影响渲染性能 + // viewer.resolutionScale = window.devicePixelRatio + // 视图重绘后确保清晰度 + viewer.scene.preRender.addEventListener(function () { + if (viewer.resolutionScale !== window.devicePixelRatio) { + viewer.resolutionScale = window.devicePixelRatio + } + }) + // 去掉entity的点击事件(双击、单击) + viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( + ScreenSpaceEventType.LEFT_DOUBLE_CLICK, + ) + viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( + ScreenSpaceEventType.LEFT_CLICK, + ) + return viewer +} + +/** + * 性能优化 + * @param viewer :场景Viewer + */ +function perfViewer(viewer: Viewer) { + // 抗锯齿 + // 是否支持图像渲染像素化处理 + // if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) { + // viewer.resolutionScale = window.devicePixelRatio + // } + viewer.scene.postProcessStages.fxaa.enabled = true + // 关闭太阳,月亮,天空盒,雾等相关特效 + viewer.scene.moon.show = false + viewer.scene.fog.enabled = false + viewer.scene.sun.show = false + viewer.scene.skyBox.show = false + // 优化加载WMTS图层速度 + RequestScheduler.maximumRequestsPerServer = 18 // 设置cesium请求调度器的最大并发数量 + RequestScheduler.throttleRequests = false //关闭请求调度器的请求节流 +} + +function showNavigator(viewer: Viewer) { + const options: any = {} + // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle + options.defaultResetView = Rectangle.fromDegrees(80, 22, 130, 50) + options.enableCompass = true //罗盘组件 true启用,false禁用 + options.enableCompassOuterRing = true //罗盘外环组件 true启用,false禁用 + options.enableZoomControls = true //缩放组件 true启用,false禁用 + options.enableDistanceLegend = true //比例尺组件 true启用,false禁用 + new CesiumNavigation(viewer, options) +} +export { initViewer, perfViewer, showNavigator }