/* 引入Cesium */ // import * as Cesium from 'Cesium'; /* 引入算法 */ import * as turf from "@turf/turf"; /** * 限高分析 */ class HeightLimit { /** * 默认初始化 * @param {Object} viewer 三维场景 */ constructor(viewer) { if (!viewer) throw new Cesium.DeveloperError('no viewer object!'); this._viewer = viewer; this.targetY = 0; } /** * 这里主要是为了添加一个高出地面的 polygon , 用到的经纬度数据和需要校验的建筑物数据一样 * @ignore 忽略注释,注释不生成Doc * @param {Object} options */ _setPolygon(options) { let _self = this; _self.HiePolygon = _self._viewer.entities.add({ polygon: { hierarchy: new Cesium.PolygonHierarchy(_self.data), material: _self._handleColor('#FFF8DC', options.alpha), height: new Cesium.CallbackProperty(_self._createPolygonUpdateFunction(), false), perPositionHeight: false, outline: true, outlineColor: _self._handleColor('red', options.alpha), outlineWidth: 1.0, } }); } /** * @ignore 忽略注释,注释不生成Doc */ _createPolygonUpdateFunction() { let _self = this; return function() { return _self.targetY; }; } /** * @ignore 忽略注释,注释不生成Doc * @param {Object} color * @param {Object} alpha */ _handleColor(color, alpha) { return Cesium.Color.fromCssColorString(color).withAlpha(alpha || 1); } /** * @ignore 忽略注释,注释不生成Doc * 获取最小高度 */ _getMinHeight(points) { let height = 0; let positions = points.map(point => { let _height = point[2] || 0; height = _height; if (_height < height) { height = _height; } }); return height; } } /** * 通用对外公开函数 */ Object.assign(HeightLimit.prototype, /** @lends HeightLimit.prototype */ { /** * 绘制限高区域 */ addPrimitive(points, options) { this.removePrimitive(); options = options || {}; options.height = Cesium.defaultValue(options.height, 50); //图上选点获取最小高度 options.baseHeight = Cesium.defaultValue(options.baseHeight, 50); // //根据坐标获取最小高度 // options.baseHeight = this._getMinHeight(points); options.color = Cesium.defaultValue(options.color, 'red'); options.alpha = Cesium.defaultValue(options.alpha, 0.6); /* 转换坐标 */ let positions = points.map(point => { return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0); }); let _self = this; _self.data = positions; _self.baseHeight = options.baseHeight; _self.targetY = options.baseHeight + options.height; let polygonInstance = new Cesium.GeometryInstance({ geometry: new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy(_self.data), height: _self.baseHeight, //分层底部海拔 extrudedHeight: _self.baseHeight + 3000, //分层顶部海拔 }), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromCssColorString(options.color).withAlpha(options.alpha) ), //设置高亮颜色 show: new Cesium.ShowGeometryInstanceAttribute(true), //设置初始化后是否显示 } }); _self.limitHeightPrimitive = _self._viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ //ClassificationPrimitive 用来生成可以穿透 geometryInstances: polygonInstance, releaseGeometryInstances: false, classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, //只绘制在3dtiles上 }) ); // 这里主要是为了添加一个高出地面的 polygon , 用到的经纬度数据和需要校验的建筑物数据一样 _self._setPolygon(options) }, /** * 移除限高分析 */ removePrimitive() { if (this.HiePolygon) { this._viewer.entities.remove(this.HiePolygon); //移除图层 } if (this.limitHeightPrimitive) { this._viewer.scene.primitives.remove(this.limitHeightPrimitive); //移除图层 } }, /** * 高度变化 * @param {Object} height */ changeHeight(height) { if (!this.limitHeightPrimitive) return; // this._height = height - this.baseHeight; this.targetY = this.baseHeight + height; let cartographic = Cesium.Cartographic.fromCartesian(this.limitHeightPrimitive._primitive._boundingSpheres[0].center); let surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, this.baseHeight); let offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, this.baseHeight + height); let translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); this.limitHeightPrimitive._primitive.modelMatrix = Cesium.Matrix4.fromTranslation(translation); }, }); export default HeightLimit;