cesium学习笔记(问题记录)——(一)

一、cesium球出不来

Cesium第一次搭建环境出不来地球,如下图所示:
在这里插入图片描述
下面有一行英文提示: This application is using Cesium’s default ion access token. Please assign Cesium.Ion.defaultAccessToken with an access token from your ion account before making any Cesium API calls. You can sign up for a free ion account at https://cesium.com.

(此应用程序使用cesium的默认ion访问令牌。在进行任何Cesium API调用之前,请使用您的Ion帐户中的访问令牌代替Cesium的默认ion访问令牌。您可以在https://cesium.com.免费注册cesium帐户)

解决方法

(一)根据英文提示可知,需要注册一个免费的Cesium ion账户

1、打开https://cesium.com,注册账户

2、注册好后登入进入Access Tokens模块
在这里插入图片描述
3、Create token 创建token
在这里插入图片描述
在这里插入图片描述

(二)申请下token之后需要修改文件

(1)F12进入开发者模式,可在控制台上看到401的报错,如下所示:
在这里插入图片描述
(2)鼠标点击,调整至带默认token的链接:https://api.cesium.com/v1/assets/2/endpoint?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMmVkZTQ0Ni1kOWJlLTRmY2ItOTc1Ny03ZDEwOTcyYmIzY2IiLCJpZCI6MjU5LCJpYXQiOjE2MDk3NzQ1OTZ9.8lY9m6O6CY1lpmW5SSNmQmHdxuzNL20N9vUtsbBGezA

(3)打开下载的代码,全局搜索该token,直接将所有token替换为自己申请的token即可。

最终效果

地球出现:
在这里插入图片描述

二、BingMapsImageryProvider接口调用示例

Git上下载下默认无key,需自行去官网申请修改:

imageryLayers.addImageryProvider(
  new Cesium.BingMapsImageryProvider({

     url: 'https://dev.virtualearth.net',

     key: 'AmTLTFB9yDa02XCXQcXPPeWFuTiRQpezXihtyD_-67kH4RgYAOv1QSejOjTiGsYG',

     mapStyle: Cesium.BingMapsStyle.AERIAL

 })
);

效果如下:
在这里插入图片描述

三、cesium建筑白膜的加载与渲染

本文以建筑的不同高度来渲染不同的颜色为例

Cesium3DTileset加载模型

在这里插入图片描述

var tileset = new Cesium.Cesium3DTileset({
  url: "http://data1.mars3d.cn/3dtiles/jzw-hefei/tileset.json" // 在火星科技上找的JSON白膜数据
});
viewer.scene.primitives.add(tileset);

数据属性信息

在这里插入图片描述

tileset.readyPromise.then(function(tileset) {
    // tile.properties is not defined until readyPromise resolves.
    var properties = tileset.properties;
    if (Cesium.defined(properties)) {
        for (var name in properties) {
            console.log(properties[name]);
        }
    }
});

根据建筑高度设置不同颜色

在这里插入图片描述

tileset.style = new Cesium.Cesium3DTileStyle({
  color: {
  	conditions: [
  		['${height} >= 200', "color('#FFF700')"], // height为在模型数据中包含的属性
  		['${height} >= 150', "color('#AFDAFC')"],
  		['${height} >= 100', "color('#B0B7BD')"],
  		['${height} >= 50', "color('#05909E')"],
  		['true', "color('#FB8D82')"]]
   }
});

四、cesium材质设置

无论是通过Entity类,还是通过Primitive类添加的空间几何数据,Cesium都提供了对应的方法或材质相关类对材质进行修改。
材质可以是几何对象表面的任意一种着色(Cesium.Color)、可以是贴在其表面的一张图片、也可以是一个纹理或图案,比如下图中的条形或棋盘形的图案。
在这里插入图片描述
针对于两种方式(Entity和Primitive)绘制的几何对象,Cesium也提供了Material类和MaterialProperty类,分别对通过Primitive和Entity两种方式生成的几何对象的material属性进行赋值。Primitive的appearance(或继承类)的material属性为Material类型,EntityGraphics的material属性为MaterialProperty或Color类型。
Primitive方式加载:
在这里插入图片描述
Entity方式加载:
在这里插入图片描述
在这里插入图片描述

Material类

Material类专为Appearance类而生,用于修改Primitive的几何对象材质。同时,Apperance也有自己的继承类,通过修改部分继承类的material属性,也可实现Primitive几何对象材质的修改。Appearance的继承类如下图所示,其中橘黄色背景的子类,能修改其material属性。
在这里插入图片描述
通过Material类修改材质相对来说比较复杂,需要对OpenGL以及底层渲染机制进行了解。Cesium中的Material类的内部机制是通过一种json格式的Fabric对象来表达物体的外观特征,而这些外观特征是由漫反射(diffuse)、镜面反射(specular)、法向量(normal)、自发光(emission)以及透明度(alpha)组合(即一个Components)而成。

Cesium为我们提供了23种现成的Material类型,可通过Material.fromType方法和Fabric两种方式去获取并设置几何对象材质。如下是通过Material类的两种方式实现着色的示例:

// Create a color material with fromType:
polygon.material = Cesium.Material.fromType('Color');
polygon.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0);

