import Draw from "../../../Draw/draw"; import MouseEvent from "../../../Event"; import MouseTip from "../../../MouseTip"; import Dialog from '../../../BaseDialog'; import { html } from "./_element"; class Profile extends Draw { /** * @constructor 剖面分析 * @param sdk **/ constructor(sdk, _Dialog = {}) { window.addEventListener("resize", () => { this.echartsObject && this.echartsObject.resize(); }); super(sdk) this.viewer = sdk.viewer; this.Dialog = _Dialog YJ.Analysis.Analyses.push(this) Profile.create(this) } static create(that) { this._currentId = Cesium.createGuid() let id = this._currentId that.clean() if (YJ.Measure.GetMeasureStatus()) { console.warn('上一次测量未结束') } else { YJ.Measure.SetMeasureStatus(true) that.tip = new MouseTip('左键确定,右键取消', that.sdk) that.event = new MouseEvent(that.sdk) that.positions = [] that.points_ids = [] //存放左键点击时临时添加的point的id let cache_positions = [] let car = undefined that.event.mouse_left(async (movement, cartesian) => { try { if (!that.entityHasCreated) { Profile.create_polyline(that) } cache_positions.push(cartesian) that.points_ids.push(that.create_point(cartesian,)) if (cache_positions.length == 2) { that.end() let positions = [] cache_positions.forEach((item) => { positions.push(that.cartesian3Towgs84(item, that.viewer)) }) Profile.interPoints(that).then((points) => { if (this._currentId && this._currentId === id) { that._DialogObject ? Profile.initEcharts(that, points) : Profile.edit(that, points) } }) } } catch (error) { console.log(error) } }) that.event.mouse_right((movement, cartesian) => { let positions = [] cache_positions = [] that.clean() }) that.event.mouse_move((movement, cartesian) => { that.positions = cache_positions.concat(cartesian) that.tip.setPosition( cartesian, movement.endPosition.x, movement.endPosition.y ) }) that.event.gesture_pinck_start((movement, cartesian) => { let startTime = new Date() that.event.gesture_pinck_end(() => { let endTime = new Date() if (endTime - startTime >= 500) { let positions = [] cache_positions = [] that.end() } }) }) } } static create_polyline(that) { that.entityHasCreated = true let id = that.randomString() that.polyline = that.viewer.entities.add( new Cesium.Entity({ id: id, polyline: { positions: new Cesium.CallbackProperty(() => { return that.positions }, false), width: 5, material: Cesium.Color.fromCssColorString(that.color), clampToGround: true, zIndex: 99999999 }, }) ) return id } /** * 线段插值点 */ static async interPoints(that) { let viewer = that.viewer let positions = that.positions let positionsCartographic = [] let positions84 = []; for (let index = 0; index < positions.length; index++) { const element = positions[index]; let cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(element); positionsCartographic.push(cartographic); let pos84 = that.cartesian3Towgs84(element, viewer) positions84.push(pos84); } let positions_Inter = []; let height = await that.getClampToHeight({ lng: positions84[0].lng, lat: positions84[0].lat }); positions_Inter.push({ position: { lng: positions84[0].lng, lat: positions84[0].lat, height: height }, distance: 0, }); for (let i = 0; i < positionsCartographic.length - 1; i++) { let line = turf.lineString([[positions84[i].lng, positions84[i].lat], [positions84[i + 1].lng, positions84[i + 1].lat]]); let totalDistance = turf.length(line, { units: 'kilometers' }); const m_Cartographic0 = positionsCartographic[i]; const m_Cartographic1 = positionsCartographic[i + 1]; let a = Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) * 10000000; let b = Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) * 10000000; //等距采样 if (a > b) b = a; let length = parseInt(b / 2); if (length > 150) length = 150; if (length < 2) length = 2; let distance = totalDistance / (length - 1) for (let j = 0; j < length - 1; j++) { let start = j * distance let stop = (j + 1) * distance let sliced = await turf.lineSliceAlong(line, start, stop, { units: 'kilometers' }); let lng = sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1][0] let lat = sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1][1] let height = await that.getClampToHeight({ lng: lng, lat: lat }); positions_Inter.push({ position: { lng: lng, lat: lat, height: height }, distance: stop * 1000, }); } } return positions_Inter } static async edit(that, points) { if (that._DialogObject && that._DialogObject.close) { that._DialogObject.close() that._DialogObject = null } that._DialogObject = await new Dialog(that.sdk.viewer._container, { title: '剖面分析', left: '180px', top: '100px', closeCallBack: () => { that.clean() that.Dialog.closeCallBack && that.Dialog.closeCallBack() }, }) await that._DialogObject.init() that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' profile' let contentElm = document.createElement('div'); contentElm.innerHTML = html() that._DialogObject.contentAppChild(contentElm) let resetBtn = document.createElement('button'); resetBtn.innerHTML = '重新绘制' resetBtn.style.width = 'auto' resetBtn.addEventListener('click', () => { Profile.create(that) Profile.initEcharts(that) }) that._DialogObject.footAppChild(resetBtn) Profile.initEcharts(that, points) } static initEcharts(that, points) { let datas = [], coords = []; const pointsData = points; let option if (pointsData) { const maxDistance = pointsData[pointsData.length - 1].distance; let xAixMax = Math.ceil(maxDistance); for (let index = 0; index < pointsData.length; index++) { const element = pointsData[index]; if (element.position.height === void 0) { continue } const curData = [ element.distance.toFixed(2), element.position.height.toFixed(2), ]; datas.push(curData); const curCoords = [element.position.lng, element.position.lat]; coords.push(curCoords); } const pointOption = { show: true, pixelSize: 10, color: Cesium.Color.GREEN, outlineColor: Cesium.Color.SKYBLUE, outlineWidth: 3, disableDepthTestDistance: Number.POSITIVE_INFINITY }; const ele = that._DialogObject._element.content.getElementsByClassName("profile-echarts")[0]; that.echartsObject = echarts.init(ele); option = { tooltip: { trigger: "axis", textStyle: { align: "left", }, formatter(params) { const xy = coords[params[0].dataIndex]; const tipData = params[0]["data"]; if (!that.tipEntity) { that.tipEntity = that.sdk.viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees( xy[0], xy[1], Number(tipData[1]) ), point: pointOption, }); } else { that.tipEntity.position = Cesium.Cartesian3.fromDegrees( xy[0], xy[1], Number(tipData[1]) ); } return ( "距离:" + tipData[0] + "m
" + "高度:" + tipData[1] + "m
" + "坐标:" + xy[0].toFixed(5) + "," + xy[1].toFixed(5) ); }, }, grid: { top: 40, bottom: 20, left: 55, right: 30 }, calculable: true, xAxis: [ { type: "value", max: xAixMax, scale: true, axisLabel: { color: '#ffffff' }, axisLine: { lineStyle: { color: "#ffffff" } } }, ], yAxis: [ { type: "value", scale: true, axisLabel: { color: '#ffffff' }, axisLine: { lineStyle: { color: "#ffffff" } } }, ], series: [ { name: "ProfileLine", type: "line", data: datas, smooth: true, itemStyle: { normal: { color: "#39FDA1", }, }, lineStyle: { normal: { width: 3, color: { type: "linear", x: 0, y: 0, x2: 1, y2: 0, colorStops: [ { offset: 0, color: "rgba(85,254,139,1)", // 0% 处的颜色 }, { offset: 0.5, color: "rgba(7,252,202,1)", // 100% 处的颜色 }, { offset: 1, color: "rgba(14,245,210,1)", // 100% 处的颜色 }, ], globalCoord: false, // 缺省为 false }, }, }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient( 0, 0, 0, 1, [ { offset: 0, color: "rgba(102,153,255,1)", }, { offset: 0.8, color: "rgba(102,153,255,0.08)", }, { offset: 1, color: "rgba(9,173,208,0.15)", }, ], false ), shadowColor: "rgba(14,245,210,1)", //阴影颜色 shadowBlur: 20, }, }, markPoint: { data: [ { type: "max", name: "最高点", label: { color: '#ffffff', } }, { type: "min", name: "最低点", label: { color: '#ffffff', } }, ], }, }, ], }; } else { const ele = that._DialogObject._element.content.getElementsByClassName("profile-echarts")[0]; that.echartsObject = echarts.init(ele); option = { tooltip: { trigger: "axis", textStyle: { align: "left", } }, grid: { top: 40, bottom: 20, left: 55, right: 30 }, calculable: true, xAxis: [ { type: "value", scale: true, axisLabel: { color: '#ffffff' }, axisLine: { lineStyle: { color: "#ffffff" } } }, ], yAxis: [ { type: "value", scale: true, axisLabel: { color: '#ffffff' }, axisLine: { lineStyle: { color: "#ffffff" } } }, ], series: [ { name: "ProfileLine", type: "line", data: [], smooth: true, itemStyle: { normal: { color: "#39FDA1", }, }, lineStyle: { normal: { width: 3, color: { type: "linear", x: 0, y: 0, x2: 1, y2: 0, colorStops: [ { offset: 0, color: "rgba(85,254,139,1)", // 0% 处的颜色 }, { offset: 0.5, color: "rgba(7,252,202,1)", // 100% 处的颜色 }, { offset: 1, color: "rgba(14,245,210,1)", // 100% 处的颜色 }, ], globalCoord: false, // 缺省为 false }, }, }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient( 0, 0, 0, 1, [ { offset: 0, color: "rgba(102,153,255,1)", }, { offset: 0.8, color: "rgba(102,153,255,0.08)", }, { offset: 1, color: "rgba(9,173,208,0.15)", }, ], false ), shadowColor: "rgba(14,245,210,1)", //阴影颜色 shadowBlur: 20, }, }, markPoint: { data: [ { type: "max", name: "最高点", label: { color: '#ffffff', } }, { type: "min", name: "最低点", label: { color: '#ffffff', } }, ], }, }, ], }; } that.echartsObject.setOption(option); } clean() { this.end() this._currentId = null this.entityHasCreated = false this.polyline && this.viewer.entities.remove(this.polyline) this.tipEntity && this.viewer.entities.remove(this.tipEntity) this.polyline = null this.tipEntity = null } destroy() { this.clean() if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } } } // const Profile = function (viewer, callback) { // if (!viewer) throw new Error("no viewer object!"); // if (window.profileEntities && window.profileEntities.length > 0) { // window.profileEntities.forEach((element) => { // window.viewer.entities.remove(element); // }); // } // window.profileEntities = []; // CreatePolyline( // viewer, // window.profileEntities, // { color: Cesium.Color.RED, width: 2 }, // function (e) { // e.polyline.clampToGround = true; // console.log(e.pottingPoint); // let points = interPoints(viewer, e.pottingPoint, [e]); // console.log(points); // if (typeof callback == "function") callback(points); // } // ); // }; // /** // * 线段插值点 // * @param {*} viewer // * @param {*} positions 线段节点集合 // * @param {*} objectsToExclude 高度采集时排除的对象集合 // * @returns 经纬度点集合,包含距离值 // */ // function interPoints(viewer, positions, objectsToExclude) { // let positionsCartographic = []; // let terrainSamplePositions = []; // for (let index = 0; index < positions.length; index++) { // const element = positions[index]; // let ellipsoid = viewer.scene.globe.ellipsoid; // let cartographic = ellipsoid.cartesianToCartographic(element); // positionsCartographic.push(cartographic); // } // for (let i = 0; i < positionsCartographic.length; i++) { // const m_Cartographic0 = positionsCartographic[i]; // const m_Cartographic1 = positionsCartographic[i + 1]; // if (m_Cartographic1) { // let a = // Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) * // 10000000; // let b = // Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) * // 10000000; // //等距采样 // if (a > b) b = a; // let length = parseInt(b / 2); // if (length > 1000) length = 1000; // if (length < 2) length = 2; // for (let j = 0; j < length; j++) { // terrainSamplePositions.push( // new Cesium.Cartographic( // Cesium.Math.lerp( // m_Cartographic0.longitude, // m_Cartographic1.longitude, // j / (length - 1) // ), // Cesium.Math.lerp( // m_Cartographic0.latitude, // m_Cartographic1.latitude, // j / (length - 1) // ) // ) // ); // } // terrainSamplePositions.pop(); // } else { // terrainSamplePositions.push(m_Cartographic0); // } // } // let positions_Inter = []; // let distance = 0; // for (let n = 0; n < terrainSamplePositions.length; n++) { // //地理坐标(弧度)转经纬度坐标 // let curCartographic = terrainSamplePositions[n]; // let height = viewer.scene.sampleHeight(curCartographic, objectsToExclude); // const lon = (curCartographic.longitude / Math.PI) * 180; // const lat = (curCartographic.latitude / Math.PI) * 180; // let point = Cesium.Cartesian3.fromDegrees(lon, lat, height); // let preCartographic = terrainSamplePositions[n - 1]; // if (preCartographic) { // const lon1 = (preCartographic.longitude / Math.PI) * 180; // const lat1 = (preCartographic.latitude / Math.PI) * 180; // let point1 = Cesium.Cartesian3.fromDegrees(lon1, lat1, height); // let curDis = Cesium.Cartesian3.distance(point1, point); // distance += curDis; // } // positions_Inter.push({ // position: { lon: lon, lat: lat, height: height }, // distance: distance, // }); // } // return positions_Inter; // } export default Profile;