637 lines
19 KiB
JavaScript
637 lines
19 KiB
JavaScript
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; |