// Create the default material:
polygon.material = new Cesium.Material();
// Create a color material with full Fabric notation:
polygon.material = new Cesium.Material({
    fabric : {
        type : 'Color',
        uniforms : {
            color : new Cesium.Color(1.0, 1.0, 0.0, 1.0)
        }
    }
});

可查阅Material的沙盒示例:https://sandcastle.cesium.com/index.html?src=Materials.html

从Material的Fabric对象组成来看,要想创建一个新的Material,只需要指定type、uniforms、compontents三个属性,构建一个Fabric的JSON对象。如果想写一些自定义的shader,则需要再指定source属性。
在这里插入图片描述

MaterialProperty类

MaterialProperty类专为Entity而生,是一个抽象类,无法进行实例化。要使用该类对材质进行设置,需要实例化其子类。MaterialProperty类的继承类,如下图所示:
在这里插入图片描述

1.ColorMaterialProperty 颜色材质

ColorMaterialProperty类相对来说比较简单,可以直接使用Cesium.Color替换,两个类实现的效果最终是一样的,都是给几何对象直接着色。

var color = Cesium.Color.BLUE.withAlpha(0.5);
var colorMaterial = new Cesium.ColorMaterialProperty(color);
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(-55.0, 40.0, 100000.0),
  ellipse: {
    semiMajorAxis: 300000.0, // 长半轴距离
    semiMinorAxis: 200000.0, // 短半轴距离
    height: 20000.0,
    material: colorMaterial,
  },
});
2.ImageMaterialProperty 贴图材质

ImageMaterialProperty类可以给几何对象表面贴上一张图片。

