Files
sdk4.0/src/Obj/Analysis/Profile/index.js
2025-07-03 13:54:01 +08:00

637 lines
19 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.

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 = '<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>重新绘制'
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<br>" +
"高度:" +
tipData[1] +
"m<br>" +
"坐标:" +
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;