Files
sdk4.0/src/Measure/MeasureSlopeDistance/index.js
2025-07-15 10:37:23 +08:00

317 lines
9.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @name: index
* @author: Administrator
* @date: 2022-07-11 10:31
* @descriptionindex
* @update: 2022-07-11 10:31
*/
import Measure from "../index"
import MouseEvent from "../../Event";
class MeasureSlopeDistance extends Measure {
/**
* @constructor
* @param sdk
* @description 坡度测量
* */
constructor(sdk, options = {}) {
super(sdk, options)
this.options.color = this.options.color || "#00ffff"
this.start_id = ""
this.end_id = ""
this.polyline_id = ""
this.clampPositions = []
this.event = new MouseEvent(sdk)
}
async clampToGroundMeasure(meters, cb) {
let positions = []
this.ids.forEach((id, index) => {
let p = this.viewer.entities.getById(id).position.getValue()
positions.push(this.cartesian3Towgs84(p, this.viewer))
})
let res = this.chunkLine(positions, meters)
let coordinates = []
res.forEach((Feature, index) => {
if (index === 0) {
coordinates = [...Feature.geometry.coordinates]
} else {
coordinates.push(Feature.geometry.coordinates[1])
}
})
let total = coordinates.length
for (const item of coordinates) {
const index = coordinates.indexOf(item);
let r = await this.getHeight({ lng: item[0], lat: item[1], alt: 0 }, index, total,)
cb(null, r)
}
}
async sampleHeight(p1, index) {
let p2 = await this.sampleHeightMostDetailed([p1])
p1.alt = p2[0].height
return { position: p1, index }
}
async getHeight(p1, index, total) {
let p2 = await this.sampleHeightMostDetailed([p1])
p1.alt = p2[0].height
this.clampPositions.push({ position: p1, index })
if (total === this.clampPositions.length) {
let total_length = this.startCompute()
return { total, current: this.clampPositions.length, total_length }
}
return { total, current: this.clampPositions.length, }
}
startCompute() {
this.clampPositions.sort(function (a, b) {
return a.index < b.index
})
let total_length = 0
let l = this.clampPositions.length - 1
this.clampPositions.forEach((item, index) => {
if (index !== l) {
let d1 = this.computeDistance2([item.position, this.clampPositions[index + 1].position])
let d2 = Math.abs(item.position.alt - this.clampPositions[index + 1].position.alt)
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
total_length += d3
}
})
return Number(total_length.toFixed(2))
}
static createPolyline(that) {
let id = that.randomString()
that.viewer.entities.add(new Cesium.Entity({
id,
polyline: {
positions: new Cesium.CallbackProperty(() => {
return that.positions
}, false),
clampToGround: true,
width: 3,
material: new Cesium.PolylineDashMaterialProperty({
color: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
dashLength: 20, //短划线长度
}),
zIndex: 99999999
}
}))
return id
}
static create_point(cartesian, {
label, image = "point.png",
width,
height
}, that) {
let id = that.randomString()
let p = that.cartesian3Towgs84(cartesian, that.viewer)
if (label) {
label.pixelOffset = new Cesium.Cartesian2(
0, -(height || 32)
)
}
that.viewer.entities.add(
new Cesium.Entity({
id: id,
label,
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
billboard: {
image: that.getSourceRootPath() + '/img/' + image,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width,
height
}
})
)
return id
}
getLabel(text) {
return {
text: text || '',
//标注文字描述
font: '20px Microsoft YaHei',
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
// distanceDisplayCondition: this.distanceDisplayCondition,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
// disableDepthTestDistance: this.disableDepthTestDistance,
}
}
/**
* 开始测量
*/
start() {
if (!YJ.Measure.GetMeasureStatus()) {
super.start()
this.positions = []
this.cachePositions = []
let leftEvent = (movement, car) => {
if (this.ids.length === 0) {
this.polyline_id = (MeasureSlopeDistance.createPolyline(this))
this.start_id = MeasureSlopeDistance.create_point(car, {
image: "start1.png", width: 30, height: 38, label: this.getLabel("")
}, this)
//创建起点
}
this.tip.setPosition(car, movement.position.x, movement.position.y)
this.positions = this.cachePositions.concat(car)
if (this.ids.length !== 0) {
let cur_point = this.cartesian3Towgs84(car, this.viewer)
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
if (cur_point.lng !== pre_p.lng || cur_point.lat !== pre_p.lat || cur_point.alt !== pre_p.alt) {
this.cachePositions.push(car)
//计算坡度
this.computeAngle(pre_p, cur_point)
}
} else {
this.cachePositions.push(car)
this.ids.push(MeasureSlopeDistance.create_point(car, {}, this))
let startPoint = this.viewer.entities.getById(this.ids[0])
if(startPoint) {
startPoint.billboard.show = false
}
}
}
let rightEvent = (movement, car) => {
if (this.ids.length !== 0) {
// let cur_point = this.cartesian3Towgs84(car, this.viewer)
// let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
// if (cur_point.lng !== pre_p.lng || cur_point.lat !== pre_p.lat || cur_point.alt !== pre_p.alt) {
// this.cachePositions.push(car)
// //计算坡度
// this.computeAngle(pre_p, cur_point)
// }
} else {
// this.cachePositions.push(car)
this.ids.push(MeasureSlopeDistance.create_point(car, {}, this))
}
if (this.cachePositions.length) {
this.positions = this.cachePositions
this.end_id = MeasureSlopeDistance.create_point(this.cachePositions[this.cachePositions.length - 1], {
image: "end1.png",
width: 30,
height: 38,
}, this)
let endPoint = this.viewer.entities.getById(this.ids[this.ids.length-1])
if(endPoint) {
endPoint.billboard.show = false
}
}
if (this.cachePositions.length < 2) {
this.destroy()
YJ.Measure.Measures.pop()//弹出测量实体
}
this.end()
}
this.event.mouse_left(leftEvent)
this.event.mouse_move((movement, car) => {
movement.endPosition.y += 2
let position = movement.endPosition
let cartesian = this.viewer.scene.pickPosition(position)
if (!cartesian) {
const ray = this.viewer.camera.getPickRay(position); //相交的射线
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
}
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
this.positions = this.cachePositions.concat(cartesian)
if (this.cachePositions.length) {
let cur_point = this.cartesian3Towgs84(cartesian, this.viewer)
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
let d1 = this.computeDistance2([pre_p, cur_point])
let d2 = Math.abs(pre_p.alt - cur_point.alt)
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
let cosAlpha = d1 / d3
let acos = Math.acos(cosAlpha)
let angle = this.radiansToDegrees(acos)
let label = "坡度:" + angle.toFixed(2) + "°"
this.tip.set_text(label)
}
})
this.event.mouse_right(rightEvent)
this.event.mouse_right_keyboard_ctrl((movement, car) => {
if (this.cachePositions.length) {
this.cachePositions.pop()
this.remove_entity(this.ids.pop())
}
})
this.event.gesture_pinck_start((movement, cartesian) => {
let startTime = new Date()
let pos = {
position: {
x: (movement.position1.x + movement.position2.x) / 2,
y: (movement.position1.y + movement.position2.y) / 2
}
}
this.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
rightEvent(pos, cartesian)
}
else {
leftEvent(pos, cartesian)
}
})
})
}
}
computeAngle(start, end) {
let d1 = this.computeDistance2([start, end])
let d2 = Math.abs(start.alt - end.alt)
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
let cosAlpha = d1 / d3
let acos = Math.acos(cosAlpha)
let angle = this.radiansToDegrees(acos)
let label = this.getLabel("坡度:" + angle.toFixed(2) + "°")
label.pixelOffset = new Cesium.Cartesian2(
0, -(32)
)
this.ids.push(MeasureSlopeDistance.create_point(Cesium.Cartesian3.fromDegrees(end.lng, end.lat, end.alt), {label: label}, this))
}
/**
* 清除测量
*/
destroy() {
[this.polyline_id, this.end_id, this.start_id, ...this.ids].forEach(id => {
this.remove_entity(id)
})
super.destroy()
}
/**
* 结束测量
*/
end() {
// YJ.Measure.SetMeasureStatus(false)
// this.tip.destroy()
// this.event.destroy()
super.end()
// this.setPickStatus(this.pickStatus.pick)
}
}
export default MeasureSlopeDistance