Files
sdk4.0/src/Measure/MeasureDistance/index.js
2025-07-03 13:54:01 +08:00

327 lines
9.5 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"
class MeasureDistance 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 = []
}
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 computeDisByTowPoint(p1, p2) {
let d = this.computeDistance([p1, p2])
let meters = 10
let createLabel = (distance) => {
if(this._isDestroy) {
return
}
let label = this.getLabel("贴地距离:" + Number(distance).toFixed(2) + "米")
label.pixelOffset = new Cesium.Cartesian2(
0, -(32)
)
this.ids.push(MeasureDistance.create_point(Cesium.Cartesian3.fromDegrees(p2.lng, p2.lat, p2.alt), {label: label}, this))
}
let start = async (meters) => {
let res = this.chunkLine([p1, p2], meters)
let coordinates = []
res.forEach((Feature, index) => {
if (index === 0) {
coordinates = [...Feature.geometry.coordinates]
} else {
coordinates.push(Feature.geometry.coordinates[1])
}
})
let arr = []
for (const item of coordinates) {
const index = coordinates.indexOf(item);
let r = await this.sampleHeight({lng: item[0], lat: item[1], alt: 0}, index)
arr.push(r)
}
let total_length = 0
let l = arr.length - 1
arr.forEach((item, index) => {
if (index !== l) {
let d1 = this.computeDistance([item.position, arr[index + 1].position])
let d2 = Math.abs(item.position.alt - arr[index + 1].position.alt)
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
total_length += d3
}
})
createLabel(total_length)
}
//暂时固定取20个点
if (d > 20) {//大于20m时固定取20个点
meters = d / 20
await start(meters)
} else if (d < 1) {
//不计算
createLabel(d)
} else {//小于20m的时候
meters = 1
await start(meters)
}
}
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.computeDistance([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 = async (movement, car) => {
if (this.ids.length === 0) {
this.polyline_id = (MeasureDistance.createPolyline(this))
this.start_id = MeasureDistance.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)
this.cachePositions.push(car)
await this.computeDisByTowPoint(pre_p, cur_point)
} else {
this.cachePositions.push(car)
this.ids.push(MeasureDistance.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.cachePositions.length) {
this.positions = this.cachePositions
this.end_id = MeasureDistance.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) => {
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
this.positions = this.cachePositions.concat(car)
// if (this.cachePositions.length) {
// let cur_point = this.cartesian3Towgs84(car, this.viewer)
// let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
// let cur_len = this.computeDistance([cur_point, pre_p])
// let text = "当前投影距离:" + cur_len + " 米"
// // this.tip.set_text(text)
// }
})
this.event.mouse_right(rightEvent)
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)
}
})
})
}
}
/**
* 清除测量
*/
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 MeasureDistance