/** * @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.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