Files
sdk4.0/src/Obj/Analysis/Contour/index.js

208 lines
6.8 KiB
JavaScript
Raw Normal View History

2025-07-03 13:54:01 +08:00
import Tools from '../../../Tools';
class ContourAnalysis {
/**
* @constructor 等高线分析
* @param sdk
* **/
constructor(sdk, options = {}) {
this.viewer = sdk.viewer
let terrainAvailability = this.viewer.terrainProvider.availability;
if (!terrainAvailability) {
this.error = '未加载地形数据!'
window.ELEMENT && window.ELEMENT.Message({
message: '未加载地形数据!',
type: 'warning',
duration: 1500
});
console.warn(this.error)
return
}
this.positions = options.positions
this.interfaceNum = options.interfaceNum || 25 //内插时均分的数量即沿着边界长或宽均分成n分进行插点默认值25
this.colorFill = options.colorFill || [
"#8CEA00",
"#B7FF4A",
"#FFFF37",
"#FFE66F",
"#FFD1A4",
"#FFCBB3",
"#FFBD9D",
"#FFAD86",
"#FF9D6F",
"#FF8F59",
"#FF8040",
"#FF5809",
"#F75000",
"#D94600",
"#BB3D00",
"#A23400",
"#842B00",
"#642100",
"#4D0000",
"#2F0000",
]; //等高线赋值颜色内含default值
this.countorLineList = Cesium.defaultValue(options.countorLineList, []);
YJ.Analysis.Analyses.push(this)
this.createNewLine();
}
createNewLine() {
ContourAnalysis.interpolatePoint(this);
}
//利用turf在box内进行插点
static interpolatePoint(that) {
let curPoints = that.positions
let features = [];
const boundaryCoord = {
minX: 360,
maxX: -360,
minY: 180,
maxY: -180,
}; //绘制几何图形的外围矩形box
for (let index = 0; index < curPoints.length; index++) {
const element = Cesium.Cartesian3.fromDegrees(curPoints[index].lng, curPoints[index].lat, curPoints[index].alt);
let ellipsoid = that.viewer.scene.globe.ellipsoid;
let cartographic = ellipsoid.cartesianToCartographic(element);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let lng = Cesium.Math.toDegrees(cartographic.longitude);
boundaryCoord.maxY = Math.max(lat, boundaryCoord.maxY);
boundaryCoord.minY = Math.min(lat, boundaryCoord.minY);
boundaryCoord.maxX = Math.max(lng, boundaryCoord.maxX);
boundaryCoord.minX = Math.min(lng, boundaryCoord.minX);
let curFeature = {
type: "Feature",
properties: {},
geometry: {
type: "Point",
coordinates: [lng, lat],
},
};
features.push(curFeature);
}
let boundaryJson = {
type: "FeatureCollection",
features: features,
};
turf.featureEach(boundaryJson, function (point) {
point.properties.height = 0;
});
let options = {
gridType: "points",
property: "height",
units: "kilometers",
};
let from = turf.point([boundaryCoord.minX, boundaryCoord.minY]);
let to = turf.point([boundaryCoord.maxX, boundaryCoord.maxY]);
let diagonalDistance = turf.rhumbDistance(from, to, {
units: "kilometers",
});
let grid = turf.interpolate(
boundaryJson,
diagonalDistance / that.interfaceNum,
options
);
let minHeight = 10000000; //最低点高程值
let maxHeight = -100000000; //最高点高程值
turf.featureEach(grid, function (point) {
let pos = point.geometry.coordinates;
let cartographic = Cesium.Cartographic.fromDegrees(pos[0], pos[1]);
let height = that.viewer.scene.globe.getHeight(cartographic);
maxHeight = Math.max(height, maxHeight);
minHeight = Math.min(height, minHeight);
point.properties.height = height;
});
let breaks = [];
let stepCount = that.colorFill.length - 1;
let step = (maxHeight - minHeight) / stepCount;
for (let index = 0; index < stepCount + 1; index++) {
breaks.push(Math.ceil(minHeight + step * index));
}
// console.log('grid', grid)
let linesJson = turf.isolines(grid, breaks, { zProperty: "height" });
let _countorLine = Cesium.GeoJsonDataSource.load(linesJson, {
clampToGround: true,
});
// console.log(linesJson)
_countorLine.then(function (dataSource) {
console.log(dataSource)
that.countorLine = dataSource; //最终计算生成的等高线对象GeoJsonDataSource
that.countorLineList.push(dataSource); //等高线数组
that.viewer.dataSources.add(dataSource);
let entities = dataSource.entities.values;
for (let index = 0; index < entities.length; index++) {
const element = entities[index];
let center = getPolylineCenter(element.polyline);
element.position = center;
// dataSource.entities.add(new Cesium.Entity({
// position: center,
// label: {
// text: element.properties.height._value + '',
// font: '20px Microsoft YaHei',
// fillColor: Cesium.Color.fromCssColorString('#f1d20c'),
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
// },
// }))
// element.label = new Cesium.LabelGraphics({
// })
let cur_index = that.getObjectIndex(
breaks,
element.properties.height._value
);
if (cur_index) {
element.polyline.material = Cesium.Color.fromCssColorString(
that.colorFill[cur_index - 1]
);
}
}
});
function getPolylineCenter(polyline) {
let tools = new Tools()
let positions = polyline.positions;
let length = positions._value.length;
let array = []
for (let i = 0; i < length; i++) {
let pos = tools.cartesian3Towgs84(positions._value[i], that.viewer)
array.push([pos.lng, pos.lat])
}
let line = turf.lineString(array);
let distance = turf.length(line, { units: "kilometers" });
let along = turf.along(line, distance/2, { units: "kilometers" });
return Cesium.Cartesian3.fromDegrees(along.geometry.coordinates[0], along.geometry.coordinates[1], 0);
}
}
/**
* 返回随机插入的数在数组中的位置
* @param {*} arr 元数组
* @param {*} num 随机数
* @returns 序号
* @example getObjectIndex([0,218,325,333,444],354)=>4;
*/
getObjectIndex(arr, num) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] > num) {
return i;
}
}
}
clear(countorLine) {
if (countorLine) {
this.viewer.dataSources.remove(countorLine);
let index = this.countorLineList.indexOf(countorLine);
this.countorLineList.splice(index, 1);
}
}
destroy() {
this.countorLineList.forEach((element) => {
this.viewer.dataSources.remove(element);
});
this.countorLineList = [];
}
}
export default ContourAnalysis;