feat: 新增距离、方位角计算、面积测量交互接口,绘制折线、多边形时可选

pull/8/head
zhaipx 11 months ago
parent 2c45764989
commit e50790c3e9

@ -5,10 +5,9 @@
--> -->
<script setup lang="ts"> <script setup lang="ts">
import { Angle } from '@/utils/map/angle.ts' import { Angle } from '@/utils/map/angle.ts'
import {ScreenSpaceEventHandler, Math, ScreenSpaceEventType, Cartesian3, Cartographic} from 'cesium' import {ScreenSpaceEventHandler, Math, ScreenSpaceEventType, Cartographic} from 'cesium'
import {onMounted, ref} from "vue"; import {onMounted, ref} from "vue";
import {cartesian2ToCartesian3} from "@/utils/map/coordinate.ts"; import {cartesian2ToCartesian3} from "@/utils/map/coordinate.ts";
import {elevationProfile} from "@/utils/map/SpatialAnalysis.ts";
let nowLatStr: string, nowLonStr: string let nowLatStr: string, nowLonStr: string
let lonlatStr = ref('') let lonlatStr = ref('')
let isDecimal = ref(true) let isDecimal = ref(true)
@ -53,7 +52,6 @@ function lonlatClick() {
lonlatStr.value = `经度: ${nowLonStr}°, 纬度: ${nowLatStr}°, 高度` + elevStr lonlatStr.value = `经度: ${nowLonStr}°, 纬度: ${nowLatStr}°, 高度` + elevStr
} }
isDecimal.value = !isDecimal.value isDecimal.value = !isDecimal.value
elevationProfile(window.viewer, Cartesian3.fromDegrees(119.0,30.05),Cartesian3.fromDegrees(119.05,30.0),500)
} }
</script> </script>

@ -69,9 +69,9 @@ onMounted(() => {
window.viewer = viewer window.viewer = viewer
inputGeoJson(viewer) inputGeoJson(viewer)
// //
// const drawPolyline = new CreatePolyline(viewer) // const drawPolyline = new CreatePolyline(viewer,true,{})
// drawPolyline.start() // drawPolyline.start()
const drawPolygon = new DrawPolygon(viewer) const drawPolygon = new DrawPolygon(viewer,true)
drawPolygon.start() drawPolygon.start()
}) })
</script> </script>

@ -0,0 +1,16 @@
<!--
文件描述工具条
创建时间2024/4/16 10:54
创建人Zhaipeixiu
-->
<script setup lang="ts">
</script>
<template>
</template>
<style scoped>
</style>

@ -6,19 +6,20 @@
* @Description: * @Description:
*/ */
import { import {
Viewer, CallbackProperty,
ScreenSpaceEventHandler,
Cartesian3, Cartesian3,
Color, Color,
ScreenSpaceEventType,
Entity, Entity,
CallbackProperty,
PolylineDashMaterialProperty, PolylineDashMaterialProperty,
Rectangle,
ScreenSpaceEventHandler,
ScreenSpaceEventType,
Viewer,
} from 'cesium' } from 'cesium'
import {cartesian2ToCartesian3} from '@/utils/map/coordinate' import {cartesian2ToCartesian3} from '@/utils/map/coordinate'
import {PolygonEntity} from '../geometry/polygonEntity' import {PolygonEntity} from '../geometry/polygonEntity'
import { PointEntity } from '@/utils/map/geometry/pointEntity' import {getPolygonArea} from "@/utils/map/geocomputation.ts";
import EditGeometry from '@/utils/map/draw/editGeometry' import {TextLabel} from "@/utils/map/geometry/textLabel.ts";
export class DrawPolygon { export class DrawPolygon {
viewer: Viewer viewer: Viewer
@ -28,9 +29,11 @@ export class DrawPolygon {
trackingLine: Entity | null trackingLine: Entity | null
trackingLinePositions: Cartesian3[] = [] trackingLinePositions: Cartesian3[] = []
bMove: boolean = false bMove: boolean = false
bMeasure = false
bLongClick: boolean = false bLongClick: boolean = false
constructor(viewer: Viewer) { constructor(viewer: Viewer, isMeasure: boolean=false) {
this.viewer = viewer this.viewer = viewer
this.bMeasure = isMeasure
this.handler = new ScreenSpaceEventHandler(viewer.scene.canvas) this.handler = new ScreenSpaceEventHandler(viewer.scene.canvas)
this.polygon = null this.polygon = null
this.trackingLine = null this.trackingLine = null
@ -130,17 +133,22 @@ export class DrawPolygon {
} }
} }
} }
//左双击回调事件 //左双击回调事件
private leftDoubleClickCallBack = ( private leftDoubleClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent) => {
event: ScreenSpaceEventHandler.PositionedEvent,
) => {
if (!this.polygon) return if (!this.polygon) return
console.log('**************************** double click')
this.bMove = false this.bMove = false
//移除多余的点 //移除多余的点
this.polygon.removePoint(-1) this.polygon.removePoint(-1)
this.polygon.removePoint(-1) this.polygon.removePoint(-1)
if(this.bMeasure){
//计算面积
let area = getPolygonArea(this.positions)
//添加label
new TextLabel(this.viewer,this.getCenter(),`面积: ${(area/1000000).toFixed(2)}k㎡`)
} }
}
//创建追踪线 //创建追踪线
createTrackingLine(positions: Cartesian3[]) { createTrackingLine(positions: Cartesian3[]) {
return new Entity({ return new Entity({
@ -157,4 +165,15 @@ export class DrawPolygon {
}, },
}) })
} }
// 获取多边形的外接矩形
public getRectangle(): Rectangle {
return Rectangle.fromCartesianArray(this.positions)
}
// 获取几何中心
public getCenter(): Cartesian3 {
let rec = this.getRectangle()
return Cartesian3.fromRadians((rec.east + rec.west) / 2, (rec.south + rec.north) / 2)
}
} }

