Men的博客

欢迎光临!

0%

Cesium分析

坡度分析
slope
等高线
contourLine
地形开挖
clipping
淹没分析
SubmergeAnalysis
光照分析
SunshineAnalysis
坐标
WHCGCE2000ToWGS84
三维飞行初始化
flycesium
ViewShedStage
addHeatMap
addBillboard
addSkyBoxFn
DrawTool

山谷、山脊

export const elevation = function (viewer, show) {
viewer.scene.globe.enableLighting = true;
var elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0];
function getColorRamp(selectedShading) {
var ramp = document.createElement(“canvas”);
ramp.width = 100;
ramp.height = 1;
var ctx = ramp.getContext(“2d”);
var values;
if (selectedShading === “elevation”) {
values = elevationRamp;
}
var grd = ctx.createLinearGradient(0, 0, 100, 0);
grd.addColorStop(values[0], “#000000”); //black
grd.addColorStop(values[1], “#2747E0”); //blue
grd.addColorStop(values[2], “#D33B7D”); //pink
grd.addColorStop(values[3], “#D33038”); //red
grd.addColorStop(values[4], “#FF9742”); //orange
grd.addColorStop(values[5], “#ffd700”); //yellow
grd.addColorStop(values[6], “#ffffff”); //white
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 1);
return ramp;
}

var minHeight = -414.0; // approximate dead sea elevation
var maxHeight = 8777.0; // approximate everest elevation
var contourColor = Cesium.Color.RED.clone();
var contourUniforms = {};
var shadingUniforms = {};

// The viewModel tracks the state of our mini application.
var viewModel = {
  selectedShading: "elevation",
  changeColor: function () {
    contourUniforms.color = Cesium.Color.fromRandom(
      { alpha: 1.0 },
      contourColor
    );
  },
};
function updateMaterial(selectedShading) {
  viewModel.selectedShading = selectedShading;
  var globe = viewer.scene.globe;
  var material;
  if (selectedShading === "elevation") {
    material = Cesium.Material.fromType("ElevationRamp");
    shadingUniforms = material.uniforms;
    shadingUniforms.minimumHeight = minHeight;
    shadingUniforms.maximumHeight = maxHeight;
  } 
  if (selectedShading !== "none") {
    shadingUniforms.image = getColorRamp(selectedShading);
  }
  globe.material = material;
}
updateMaterial(show? "elevation" : "none");

}

坡度分析

export const slope = function(viewer){
viewer.scene.globe.enableLighting = true;
var material = Cesium.Material.fromType(‘SlopeRamp’);
var shadingUniforms = material.uniforms;
shadingUniforms.image = getColorRamp();
viewer.scene.globe.material = material;
function getColorRamp() {
var ramp = document.createElement(‘canvas’);
ramp.width = 100;
ramp.height = 1;
var ctx = ramp.getContext(‘2d’);

    var grd = ctx.createLinearGradient(0, 0, 100, 0);
   
    // var values = [0.0, 0.25,0.5];

    var values = [0.0,0.2,0.6,1];
    grd.addColorStop(values[0], 'rgba(0,0,0,0.0)'); //black
    grd.addColorStop(values[1], 'rgba(220,20,60,0.6)'); //blue
    grd.addColorStop(values[2], 'rgba(255,255,0,1.0)'); //
    grd.addColorStop(values[3], 'rgba(255,0,255,1.0)'); //green

    // var values = [0.0, 0.25, 0.5];
    // grd.addColorStop(values[0], 'rgba(0,0,0,0.8)'); //black
    // grd.addColorStop(values[1], 'rgba(39,71,224,0.8)'); //blue
    // grd.addColorStop(values[2], 'rgba(211,48,56,0.8)'); //red

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, 100, 1);
    return ramp;
}

}

等高线

export const contourLine = function (viewer) {

viewer.scene.globe.enableLighting = true;

// 创建一个拥有高程阴影和等高线的组合样式
function getElevationContourMaterial() {
    return new Cesium.Material({
        fabric: {
            type: 'ElevationColorContour',
            materials: {
                contourMaterial: {
                    type: 'ElevationContour'
                },
                elevationRampMaterial: {
                    type: 'ElevationRamp'
                }
            },
            components: {
                diffuse: 'contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse',
                alpha: 'max(contourMaterial.alpha, elevationRampMaterial.alpha)'
            }
        },
        translucent: false
    });
}

var minHeight = 50.0; // 最低接近死海高度
var maxHeight = 1000.0; // 最高接近珠峰高度
var contourColor = Cesium.Color.AQUA.withAlpha(0.8); // 等高线的颜色
var contourSpacing = 100.0; // 等高线的等间距
var contourWidth = 2.0; // 等高线的宽度

// 1、高程阴影
// var material = Cesium.Material.fromType('ElevationRamp');
// var shadingUniforms = material.uniforms;
// shadingUniforms.minimumHeight = minHeight;
// shadingUniforms.maximumHeight = maxHeight;
// shadingUniforms.image = getColorRamp();

// 2、等高线
// var material = Cesium.Material.fromType('ElevationContour');
// var contourUniforms = material.uniforms;
// contourUniforms.width = contourWidth;
// contourUniforms.spacing = contourSpacing;
// contourUniforms.color = contourColor;

// 3、高程阴影+等高线
var material = getElevationContourMaterial();
var shadingUniforms = material.materials.elevationRampMaterial.uniforms;
shadingUniforms.minimumHeight = minHeight;
shadingUniforms.maximumHeight = maxHeight;
shadingUniforms.image = getColorRamp();

var contourUniforms = material.materials.contourMaterial.uniforms;
contourUniforms.width = contourWidth;
contourUniforms.spacing = contourSpacing;
contourUniforms.color = contourColor;
viewer.scene.globe.material = material;

function getColorRamp() {
    var ramp = document.createElement('canvas');
    ramp.width = 100;
    ramp.height = 1;
    var ctx = ramp.getContext('2d');
    var values = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0];
    var grd = ctx.createLinearGradient(0, 0, 100, 0);

    // grd.addColorStop(values[0], 'rgba(0,0,0,0.0)'); //black
    // grd.addColorStop(values[1], 'rgba(39,71,224,0.8)'); //blue
    // grd.addColorStop(values[2], 'rgba(211,59,125,0.8)'); //pink
    // grd.addColorStop(values[3], 'rgba(211,48,56,0.8)'); //red
    // grd.addColorStop(values[4], 'rgba(255,151,66,0.8)'); //orange
    // grd.addColorStop(values[5], 'rgba(255,215,0,0.8)'); //yellow
    // grd.addColorStop(values[6], 'rgba(255,255,255,0.8)'); //white


    grd.addColorStop(values[0], 'rgba(255,255,255,0)'); //black
    grd.addColorStop(values[1], 'rgba(39,71,224,0.8)'); //blue
    grd.addColorStop(values[2], 'rgba(211,59,125,0.8)'); //pink
    grd.addColorStop(values[3], 'rgba(211,48,56,0.8)'); //red
    grd.addColorStop(values[4], 'rgba(255,151,66,0.8)'); //orange
    grd.addColorStop(values[5], 'rgba(255,215,0,0.8)'); //yellow
    grd.addColorStop(values[6], 'rgba(255,255,255,0.8)'); //white

   


    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, 100, 1);
    return ramp;
}

}

地形开挖

class ClippingPlane {
constructor(tileset,viewer,image) {
this._viewer = viewer;
this.activeShapePoints = [];
this.activeShape = null;
this.floatingPoint = null;
this.points = [];
this.drawingMode = “polygon”; //多边形
this.handler = null;
this.image = image;
this.init();
}
/**

  • 绑定点击事件

  • /
    init() {

    let that = this;

    that.handler = new Cesium.ScreenSpaceEventHandler(that._viewer.canvas);

    //双击鼠标左键清除默认事件
    that._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );

    that.handler.setInputAction(function(event) {

    // We use viewer.scene.pickPosition here instead of viewer.camera.pickEllipsoid so that
    // we get the correct point when mousing over terrain.
    // scene.pickPosition只有在开启地形深度检测,且不使用默认地形时是准确的。
    var earthPosition = that._viewer.scene.pickPosition(event.position);

    // earthPosition will be undefined if our mouse is not over the globe.
    if (Cesium.defined(earthPosition)) {

    if (that.activeShapePoints.length === 0) {
      that.floatingPoint = that.createPoint(earthPosition);
      that.activeShapePoints.push(earthPosition);
      var dynamicPositions = new Cesium.CallbackProperty(function() {
        if (that.drawingMode === "polygon") {
          return new Cesium.PolygonHierarchy(that.activeShapePoints);
        }
        return that.activeShapePoints;
      }, false);
      that.activeShape = that.drawShape(dynamicPositions); //绘制动态图
    }
    that.activeShapePoints.push(earthPosition);
    that.points.push(earthPosition)
    that.createPoint(earthPosition);
    

    }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    //鼠标移动
    that.handler.setInputAction(function(event) {
    if (Cesium.defined(that.floatingPoint)) {

    var newPosition = that._viewer.scene.pickPosition(event.endPosition);
    if (Cesium.defined(newPosition)) {
      that.floatingPoint.position.setValue(newPosition);
      that.activeShapePoints.pop();
      that.activeShapePoints.push(newPosition);
    }
    

    }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    that.handler.setInputAction(function(event) {
    that._viewer.entities.remove(that.activeShape);
    that._viewer.entities.remove(that.floatingPoint);
    var earthPosition = that._viewer.scene.pickPosition(event.position);
    that.points.push(earthPosition);
    // console.log(‘points’, that.points);
    var planes = that.createClippingPlane(that.points);
    // console.log(‘planes’,planes)
    //赋值给globe的 clippingPlanes
    that._viewer.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection({

      planes: planes,
      edgeWidth: 1.0,
      edgeColor: Cesium.Color.WHITE
    

    })
    //依次计算顶点与下个顶点之间组成的线段,中间按照精度大小插值n个点,然后计算每个点的地形高度
    let promises = []
    for (let i = 0; i < that.points.length - 1; i++) {

      promises.push(that.calHeight(that._viewer, that.points[i], that.points[i + 1], 100)); // 返回promise对象
    

    }
    // 待所有的计算完毕后,处理坐标点,构造多边形
    Promise.all([…promises]).then(data => {

      var positons = Array.prototype.concat.apply([], data); // 数组降维
      var hierarchy = [];
      positons.forEach(element => {
          hierarchy.push(Cesium.Math.toDegrees(element.longitude));
          hierarchy.push(Cesium.Math.toDegrees(element.latitude));
          hierarchy.push(element.height);
      });
      that._viewer.entities.add({
          polygon: {
              hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(hierarchy),
              closeTop: false, // 这个要设置为false
          material: that.image ?
            new Cesium.ImageMaterialProperty({
              image:that.image,
              // repeat:new Cesium.Cartesian2(100.0, 100.0)
            }) : new Cesium.ColorMaterialProperty(Cesium.Color.BROWN),                  
              extrudedHeight: 0,
              perPositionHeight: true // 这个要设置true
          }
      });
    

    })
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
    /**

  • 根据点集计算 ClippingPlane

  • @param {*} points

  • @returns

  • /
    createClippingPlane(points) {
    var pointsLength = points.length;
    var clippingPlanes = []; // 存储ClippingPlane集合
    for (var i = 0; i < pointsLength; ++i) {
    var nextIndex = (i + 1) % pointsLength;
    var midpoint = Cesium.Cartesian3.add(

    points[i],
    points[nextIndex],
    new Cesium.Cartesian3()
    

    );
    midpoint = Cesium.Cartesian3.multiplyByScalar(midpoint, 0.5, midpoint);
    var up = Cesium.Cartesian3.normalize(midpoint, new Cesium.Cartesian3());
    var right = Cesium.Cartesian3.subtract(

    points[nextIndex],
    midpoint,
    new Cesium.Cartesian3()
    

    );
    right = Cesium.Cartesian3.normalize(right, right);
    var normal = Cesium.Cartesian3.cross(right, up, new Cesium.Cartesian3());
    normal = Cesium.Cartesian3.normalize(normal, normal);
    var originCenteredPlane = new Cesium.Plane(normal, 0.0);
    var distance = Cesium.Plane.getPointDistance(

    originCenteredPlane,
    midpoint
    

    );
    clippingPlanes.push(new Cesium.ClippingPlane(normal, distance));
    }
    return clippingPlanes;
    }
    /**

  • 插值、计算坐标点高度(如果不加载地形的话,这步可以省略)

  • @param {*} viewer

  • @param {*} fromPoint

  • @param {*} endPoint

  • @param {*} count

  • @returns

  • /
    calHeight(viewer, fromPoint, endPoint, count) {
    var positions = [];
    for (var i = 0; i <= count; i++) {
    var cart = Cesium.Cartesian3.lerp(

    fromPoint,
    endPoint,
    i / count,
    new Cesium.Cartesian3()
    

    );
    positions.push(Cesium.Cartographic.fromCartesian(cart));
    }
    return new Promise((resolve, reject) => {
    var promise = Cesium.sampleTerrainMostDetailed(

    viewer.terrainProvider,
    positions
    

    );
    Cesium.when(promise, function(updatedPositions) {

    resolve(updatedPositions);
    

    });
    });
    }
    //绘制点
    createPoint(worldPosition) {
    var point = this._viewer.entities.add({
    position: worldPosition,
    point: {

    color: Cesium.Color.GREENYELLOW,
    pixelSize: 9,
    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
    

    },
    });
    return point;
    }
    //绘制图形
    drawShape(positionData) {
    var that = this;
    var shape;
    shape = that._viewer.entities.add({
    polygon: {

    hierarchy: positionData,
    perPositionHeight: true,
    extrudedHeight: 4,
    //new Cesium.Color.fromBytes(0,191,255,100),
    //new Cesium.ColorMaterialProperty(Cesium.Color.AQUA.withAlpha(0.3))
    material: new Cesium.Color.fromBytes(0, 191, 255, 100),
    

    },
    });
    return shape;
    }

clear(){
this._viewer.scene.globe.clippingPlanes && this._viewer.scene.globe.clippingPlanes.removeAll();
this._viewer.entities.removeAll();
this.activeShapePoints = [];
this.activeShape = null;
this.floatingPoint = null;
this.points = [];
}
}

日照分析

class SunshineAnalysis{

    constructor(option){
          this._viewer = option.viewer
          this.init();
          this.eventBus = {};
    }

    init(){
        
    }

    $on(event, cb) {
        if (!this.eventBus[event]) {
            this.eventBus[event] = new Set()
        }
        this.eventBus[event].add(cb)
    }
    $emit(event, ...args) {

        if (this.eventBus[event]) {
            Array.from(this.eventBus[event]).forEach((handle) => {

                handle.call(this, args)
            })
        }
    }
    $off(event, cb) {
        if (this.eventBus[event]) {
            this.eventBus[event].delete(cb)
        }
    }

}

可视域分析

/**

  • 可视域分析。
  • @author
  • @date
  • @alias ViewShedStage
  • @class
  • @param {Cesium.Viewer} viewer Cesium三维视窗。
  • @param {Object} options 选项。
  • @param {Cesium.Cartesian3} options.viewPosition 观测点位置。
  • @param {Cesium.Cartesian3} options.viewPositionEnd 最远观测点位置(如果设置了观测距离,这个属性可以不设置)。
  • @param {Number} options.viewDistance 观测距离(单位,默认值100)。
  • @param {Number} options.viewHeading 航向角(单位,默认值0)。
  • @param {Number} options.viewPitch 俯仰角(单位,默认值0)。
  • @param {Number} options.horizontalViewAngle 可视域水平夹角(单位,默认值90)。
  • @param {Number} options.verticalViewAngle 可视域垂直夹角(单位,默认值60)。
  • @param {Cesium.Color} options.visibleAreaColor 可视区域颜色(默认值绿色)。
  • @param {Cesium.Color} options.invisibleAreaColor 不可视区域颜色(默认值红色)。
  • @param {Boolean} options.enabled 阴影贴图是否可用。
  • @param {Boolean} options.softShadows 是否启用柔和阴影。
  • @param {Boolean} options.size 每个阴影贴图的大小。
  • /