var imgUrl = "./images/bumpmap.png";
var imgMaterial = new Cesium.ImageMaterialProperty({
  image: imgUrl,
  repeat: new Cesium.Cartesian2(4, 4),
  color: Cesium.Color.BLUE,
});
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(-65.0, 40.0, 100000.0),
  ellipse: {
    semiMajorAxis: 300000.0, // 长半轴距离
    semiMinorAxis: 200000.0, // 短半轴距离
    height: 20000.0,
    material: imgMaterial,
  },
});
3.CheckerboardMaterialProperty 棋盘纹理
var checkerboardMaterial = new Cesium.CheckerboardMaterialProperty({
  evenColor: Cesium.Color.WHITE,
  oddColor: Cesium.Color.BLACK,
  repeat: new Cesium.Cartesian2(4, 4),
});
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(-75.0, 40.0, 100000.0),
  ellipse: {
    semiMajorAxis: 300000.0, // 长半轴距离
    semiMinorAxis: 200000.0, // 短半轴距离
    height: 20000.0,
    material: checkerboardMaterial,
  },
});
4.StripeMaterialProperty 条纹纹理
var stripeMaterial = new Cesium.StripeMaterialProperty({
  orientation: Cesium.StripeOrientation.VERTICAL,
  evenColor: Cesium.Color.WHITE,
  oddColor: Cesium.Color.BLACK,
  repeat: 16,
});
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(-85.0, 40.0, 100000.0),
  ellipse: {
    semiMajorAxis: 300000.0, // 长半轴距离
    semiMinorAxis: 200000.0, // 短半轴距离
    height: 20000.0,
    material: stripeMaterial,
  },
});
5.GridMaterialProperty 网格
var gripMaterial = new Cesium.GridMaterialProperty({
  color: Cesium.Color.YELLOW,
  cellAlpha: 0.5,
  lineCount: new Cesium.Cartesian2(8, 8),
  lineThickness: new Cesium.Cartesian2(2.0, 2.0),
  lineOffset: new Cesium.Cartesian2(0.0, 0.0),
});
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0),
  ellipse: {
    semiMajorAxis: 300000.0, // 长半轴距离
    semiMinorAxis: 200000.0, // 短半轴距离
    height: 20000.0,
    material: gripMaterial,
  },
});
6.PolylineGlowMaterialProperty 发光材质
var glowingLine = viewer.entities.add({
 name: "Glowing blue line on the surface",
 polyline: {
   positions: Cesium.Cartesian3.fromDegreesArray([-75, 37, -125, 37]),
   width: 10,
   material: new Cesium.PolylineGlowMaterialProperty({
     glowPower: 0.8,
     taperPower: 0.5,
     color: Cesium.Color.CORNFLOWERBLUE,
   }),
 },
});
7.PolylineOutlineMaterialProperty 外轮廓材质
var orangeOutlined = viewer.entities.add({
  name:
    "Orange line with black outline at height and following the surface",
  polyline: {
    positions: Cesium.Cartesian3.fromDegreesArrayHeights([
      -75,
      39,
      250000,
      -125,
      39,
      250000,
    ]),
    width: 5,
    material: new Cesium.PolylineOutlineMaterialProperty({
      color: Cesium.Color.ORANGE,
      outlineWidth: 5,
      outlineColor: Cesium.Color.BLACK,
    }),
  },
});
8.PolylineArrowMaterialProperty 带有箭头的线
var purpleArrow = viewer.entities.add({
  name: "Purple straight arrow at height",
  polyline: {
    positions: Cesium.Cartesian3.fromDegreesArrayHeights([
      -75,
      43,
      500000,
      -125,
      43,
      500000,
    ]),
    width: 10,
    arcType: Cesium.ArcType.NONE,
    material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.PURPLE),
  },
});
9.PolylineDashMaterialProperty 虚线
var dashedLine = viewer.entities.add({
  name: "Blue dashed line",
  polyline: {
    positions: Cesium.Cartesian3.fromDegreesArrayHeights([
      -75,
      45,
      500000,
      -125,
      45,
      500000,
    ]),
    width: 4,
    material: new Cesium.PolylineDashMaterialProperty({
      color: Cesium.Color.CYAN,
    }),
  },
});

上述9种方式生成的效果图如下所示:
在这里插入图片描述

五、加载geojson格式数据

shp转geojson,可通过http://www.mapshaper.org/网站进行转换

1、添加Cesium的底图数据并在图层上叠加各国夜晚灯光亮度图

var viewer = new Cesium.Viewer('cesiumContainer', {
  imageryProvider:newCesium.ArcGisMapServerImageryProvider(
  {
  	url:'https://server.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer'
  }),
  baseLayerPicker:true//地图切换控件(底图以及地形图)是否显示,默认显示true
});

var layers = viewer.imageryLayers;
//添加各国夜晚灯光亮度图
var blackMarble =layers.addImageryProvider(Cesium.createTileMapServiceImageryProvider({
  url: 'https://cesiumjs.org/blackmarble',
  credit: 'Black Marble imagery courtesy NASA EarthObservatory',
  flipXY: true // Only old gdal2tile.py generatedtilesets need this flag.
}));

blackMarble.alpha = 0.5;    //透明度
blackMarble.brightness = 1.5;   //亮度

2、使用Cesium添加geojson,将数据叠加到Cesium的底图上