@ -20,6 +20,9 @@ import { cartesian2ToCartesian3 } from '@/utils/map/coordinate'
import { PolylineEntity } from '../geometry/polylineEntity' import { PolylineEntity } from '../geometry/polylineEntity'
import { PointEntity } from '@/utils/map/geometry/pointEntity' import { PointEntity } from '@/utils/map/geometry/pointEntity'
import EditGeometry from '@/utils/map/draw/editGeometry' import EditGeometry from '@/utils/map/draw/editGeometry'
import {getDistance} from "@/utils/map/geocomputation.ts";
import {Angle} from "@/utils/map/angle.ts";
import {TextLabel} from "@/utils/map/geometry/textLabel.ts";
type EntityOptions = { type EntityOptions = {
id?: string id?: string
name?: string name?: string
@ -44,6 +47,8 @@ export default class CreatePolyline {
moveSelectedPoint: PointEntity | null = null moveSelectedPoint: PointEntity | null = null
positions: Cartesian3[] = [] positions: Cartesian3[] = []
bMove: boolean = false bMove: boolean = false
bMeasure: boolean | undefined = false //是否处于测距模式
totalDistance: number = 0
bLongClick: boolean = false bLongClick: boolean = false
clickTimeout: any clickTimeout: any
// layer: CustomDataSource // layer: CustomDataSource
@ -54,13 +59,14 @@ export default class CreatePolyline {
width: 2, width: 2,
color: Color.GREEN, color: Color.GREEN,
} }
constructor(viewer: Viewer, options?: EntityOptions) { constructor(viewer: Viewer, bMeasure: boolean=false,options?: EntityOptions) {
this.viewer = viewer this.viewer = viewer
this.bMeasure = bMeasure;
this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas)
this.polyline = null this.polyline = null
this.trackingLine = null this.trackingLine = null
this.dashLine = null this.dashLine = null
this.totalDistance = 0
this.controlPoints = [] this.controlPoints = []
this.defaultStyle = { ...this.defaultStyle, ...options } this.defaultStyle = { ...this.defaultStyle, ...options }
} }
@ -90,21 +96,14 @@ export default class CreatePolyline {
public end() { public end() {
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK)
} }
//左单击回调事件 //左单击回调事件
private leftClickCallBack = ( private leftClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent) => {
event: ScreenSpaceEventHandler.PositionedEvent,
) => {
const pickedObject = this.viewer.scene.pick(event.position) const pickedObject = this.viewer.scene.pick(event.position)
// console.log(pickedObject)
if (pickedObject) { if (pickedObject) {
//点击同一位置,返回 //点击同一位置,返回
if ( if (pickedObject.id.id === this.polyline?.controlPointsID[this.positions.length - 1])
pickedObject.id.id ===
this.polyline?.controlPointsID[this.positions.length - 1]
) {
return return
// console.log('********click the same point')
}
} }
const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position)
if (cartesian3 != undefined) { if (cartesian3 != undefined) {
@ -117,8 +116,19 @@ export default class CreatePolyline {
this.polyline.addPoint(cartesian3) this.polyline.addPoint(cartesian3)
this.trackingLinePositions[0] = cartesian3 this.trackingLinePositions[0] = cartesian3
this.bMove = true this.bMove = true
this.viewer.scene.requestRender() //刷新 this.viewer.scene.requestRender() //刷新
// 计算2点距离
if(this.positions.length>=2 && this.bMeasure){
let distance = getDistance(this.positions[this.positions.length-1],this.positions[this.positions.length-2])
this.totalDistance += distance
// 计算2点方位角
let azimuth = Angle.getAzimuth(this.positions[this.positions.length-2],this.positions[this.positions.length-1])
// 计算2点的中间点
let midPoint = Cartesian3.midpoint(this.positions[this.positions.length-1],this.positions[this.positions.length-2],new Cartesian3())
// 添加label
let labelText = `距离: ${distance.toFixed(2)}km, 方位角: ${azimuth}°`
new TextLabel(this.viewer, midPoint,labelText)
}
} }
} }
// 移动回调事件 // 移动回调事件
@ -140,13 +150,8 @@ export default class CreatePolyline {
} }
} }
// 左双击回调事件 // 左双击回调事件
private leftDoubleClickCallBack = ( private leftDoubleClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent,) => {
event: ScreenSpaceEventHandler.PositionedEvent,
) => {
// 清除可能已经设置的单击定时器
// clearTimeout(this.clickTimeout)
if (!this.polyline) return if (!this.polyline) return
console.log('**************************** double click')
this.bMove = false this.bMove = false
const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position)
if (cartesian3 != undefined) { if (cartesian3 != undefined) {
@ -156,9 +161,12 @@ export default class CreatePolyline {
} }
} }
if(this.bMeasure){
// 添加总距离label
new TextLabel(this.viewer,this.positions[this.positions.length-1],
`总距离: ${this.totalDistance.toFixed(2)}km`)
}
this.clearEvent() this.clearEvent()
console.log('end:' + this.positions.length.toString())
console.log(this.positions)
//结束绘制进入编辑模式 //结束绘制进入编辑模式
this.polyline.removeControlPoints() this.polyline.removeControlPoints()
const editTool = new EditGeometry(this.viewer, this.polyline.geometry!) const editTool = new EditGeometry(this.viewer, this.polyline.geometry!)
@ -173,7 +181,8 @@ export default class CreatePolyline {
this.viewer.entities.remove(this.controlPoints.pop() as Entity) this.viewer.entities.remove(this.controlPoints.pop() as Entity)
} }
} }
clearEvent() {
private clearEvent() {
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK)
this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE)
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK)

