123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- /* 引入Cesium */
- // import * as Cesium from 'Cesium';
- /* 引入算法 */
- import * as turf from "@turf/turf";
- import CreateRemindertip from "../common/ReminderTip.js";
- import CoordTransform from "../common/CoordTransform.js";
- import {
- setSessionid
- } from "../common/common.js";
- /**
- * 坡度坡向分析类
- */
- class SlopeAspect {
- /**
- * 默认初始化
- * @param {Object} viewer 三维场景
- */
- constructor(viewer) {
- if (!viewer) throw new Cesium.DeveloperError('no viewer object!');
- this._viewer = viewer;
- this.result = []; //存储创建的坡度分析结果,primitive集合
- this.handler = undefined;
- this.toolTip = "";
- }
- /**
- * 坡度提示信息
- * @ignore
- */
- _openTip() {
- let _self = this;
- this.handler = new Cesium.ScreenSpaceEventHandler(_self._viewer.canvas);
- this.handler.setInputAction(function(movement) {
- let endPos = movement.endPosition;
- var pick = _self._viewer.scene.pick(endPos);
- if (pick && pick.id && pick.id.type === "SlopeAspect") {
- _self.toolTip = pick.id.value.toFixed(2);
- CreateRemindertip(_self.toolTip, endPos, true);
- } else {
- _self.toolTip = "";
- CreateRemindertip(_self.toolTip, endPos, false);
- }
- }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- }
- /**
- * @ignore
- * @param {Object} gridSquare
- */
- _createEllipse(gridSquare) {
- let _self = this;
- let boxResults = [];
- for (let index = 0; index < gridSquare.features.length; index++) {
- const feature = gridSquare.features[index];
- const coordinates = feature.geometry.coordinates[0];
- const centerdegree = [
- (coordinates[0][0] + coordinates[2][0]) / 2,
- (coordinates[0][1] + coordinates[2][1]) / 2,
- ];
- let centerCartographic = Cesium.Cartographic.fromDegrees(
- centerdegree[0],
- centerdegree[1]
- );
- boxResults.push(centerCartographic);
- for (let i = 0; i < coordinates.length; i++) {
- const coord = coordinates[i];
- let cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1]);
- boxResults.push(cartographic);
- const coord1 = coordinates[i + 1];
- if (coord1) {
- let newCoord = [(coord[0] + coord1[0]) / 2, (coord[1] + coord1[1]) / 2];
- let newCartographic = Cesium.Cartographic.fromDegrees(newCoord[0], newCoord[1]);
- boxResults.push(newCartographic);
- }
- }
- }
- Cesium.sampleTerrainMostDetailed(
- _self._viewer.scene.terrainProvider,
- boxResults
- ).then((updatePositions) => {
- let arrr = [];
- let ellipseResults = updatePositions.reduce(function(pre, item, index, updatePositions) {
- var begin = index * 10;
- var end = begin + 10;
- var res = updatePositions.slice(begin, end);
- if (res.length != 0) {
- arrr[index] = res;
- }
- return arrr;
- }, []);
- _self._calculateSlope(ellipseResults);
- _self._openTip();
- });
- }
- /**
- * @ignore
- * @param {Object} points
- * @param {Object} color
- */
- _createPolygonInsrance(points, color) {
- let positions = [];
- for (let index = 1; index < points.length - 1; index++) {
- const element = points[index];
- positions.push(Cesium.Cartographic.toCartesian(element));
- }
- let polygon = new Cesium.PolygonGeometry({
- polygonHierarchy: new Cesium.PolygonHierarchy(positions),
- });
- let polygonInstance = new Cesium.GeometryInstance({
- geometry: polygon,
- attributes: {
- color: Cesium.ColorGeometryInstanceAttribute.fromColor(
- Cesium.Color.fromCssColorString(color)
- ),
- show: new Cesium.ShowGeometryInstanceAttribute(true), //显示或者隐藏
- },
- });
- return polygonInstance;
- }
- /**
- * 箭头
- * @ignore
- * @param {Object} targetPoint
- * @param {Object} center
- * @param {Object} diagonalPoint
- * @param {Object} heightDifference
- * @param {Object} curSlope
- */
- _createArrowInstance(targetPoint, center, diagonalPoint, heightDifference, curSlope) {
- let cartographic_0 = new Cesium.Cartographic(
- (targetPoint.longitude + center.longitude) / 2,
- (targetPoint.latitude + center.latitude) / 2,
- (targetPoint.height + center.height) / 2
- );
- let cartographic_1 = new Cesium.Cartographic(
- (diagonalPoint.longitude + center.longitude) / 2,
- (diagonalPoint.latitude + center.latitude) / 2,
- (diagonalPoint.height + center.height) / 2
- );
- //偏移的
- let positions1 =
- heightDifference > 0 ? [
- Cesium.Cartographic.toCartesian(cartographic_0),
- Cesium.Cartographic.toCartesian(cartographic_1)
- ] : [
- Cesium.Cartographic.toCartesian(cartographic_1),
- Cesium.Cartographic.toCartesian(cartographic_0)
- ];
- //箭头线
- const instance = new Cesium.GeometryInstance({
- id: {
- type: "SlopeAspect",
- value: curSlope,
- },
- geometry: new Cesium.GroundPolylineGeometry({
- positions: positions1,
- width: this.arrowWidth,
- }),
- attributes: {
- color: Cesium.ColorGeometryInstanceAttribute.fromColor(
- Cesium.Color.BLUE.withAlpha(0.6)
- ),
- show: new Cesium.ShowGeometryInstanceAttribute(true), //显示或者隐藏
- },
- });
- return instance;
- }
- /**
- * @ignore
- * @param {Object} ellipseResults
- */
- _calculateSlope(ellipseResults) {
- let _self = this;
- let instances = [];
- let polygonInstance = [];
- for (let index = 0; index < ellipseResults.length; index++) {
- const ellipse = ellipseResults[index];
- const center = ellipse[0];
- let heightDifference = 0;
- let maxIndex = 0;
- for (let i = 1; i < ellipse.length - 1; i++) {
- const point = ellipse[i];
- let curHD = point.height - center.height;
- if (Math.abs(curHD) > heightDifference) {
- heightDifference = curHD;
- maxIndex = i;
- }
- }
- let pos0 = new Cesium.Cartographic(center.longitude, center.latitude, 0);
- let pos1 = new Cesium.Cartographic(
- ellipse[maxIndex].longitude,
- ellipse[maxIndex].latitude,
- 0
- );
- let distance = Cesium.Cartesian3.distance(
- Cesium.Cartographic.toCartesian(pos0),
- Cesium.Cartographic.toCartesian(pos1)
- );
- let curSlope = Math.abs(heightDifference / distance); //坡度的tan值
- let curColor = _self._calculateSlopeColor(curSlope, 0.4);
- const curPolygonInstance = _self._createPolygonInsrance(ellipse, curColor);
- polygonInstance.push(curPolygonInstance);
- let diagonalPoint = maxIndex > 4 ? ellipse[maxIndex - 4] : ellipse[maxIndex + 4]; //对角点
- let targetPoint = ellipse[maxIndex];
- const arrowInstance = _self._createArrowInstance(targetPoint, center, diagonalPoint, heightDifference, curSlope);
- instances.push(arrowInstance);
- }
- const mapPrimitive = _self._viewer.scene.primitives.add(
- new Cesium.GroundPrimitive({
- geometryInstances: polygonInstance,
- appearance: new Cesium.PerInstanceColorAppearance({
- translucent: true, //false时透明度无效
- closed: false,
- }),
- })
- );
- const arrowPrimitive = _self._viewer.scene.primitives.add(
- new Cesium.GroundPolylinePrimitive({
- geometryInstances: instances,
- appearance: new Cesium.PolylineMaterialAppearance({
- material: new Cesium.Material({
- fabric: {
- type: "PolylineArrow",
- uniforms: {
- color: new Cesium.Color(1.0, 1.0, 0.0, 0.8),
- },
- },
- }),
- }),
- })
- );
- _self.result.push(arrowPrimitive, mapPrimitive);
- }
- /**
- * 根据坡度值赋值颜色
- * @ignore
- * @param {Object} value
- * @param {Object} alpha
- */
- _calculateSlopeColor(value, alpha) {
- // 0°~0.5°为平原0.00872686779075879,rgb(85,182,43)
- // 0.5°~2°为微斜坡0.03492076949174773,rgb(135,211,43)
- // 2°~5°为缓斜坡0.08748866352592401,rgb(204,244,44)
- // 5°~15°为斜坡0.2679491924311227,rgb(245,233,44)
- // 15°~35°为陡坡0.7002075382097097,rgb(255,138,43)
- // 35°~55°为峭坡1.4281480067421144,rgb(255,84,43)
- // 55°~90°为垂直壁,rgb(255,32,43)
- if (value < 0.00872686779075879) {
- return "rgba(85,182,43," + alpha + ")";
- } else if (value < 0.03492076949174773) {
- return "rgba(135,211,43," + alpha + ")";
- } else if (value < 0.08748866352592401) {
- return "rgba(204,244,44," + alpha + ")";
- } else if (value < 0.2679491924311227) {
- return "rgba(245,233,44," + alpha + ")";
- } else if (value < 0.7002075382097097) {
- return "rgba(255,138,43," + alpha + ")";
- } else if (value < 1.4281480067421144) {
- return "rgba(255,84,43," + alpha + ")";
- } else {
- return "rgba(255,32,43," + alpha + ")";
- }
- }
- }
- /**
- * 通用对外公开函数
- */
- Object.assign(SlopeAspect.prototype, /** @lends SlopeAspect.prototype */ {
- /**
- * 等距离切分网格
- * @param {Object} points
- * @param {Object} polygon
- * @param {Object} options
- * @param {Object} options.distance 默认0.1km精度
- */
- createNew4Distance(points, polygon, options) {
- let _self = this;
- options = options || {};
- options.distance = options.distance || 0.1;//默认0.1km精度
- let width = options.distance * 200 > 35 ? 35 : options.distance * 200;
- _self.arrowWidth = width < 15 ? 15 : width;
- /* 转换坐标 */
- let positions = points.map(point => {
- return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
- });
- _self.clearAll();
- let degrees = CoordTransform.Cartesian3ListToWGS84(positions);
- // _self._viewer.entities.remove(polygon);
- let boundary = [];
- let minX = 10000,
- minY = 10000,
- maxX = -10000,
- maxY = -1000;
- for (let index = 0; index < degrees.length; index++) {
- const element = degrees[index];
- const x = element.lng;
- const y = element.lat;
- boundary.push([x, y]);
- minX = x < minX ? x : minX;
- minY = y < minY ? y : minY;
- maxX = x > maxX ? x : maxX;
- maxY = y > maxY ? y : maxY;
- }
- boundary.push(boundary[0]);
- let bbox = [minX, minY, maxX, maxY];
- let mask = turf.polygon([boundary]);
- let gridSquare = turf.squareGrid(bbox, options.distance, {
- // mask: mask,//加上这个参数分析不出来
- });
- _self._createEllipse(gridSquare);
- },
- /**
- * 等分切分网格,切分成一个num*num的网格
- * @param {Object} points
- * @param {Object} polygon
- * @param {Object} options.num=10
- */
- createNew4Num(points, polygon, options) {
- let _self = this;
- options = options || {};
- options.num = Cesium.defaultValue(options.num, 10);
- /* 转换坐标 */
- let positions = points.map(point => {
- return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
- });
- _self.clearAll();
- let degrees = CoordTransform.Cartesian3ListToWGS84(positions);
- // _self._viewer.entities.remove(polygon);
- let boundary = [];
- let minX = 10000,
- minY = 10000,
- maxX = -10000,
- maxY = -1000;
- for (let index = 0; index < degrees.length; index++) {
- const element = degrees[index];
- const x = element.lng;
- const y = element.lat;
- boundary.push([x, y]);
- minX = x < minX ? x : minX;
- minY = y < minY ? y : minY;
- maxX = x > maxX ? x : maxX;
- maxY = y > maxY ? y : maxY;
- }
- boundary.push(boundary[0]);
- let bbox = [minX, minY, maxX, maxY];
- let a = maxX - minX;
- let b = maxY - minY;
- b = b > a ? b : a;
- const step = b / options.num;
- let width = step * 2000 > 35 ? 35 : step * 2000;
- _self.arrowWidth = width < 15 ? 15 : width;
- let mask = turf.polygon([boundary]);
- let gridSquare = turf.squareGrid(bbox, step, {
- units: "degrees",
- // mask: mask,//加上这个参数分析不出来
- });
- _self._createEllipse(gridSquare);
- },
- /**
- * 清除
- */
- clearAll() {
- this.result.forEach((element) => {
- this._viewer.scene.primitives.remove(element);
- });
- this.result = [];
- if (this.handler) {
- this.handler.destroy();
- this.handler = undefined;
- }
- },
- });
- export default SlopeAspect;
|