//添加geojson格式地理数据(由shp格式文件转换得来)
Cesium.Math.setRandomNumberSeed(0);
var promise =Cesium.GeoJsonDataSource.load('Output_bou2_4p.json');
promise.then(function (dataSource) {
  viewer.dataSources.add(dataSource);
  var entities =dataSource.entities.values;
  var colorHash = {};
  for (var i = 0; i < entities.length;i++) {
    var entity = entities[i];
     var name = entity.name;
     var color = colorHash[name];
     if (!color) {
       color =Cesium.Color.fromRandom({
           alpha: 1.0
       });
       colorHash[name] = color;
     }
     entity.polygon.material = color;
     entity.polygon.outline = false;
  	 entity.polygon.extrudedHeight =5000.0;
  }
});
viewer.flyTo(promise);

延伸:如果需要json数据呈立体形状,需添加polygon的extrudedHeight属性:entity.polygon.extrudedHeight= 1000;

六、Cesium 场景设置

场景设置主要基于PostProcessStage方法进行设置,主要根据Shader进行渲染。

1、雨

首先创建PostProcessStage对象,通过在PostProcessStage类中uniforms属性修改雨的倾斜度、大小和速度,就可以创建出所需要的PostProcessStage对象

var tiltAngle = Cesium.defaultValue(options.tiltAngle, -0.6);
var rainSize = Cesium.defaultValue(options.rainSize, 0.3);
var rainSpeed = Cesium.defaultValue(options.rainSpeed, 60.0);
var rainStage = new Cesium.PostProcessStage({
  name: 'czm_rain',
  fragmentShader: "uniform sampler2D colorTexture;\n\
             varying vec2 v_textureCoordinates;\n\
             uniform float tiltAngle;\n\
             uniform float rainSize;\n\
             uniform float rainSpeed;\n\
             float hash(float x) {\n\
                 return fract(sin(x * 133.3) * 13.13);\n\
             }\n\
             void main(void) {\n\
                 float time = czm_frameNumber / rainSpeed;\n\
                 vec2 resolution = czm_viewport.zw;\n\
                 vec2 uv = (gl_FragCoord.xy * 2. - resolution.xy) / min(resolution.x, resolution.y);\n\
                 vec3 c = vec3(.6, .7, .8);\n\
                 float a = tiltAngle;\n\
                 float si = sin(a), co = cos(a);\n\
                 uv *= mat2(co, -si, si, co);\n\
                 uv *= length(uv + vec2(0, 4.9)) * rainSize + 1.;\n\
                 float v = 1. - sin(hash(floor(uv.x * 100.)) * 2.);\n\
                 float b = clamp(abs(sin(20. * time * v + uv.y * (5. / (2. + v)))) - .95, 0., 1.) * 20.;\n\
                 c *= v * b;\n\
                 gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c, 1), .5);\n\
             }\n\
             ";,
  uniforms: {
    tiltAngle: () => {
      return tiltAngle;
    },
    rainSize: () => {
      return rainSize;
    },
    rainSpeed: () => {
      return rainSpeed;
    }
  }
 });
viewer.scene.postProcessStages.add(rainStage);

2、雾

var fogthicknessnum = 1.0;//可见度
var nowfragmentShader =`uniform sampler2D colorTexture;uniform sampler2D depthTexture;varying vec2 v_textureCoordinates;uniform float fognum;void main(void){vec4 origcolor=texture2D(colorTexture, v_textureCoordinates);vec4 fogcolor=vec4(0.8,0.8,0.8,0.5);float depth = czm_readDepth(depthTexture, v_textureCoordinates);vec4 depthcolor=texture2D(depthTexture, v_textureCoordinates);float f=(depthcolor.r-0.22)/fognum;if(f<0.0) f=0.0;else if(f>1.0) f=1.0;gl_FragColor = mix(origcolor,fogcolor,f);}`;
var ProcessScenes = new Cesium.PostProcessStage({
	fragmentShader: nowfragmentShader,
	uniforms: {
		scale: 1.1,
		offset: function() {
			return new Cesium.Cartesian3(0.1, 0.2, 0.3);
		},
		fognum: () => {
			return fogthicknessnum;
		},
	},
})
viewer.scene.postProcessStages.add(ProcessScenes);

