213 lines
6.8 KiB
JavaScript
213 lines
6.8 KiB
JavaScript
|
||
|
||
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.AnalysesResults.push(this)
|
||
this.createNewLine();
|
||
}
|
||
|
||
get type() {
|
||
return 'ContourAnalysis'
|
||
}
|
||
|
||
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; |