327 lines
9.5 KiB
JavaScript
327 lines
9.5 KiB
JavaScript
/**
|
||
* @name: index
|
||
* @author: Administrator
|
||
* @date: 2022-07-11 10:31
|
||
* @description:index
|
||
* @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.computeDistance2([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.computeDistance2([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 > 2) {//大于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 height = await this.getClampToHeight(p1, [...this.sdk.viewer.entities.values])
|
||
p1.alt = 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 = 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.computeDistance2([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
|