3、雪

var snowSize = Cesium.defaultValue(snowopt.size, 0.02);
var snowSpeed = Cesium.defaultValue(snowopt.speed, 60.0);
var fragmentShader =`uniform sampler2D colorTexture;varying vec2 v_textureCoordinates;uniform float snowSpeed;uniform float snowSize;float snow(vec2 uv,float scale){float time=czm_frameNumber/snowSpeed;float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);k=smoothstep(0.,k,sin(f.x+f.y)*snowSize);return k*w;}void main(void){vec2 resolution=czm_viewport.zw;vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);vec3 finalColor=vec3(0);float c=0.;c+=snow(uv,30.)*.0;c+=snow(uv,20.)*.0;c+=snow(uv,15.)*.0;c+=snow(uv,10.);c+=snow(uv,8.);c+=snow(uv,6.);c+=snow(uv,5.);finalColor=(vec3(c));gl_FragColor=mix(texture2D(colorTexture,v_textureCoordinates),vec4(finalColor,1),.5);}`;
var ProcessScenes = new Cesium.PostProcessStage({
	fragmentShader: fragmentShader,
	uniforms: {
		snowSize: () => {
			return snowSize;
		},
		snowSpeed: () => {
			return snowSpeed;
		},
	},
})
viewer.scene.postProcessStages.add(ProcessScenes);

七、建筑渲染(泛光渐变效果)

1、颜色渲染

根据floor属性值,分段设置颜色进行渲染

// 设置建筑物的样式
var heightStyle = new Cesium.Cesium3DTileStyle({
  color: {
    conditions: [
    ['${floor} >= 30', 'rgba(45,0,75,0.5)'],
    ['${floor} >= 20', 'rgb(102,71,151)'],
    ['${floor} >= 15', 'rgb(170,162,204)'],
    ['${floor} >= 10', 'rgb(224,226,238)'],
    ['${floor} >= 8', 'rgb(252,230,200)'],
    ['${floor} >= 5', 'rgb(248,176,87)'],
    ['${floor} >= 1', 'rgb(198,106,11)']
    ]
    conditions: value
  }
})

2、泛光

需要用到着色器(Shader)语言,根据不同建筑物高度设置是否需要泛光,以及是否需要设置渐变色,代码如下:

// 传入3DTiles
setLight (tiles) {
  const shader = `
    varying vec3 v_positionEC;
     void main(void){
       vec4 position = czm_inverseModelView * vec4(v_positionEC,1); // 位置
       float glowRange = 100.0; // 光环的移动范围(高度)
       gl_FragColor = vec4(0.0, 0.3, 0.8, 0.8); // 颜色1
      //  gl_FragColor = vec4(220.0, 0.3, 0.8, 0.8); // 颜色2
       // 低于10米的楼不显示渐变色
        if(position.z < 10.0) {
         gl_FragColor *= vec4(vec3(position.z / 10.0 * 2.0), 1.0);
       }else{
         gl_FragColor *= vec4(vec3(position.z / 10.0), 0.8); // 渐变
       }
       // 设置动态光环
       float time = fract(czm_frameNumber / 36.0);
       time = abs(time - 0.5) * 3.0;
       float diff = step(0.005, abs( clamp(position.z / glowRange, 0.0, 1.0) - time));
       gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - diff);
     }
     `
  tiles.tileVisible.addEventListener(function (tile) {
    const content = tile.content
    const featuresLength = content.featuresLength
    let feature
    for (var i = 0; i < featuresLength; i += 2) {
      feature = content.getFeature(i)
      const _model = feature.content._model
      _model._shouldRegenerateShaders = true
      Object.getOwnPropertyNames(_model._sourcePrograms).forEach(function (j) {
        const _modelSourceP = _model._sourcePrograms[0]
        _model._rendererResources.sourceShaders[_modelSourceP.fragmentShader] = shader
        const _modelSourceP1 = _model._sourcePrograms[1]
        _model._rendererResources.sourceShaders[_modelSourceP1.fragmentShader] = shader
      })
      _model._shouldRegenerateShaders = true
    }
  })
}