@ -88,7 +88,7 @@ function isOnLineSegment(
/** /**
* *
* @param p1 * @param p1
* @param p2 * @param p2
*/ */

@ -38,13 +38,10 @@ export abstract class BaseGeometry extends CustomDataSource {
* , * ,
* @param pos * @param pos
* @param index 0 * @param index 0
* @param bAddControlPoint
* @bAddControlPoint * @bAddControlPoint
*/ */
public addPoint( public addPoint(pos: Cartesian3, index: number = -1, bAddControlPoint: boolean = true,) {
pos: Cartesian3,
index: number = -1,
bAddControlPoint: boolean = true,
) {
if (index === -1) { if (index === -1) {
//插入尾部 //插入尾部
this.positions.push(pos) this.positions.push(pos)

@ -0,0 +1,64 @@
import {Cartesian3, Entity, Color, Viewer, Cartesian2, HorizontalOrigin, VerticalOrigin, HeightReference} from "cesium";
/**
2024/4/16 11:44
Zhaipeixiu
*/
export type textLabelOptions = {
showBackground?: boolean, //显示背景
backgroundColor?: Color, //背景色
backgroundPadding?: any, //padding值
fillColor: Color,
horizontalOrigin?: any, //水平对齐方式
verticalOrigin?: any, //竖直对齐方式
outlineColor?: any,
outlineWidth?: any
}
export class TextLabel{
_viewer: Viewer|undefined = undefined
_defaultStyle: textLabelOptions = {
showBackground: true, //显示背景
backgroundColor: Color.BLACK, //背景色
backgroundPadding: new Cartesian2(10, 10), //padding值
fillColor: Color.WHITE,
outlineColor: Color.WHITESMOKE,
outlineWidth: 1.0,
horizontalOrigin: HorizontalOrigin.CENTER,//对齐方式
verticalOrigin: VerticalOrigin.CENTER,
}
_cesiumLabel: Entity|undefined = undefined
// 构造函数新建label并显示
constructor(viewer: Viewer, position: Cartesian3, text: string, options?: textLabelOptions) {
this._viewer = viewer
this._defaultStyle = {...this._defaultStyle, ...options}
this._cesiumLabel = new Entity({
position: position,
name: 'default',
label: {
text: text,
scale: .6,
pixelOffset: new Cartesian2(20, -20),
showBackground: this._defaultStyle.showBackground, //显示背景
backgroundColor: this._defaultStyle.backgroundColor, //背景色
backgroundPadding: this._defaultStyle.backgroundPadding, //padding值
fillColor: this._defaultStyle.fillColor,
outlineColor: this._defaultStyle.outlineColor,
outlineWidth: this._defaultStyle.outlineWidth,
horizontalOrigin: this._defaultStyle.horizontalOrigin, //对齐方式
verticalOrigin: this._defaultStyle.verticalOrigin,
heightReference: HeightReference.CLAMP_TO_GROUND
}
})
this._viewer.entities.add(this._cesiumLabel)
}
//移除label
public remove(){
if(this._cesiumLabel !== undefined && this._viewer!==null)
this._viewer.entities.remove(this._cesiumLabel)
}
}
Loading…
Cancel
Save