From 9fb4de853fc8aab2000f312ba2b8907e3dc9a61d Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Thu, 29 Jan 2026 17:33:29 +0800
Subject: [PATCH] feat:调整

---
 applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js |  121 ++++++++++++++++++++++++---------------
 1 files changed, 74 insertions(+), 47 deletions(-)

diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
index 9ab98fb..724288c 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
@@ -1,25 +1,32 @@
 import * as Cesium from 'cesium'
 import { MapTooltip } from '../Tooltip'
 import { ToolBase } from '../ToolBase'
-import {
-	getBoundsFromCartesians,
-	getCenterFromBounds,
-	getMetersBetween,
-	buildEllipsePositions,
-} from '../shapeUtils'
+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.ellipseEntity = null
-		this.startPosition = null
-		this.endPosition = null
 		this.centerCartesian = null
+		this.majorPoint = null
+		this.minorPoint = null
 		this.semiMajor = 0
 		this.semiMinor = 0
 		this.isDrawing = false
+		this.drawStep = 0
+		this.isCompleted = false
+		this.style = resolveStyle(options?.style)
 	}
 
 	start() {
@@ -28,26 +35,40 @@
 		this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
 		this.handler.setInputAction(click => this.handleLeftClick(click), Cesium.ScreenSpaceEventType.LEFT_CLICK)
 		this.handler.setInputAction(movement => this.handleMouseMove(movement), Cesium.ScreenSpaceEventType.MOUSE_MOVE)
-		this.tooltip.show('单击设置起点', { x: 0, y: 0 })
+		this.drawStep = 0
+		this.isCompleted = false
+		this.tooltip.show('单击设置中心点', { x: 0, y: 0 })
 	}
 
 	handleLeftClick(click) {
+		if (this.isCompleted) return
 		const position = this.getPositionFromScreen(click.position)
 		if (!position) return
-
-		if (!this.startPosition) {
-			this.startPosition = position
-			this.endPosition = position
+		if (this.drawStep === 0) {
+			this.centerCartesian = position
+			this.semiMajor = 1
+			this.semiMinor = 1
 			this.isDrawing = true
+			this.drawStep = 1
 			this.createEntities()
-			this.tooltip.show('单击结束绘制', click.position)
+			this.tooltip.show('单击设置长轴', click.position)
 			return
 		}
-
-		if (this.isDrawing) {
-			this.endPosition = position
-			this.updateEllipseByBounds()
+		if (this.drawStep === 1) {
+			this.majorPoint = position
+			this.semiMajor = Math.max(1, this.getSurfaceDistance(this.centerCartesian, this.majorPoint))
+			this.semiMinor = this.semiMajor
+			this.drawStep = 2
+			this.tooltip.show('单击设置短轴', click.position)
+			return
+		}
+		if (this.drawStep === 2) {
+			this.minorPoint = position
+			const minorRadius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, this.minorPoint))
+			this.semiMinor = Math.min(minorRadius, this.semiMajor)
 			this.isDrawing = false
+			this.drawStep = 0
+			this.isCompleted = true
 			const positions = buildEllipsePositions(this.centerCartesian, this.semiMajor, this.semiMinor)
 			this.notify('getPolygonPositions', positions)
 			this.tooltip.hide()
@@ -56,32 +77,21 @@
 	}
 
 	handleMouseMove(movement) {
-		if (!this.isDrawing) {
-			this.tooltip.move(movement.endPosition)
-			return
-		}
+		if (this.isCompleted) return
+		this.tooltip.move(movement.endPosition)
+		if (!this.isDrawing) return
 		const position = this.getPositionFromScreen(movement.endPosition)
 		if (!position) return
-		this.endPosition = position
-		this.updateEllipseByBounds()
-		this.tooltip.move(movement.endPosition)
-	}
-
-	updateEllipseByBounds() {
-		const bounds = getBoundsFromCartesians([this.startPosition, this.endPosition])
-		const center = getCenterFromBounds(bounds)
-		if (!bounds || !center) return
-		this.centerCartesian = Cesium.Cartesian3.fromRadians(center.longitude, center.latitude)
-		const eastWest = getMetersBetween(
-			new Cesium.Cartographic(bounds.west, center.latitude),
-			new Cesium.Cartographic(bounds.east, center.latitude)
-		)
-		const northSouth = getMetersBetween(
-			new Cesium.Cartographic(center.longitude, bounds.south),
-			new Cesium.Cartographic(center.longitude, bounds.north)
-		)
-		this.semiMajor = Math.max(1, eastWest / 2)
-		this.semiMinor = Math.max(1, northSouth / 2)
+		if (this.drawStep === 1) {
+			const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+			this.semiMajor = radius
+			this.semiMinor = radius
+			return
+		}
+		if (this.drawStep === 2) {
+			const minorRadius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+			this.semiMinor = Math.min(minorRadius, this.semiMajor)
+		}
 	}
 
 	createEntities() {
@@ -91,13 +101,20 @@
 			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,
 			},
 		})
+	}
+
+	getSurfaceDistance(startCartesian, endCartesian) {
+		const start = Cesium.Cartographic.fromCartesian(startCartesian)
+		const end = Cesium.Cartographic.fromCartesian(endCartesian)
+		const geodesic = new Cesium.EllipsoidGeodesic(start, end)
+		return geodesic.surfaceDistance
 	}
 
 	clearPreviewEntities() {
@@ -111,6 +128,14 @@
 		const cartesian = scene.pickPosition(screenPosition)
 		if (cartesian) return cartesian
 		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() {
@@ -127,9 +152,11 @@
 		}
 		this.tooltip?.destroy()
 		this.tooltip = null
-		this.startPosition = null
-		this.endPosition = null
 		this.centerCartesian = null
+		this.majorPoint = null
+		this.minorPoint = null
 		this.isDrawing = false
+		this.drawStep = 0
+		this.isCompleted = false
 	}
 }

--
Gitblit v1.9.3