八、动态立体墙效果

1、自定义材质

一般为渐变色图片
entity使用materialProperty,而primitive使用material

/**
 * 动态立体墙材质
 */
//动态墙材质
function DynamicWallMaterialProperty(options) {
   // 默认参数设置
   this._definitionChanged = new Cesium.Event();
   this._color = undefined;
   this._colorSubscription = undefined;
   this.color = options.color;
   this.duration = options.duration;
   this.trailImage = options.trailImage;
   this._time = (new Date()).getTime();
}
Object.defineProperties(DynamicWallMaterialProperty.prototype, {
  isConstant: {
    get: function() {
      return false;
    }
  },
  definitionChanged: {
    get: function() {
      return this._definitionChanged;
    }
  },
  color: Cesium.createPropertyDescriptor('color')
});
DynamicWallMaterialProperty.prototype.getType = function(time) {
  return 'DynamicWall';
};
DynamicWallMaterialProperty.prototype.getValue = function(time, result) {
  if (!Cesium.defined(result)) {
    result = {};
  }
  result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
  if (this.trailImage) {
    result.image = this.trailImage;
  } else {
    result.image = Cesium.Material.DynamicWallImage
  }

  if (this.duration) {
    result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
  }
  viewer.scene.requestRender();
  return result;
};
DynamicWallMaterialProperty.prototype.equals = function(other) {
  return this === other || (other instanceof DynamicWallMaterialProperty && Cesium.Property.equals(this._color, other._color))
};
Cesium.DynamicWallMaterialProperty = DynamicWallMaterialProperty;
Cesium.Material.DynamicWallType = 'DynamicWall';
Cesium.Material.DynamicWallImage = "渐变图片地址";
Cesium.Material.DynamicWallSource = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
	                                {\n\
	                                czm_material material = czm_getDefaultMaterial(materialInput);\n\
	                                vec2 st = materialInput.st;\n\
	                                vec4 colorImage = texture2D(image, vec2(fract(st.t - time), st.t));\n\
	                                vec4 fragColor;\n\
	                                fragColor.rgb = color.rgb / 1.0;\n\
	                                fragColor = czm_gammaCorrect(fragColor);\n\
	                                material.alpha = colorImage.a * color.a;\n\
	                                material.diffuse = color.rgb;\n\
	                                material.emission = fragColor.rgb;\n\
	                                return material;\n\
	                                }";
Cesium.Material._materialCache.addMaterial(Cesium.Material.DynamicWallType, {
  fabric: {
    type: Cesium.Material.DynamicWallType,
    uniforms: {
      color: new Cesium.Color(1.0, 1.0, 1.0, 1),
      image: Cesium.Material.DynamicWallImage,
      time: 0
    },
    source: Cesium.Material.DynamicWallSource
  },
  translucent: function(material) {
    return true;
  }
});

2、纹理图片

在这里插入图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

3、代码调用

/**
 * @description:立体墙效果
 * @date:2022-02-12
 * @param:viewer
 * @positions: 墙体底部位置坐标
 */
function drawWall(viewer, positions) {
  // 绘制墙体
  this.viewer.entities.add({
    name: "立体墙效果",
    wall: {
      positions: positions,
      // 设置高度
      maximumHeights: new Array(positions.length).fill(100),
      minimunHeights: new Array(positions.length).fill(0),
      // 调用前需先引用
      material: new Cesium.DynamicWallMaterialProperty({
        color: Cesium.Color.fromBytes(55, 96, 56).withAlpha(0.7),
        duration: 3000
      }),
    }
  })
}

九、光线

var Line = viewer.entities.add({
  name : 'aGlowLine',
  polyline : {
    positions : Cesium.Cartesian3.fromDegreesArray(group),
    width : 20,
    material : new Cesium.PolylineGlowMaterialProperty({
      glowPower : 0.3,
      color : Cesium.Color.BLUE.withAlpha(0.9),
    })
  }
});

十、点击绘制多边形(动态绘制多边形)

调用 click_draw_polygon() 方法就可以

// 多边形全部点的数组
var polygon_point_arr = [];
// 临时多边形entity
var temporary_polygon_entity = null;
var handler = null;

