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;