Files
sdk4.0/src/Measure/MeasureDistance/index.js

327 lines
9.5 KiB
JavaScript
Raw Normal View History

2025-07-03 13:54:01 +08:00
/**
* @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