// 开启绘制的方法
function click_draw_polygon() {
  // 清除可能会用到的监听事件
  if (handler) {
    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  //鼠标左键--确定选中点
  handler.setInputAction((event) => {
    // 屏幕坐标转为空间坐标
    let cartesian = viewer.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid);
    // 判断是否定义(是否可以获取到空间坐标)
    if (Cesium.defined(cartesian)) {
      // 将点添加进保存多边形点的数组中,鼠标停止移动的时添加的点和,点击时候添加的点,坐标一样
      polygon_point_arr.push(cartesian);
      // 判断是否开始绘制动态多边形,没有的话则开始绘制
      if (temporary_polygon_entity == null) {
        // 绘制动态多边形
        draw_dynamic_polygon();
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  //鼠标移动--实时绘制多边形
  handler.setInputAction((event) => {
    // 屏幕坐标转为空间坐标
    let cartesian = viewer.camera.pickEllipsoid(event.endPosition, viewer.scene.globe.ellipsoid);
    // 判断是否定义(是否可以获取到空间坐标)
    if (Cesium.defined(cartesian)) {
      // 判断是否已经开始绘制动态多边形,已经开始的话,则可以动态拾取鼠标移动的点,修改点的坐标
      if (temporary_polygon_entity) {
        // 只要元素点大于一,每次就删除一个点,因为实时动态的点是添加上去的
        if (polygon_point_arr.length > 1) {
          // 删除数组最后一个元素(鼠标移动添加进去的点)
          polygon_point_arr.pop();
        }
        // 将新的点添加进动态多边形点的数组中,用于实时变化,注意:这里是先添加了一个点,然后再删除点,再添加,这样重复的
        polygon_point_arr.push(cartesian);
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  //鼠标右键--结束绘制
  handler.setInputAction((event) => {
    // 取消鼠标移动监听
    handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 清除动态绘制的多边形
    viewer.entities.remove(temporary_polygon_entity);
    // 删除保存的临时多边形的entity
    temporary_polygon_entity = null;
    // 绘制结果多边形
    draw_polygon();
    // 清空多边形点数组,用于下次绘制
    polygon_point_arr = [];
    // 清除所有事件
    if (handler) {
      handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
      handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}

//绘制动态多边形
function draw_dynamic_polygon() {
  temporary_polygon_entity = viewer.entities.add({
    polygon: {
      // 这个方法上面有重点说明
      hierarchy: new Cesium.CallbackProperty(() => {
        // PolygonHierarchy 定义多边形及其孔的线性环的层次结构(空间坐标数组)
        return new Cesium.PolygonHierarchy(polygon_point_arr);
      }, false),
      extrudedHeight: 0,  // 多边体的高度(多边形拉伸高度)
      height: 10,  // 多边形离地高度
      material: Cesium.Color.RED.withAlpha(0.5),
    },
  });
}

//绘制结果多边形
function draw_polygon() {
  // 删除最后一个动态添加的点,如果鼠标没移动,最后一个和倒数第二个是一样的,所以也要删除
  polygon_point_arr.pop();
  // 三个点以上才能绘制成多边形
  if (polygon_point_arr.length >= 3) {
    let polygon_point_entity = viewer.entities.add({
      polygon: {
        hierarchy: polygon_point_arr,
        extrudedHeight: 0,  // 多边体的高度(多边形拉伸高度)
        height: 10,  // 多边形离地高度
        material: Cesium.Color.RED.withAlpha(0.5),
        outlineColor: Cesium.Color.RED,
        outlineWidth: 2
      },
    });
    // 坐标转换--这里可以输出所有点位坐标,不需要就删除了
    // polygon_point_arr.forEach(val => {
    //   let polyObj = {}
    //   let cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(val)
    //   polyObj.lon = Cesium.Math.toDegrees(cartographic.longitude)
    //   polyObj.lat = Cesium.Math.toDegrees(cartographic.latitude)
    //   point_arr.push([polyObj.lon, polyObj.lat])
    // })
    // return point_arr;
  } else {
    return
  }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值