数字孪生Web 后台dt( digital twin)2.0版本 统一命名格式
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

9830 lines
449 KiB

"use strict";
/**
* @description 重构工具包 剥离功能模块 解耦合以及模块权限 可以自动安装不同模块使用
* @private
* @author zhangti
* @version: 1.0.0
* @Date: 2019-09-05 10:58:30
* @LastEditors: zhangti
*/
; if (typeof Cesium !== 'undefined')
Cesium.D3Kit = (function () {
// 版本
var version = '1.5'
// 作者
var author = 'zhangti'
// 地址
var github = 'https://github.com/zhangti0708/cesium-examples'
// 示例地址
var examplesAddr = 'http://zhangticcc.gitee.io/webgis'
// cesium版本
var CesiumVersion = Cesium.VERSION || ''
/**
* 基础模块
* @param {*} viewer
*/
function Base(viewer) {
if (viewer) {
this._installBaiduImageryProvider()
this._installGooGleImageryProvider()
this._installAmapImageryProvider()
this._installTencentImageryProvider()
this._installTdtImageryProvider()
}
}
Base.prototype = {
// 天空盒
setOneSkyBox: function () {
return new Cesium.SkyBox({
sources: {
positiveX: 'data/images/SkyBox/00h+00.jpg',
negativeX: 'data/images/SkyBox/12h+00.jpg',
positiveY: 'data/images/SkyBox/06h+00.jpg',
negativeY: 'data/images/SkyBox/18h+00.jpg',
positiveZ: 'data/images/SkyBox/06h+90.jpg',
negativeZ: 'data/images/SkyBox/06h-90.jpg'
}
})
},
// 天空盒2
setTwoSkyBox: function () {
return new Cesium.SkyBox({
sources: {
positiveX: 'data/images/SkyBox/Version2_dark_px.jpg',
negativeX: 'data/images/SkyBox/Version2_dark_mx.jpg',
positiveY: 'data/images/SkyBox/Version2_dark_py.jpg',
negativeY: 'data/images/SkyBox/Version2_dark_my.jpg',
positiveZ: 'data/images/SkyBox/Version2_dark_pz.jpg',
negativeZ: 'data/images/SkyBox/Version2_dark_mz.jpg'
}
})
},
// 天空盒3
setThreeSkyBox: function () {
return new Cesium.SkyBox({
sources: {
positiveX: 'data/images/SkyBox/tycho2t3_80_pxs.jpg',
negativeX: 'data/images/SkyBox/tycho2t3_80_mxs.jpg',
positiveY: 'data/images/SkyBox/tycho2t3_80_pys.jpg',
negativeY: 'data/images/SkyBox/tycho2t3_80_mys.jpg',
positiveZ: 'data/images/SkyBox/tycho2t3_80_pzs.jpg',
negativeZ: 'data/images/SkyBox/tycho2t3_80_mzs.jpg'
}
})
},
//近景天空盒
setOneGroundSkyBox: function () {
return new Cesium.GroundSkyBox({
sources: {
positiveX: 'data/images/SkyBox/rightav9.jpg',
negativeX: 'data/images/SkyBox/leftav9.jpg',
positiveY: 'data/images/SkyBox/frontav9.jpg',
negativeY: 'data/images/SkyBox/backav9.jpg',
positiveZ: 'data/images/SkyBox/topav9.jpg',
negativeZ: 'data/images/SkyBox/bottomav9.jpg'
}
});
},
//近景天空盒 2
setTwoGroundSkyBox: function () {
return new Cesium.GroundSkyBox({
sources: {
positiveX: 'data/images/SkyBox/SunSetRight.png',
negativeX: 'data/images/SkyBox/SunSetLeft.png',
positiveY: 'data/images/SkyBox/SunSetFront.png',
negativeY: 'data/images/SkyBox/SunSetBack.png',
positiveZ: 'data/images/SkyBox/SunSetUp.png',
negativeZ: 'data/images/SkyBox/SunSetDown.png'
}
});
},
//近景天空盒 3
setThreeGroundSkyBox: function () {
return new Cesium.GroundSkyBox({
sources: {
positiveX: 'data/images/SkyBox/Right.jpg',
negativeX: 'data/images/SkyBox/Left.jpg',
positiveY: 'data/images/SkyBox/Front.jpg',
negativeY: 'data/images/SkyBox/Back.jpg',
positiveZ: 'data/images/SkyBox/Up.jpg',
negativeZ: 'data/images/SkyBox/Down.jpg'
}
});
},
//黑夜特效
setDarkEffect: function (options) {
options = options || {}
var fs =
'uniform sampler2D colorTexture;\n' +
'varying vec2 v_textureCoordinates;\n' +
'uniform float scale;\n' +
'uniform vec3 offset;\n' +
'void main() {\n' +
' // vec4 color = texture2D(colorTexture, v_textureCoordinates);\n' +
' vec4 color = texture2D(colorTexture, v_textureCoordinates);\n' +
' // float gray = 0.2989*color.r+0.5870*color.g+0.1140*color.b;\n' +
' // gl_FragColor = vec4(gray,gray,2.0*(gray+1.0), 1.0);\n' +
' gl_FragColor = vec4(color.r*0.2,color.g * 0.4,color.b*0.6, 1.0);\n' +
'}\n';
return this._viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
name: 'darkEffect',
fragmentShader: fs,
uniforms: {
scale: 1.0,
offset: function () {
return options.offset || new Cesium.Cartesian3(0.1, 0.2, 0.3);
}
}
}));
},
// 场景蓝光
setBlurBloom: function (options) {
if (this._viewer && options) {
var fs = 'uniform float height;\n' +
'uniform float width;\n' +
'uniform sampler2D colorTexture1;\n' +
'\n' +
'varying vec2 v_textureCoordinates;\n' +
'\n' +
'const int SAMPLES = 9;\n' +
'void main()\n' +
'{\n' +
'vec2 st = v_textureCoordinates;\n' +
'float wr = float(1.0 / width);\n' +
'float hr = float(1.0 / height);\n' +
'vec4 result = vec4(0.0);\n' +
'int count = 0;\n' +
'for(int i = -SAMPLES; i <= SAMPLES; ++i){\n' +
'for(int j = -SAMPLES; j <= SAMPLES; ++j){\n' +
'vec2 offset = vec2(float(i) * wr, float(j) * hr);\n' +
'result += texture2D(colorTexture1, st + offset);\n' +
'}\n' +
'}\n' +
'result = result / float(count);\n' +
'gl_FragColor = result;\n' +
'}\n';
return this._viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
name: 'blur_x_direction',
fragmentShader: fs,
uniforms: {
width: options.width,
height: options.height,
colorTexture1: "Bright"
}
}));
}
},
//雨天特效
setRainEffect: function () {
if (this._viewer) {
var fs = "uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float hash(float x){\n\
return fract(sin(x*23.3)*13.13);\n\
}\n\
\n\
void main(){\n\
float time = czm_frameNumber / 60.0;\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=-.4;\n\
float si=sin(a),co=cos(a);\n\
uv*=mat2(co,-si,si,co);\n\
uv*=length(uv+vec2(0,4.9))*.3+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), 0.2);\n\
}\n\
";
return this._viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
name: 'rainEffect',
fragmentShader: fs
}));
}
},
//雪天特效
setSnowEffect: function () {
if (this._viewer) {
var fs = "uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float snow(vec2 uv,float scale){\n\
float time = czm_frameNumber / 60.0;\n\
float w=smoothstep(1.,0.,-uv.y*(scale/10.));\n\
if(w<.1)return 0.;\n\
uv+=time/scale;\n\
uv.y+=time*2./scale;\n\
uv.x+=sin(uv.y+time*.5)/scale;\n\
uv*=scale;\n\
vec2 s=floor(uv),f=fract(uv),p;\n\
float k=3.,d;\n\
p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;\n\
d=length(p);\n\
k=min(d,k);\n\
k=smoothstep(0.,k,sin(f.x+f.y)*0.01);\n\
return k*w;\n\
}\n\
\n\
void main(){\n\
vec2 resolution = czm_viewport.zw;\n\
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
vec3 finalColor=vec3(0);\n\
float c = 0.0;\n\
c+=snow(uv,30.)*.0;\n\
c+=snow(uv,20.)*.0;\n\
c+=snow(uv,15.)*.0;\n\
c+=snow(uv,10.);\n\
c+=snow(uv,8.);\n\
c+=snow(uv,6.);\n\
c+=snow(uv,5.);\n\
finalColor=(vec3(c));\n\
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.3);\n\
\n\
}\n\
";
return this._viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
name: 'snowEffect',
fragmentShader: fs
}));
}
},
// 雾天
setFogEffect: function () {
if (this._viewer) {
var fs =
"float getDistance(sampler2D depthTexture, vec2 texCoords) \n" +
"{ \n" +
" float depth = czm_unpackDepth(texture2D(depthTexture, texCoords)); \n" +
" if (depth == 0.0) { \n" +
" return czm_infinity; \n" +
" } \n" +
" vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, depth); \n" +
" return -eyeCoordinate.z / eyeCoordinate.w; \n" +
"} \n" +
"float interpolateByDistance(vec4 nearFarScalar, float distance) \n" +
"{ \n" +
" float startDistance = nearFarScalar.x; \n" +
" float startValue = nearFarScalar.y; \n" +
" float endDistance = nearFarScalar.z; \n" +
" float endValue = nearFarScalar.w; \n" +
" float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0); \n" +
" return mix(startValue, endValue, t); \n" +
"} \n" +
"vec4 alphaBlend(vec4 sourceColor, vec4 destinationColor) \n" +
"{ \n" +
" return sourceColor * vec4(sourceColor.aaa, 1.0) + destinationColor * (1.0 - sourceColor.a); \n" +
"} \n" +
"uniform sampler2D colorTexture; \n" +
"uniform sampler2D depthTexture; \n" +
"uniform vec4 fogByDistance; \n" +
"uniform vec4 fogColor; \n" +
"varying vec2 v_textureCoordinates; \n" +
"void main(void) \n" +
"{ \n" +
" float distance = getDistance(depthTexture, v_textureCoordinates); \n" +
" vec4 sceneColor = texture2D(colorTexture, v_textureCoordinates); \n" +
" float blendAmount = interpolateByDistance(fogByDistance, distance); \n" +
" vec4 finalFogColor = vec4(fogColor.rgb, fogColor.a * blendAmount); \n" +
" gl_FragColor = alphaBlend(finalFogColor, sceneColor); \n" +
"} \n";
return this._viewer.scene.postProcessStages.add(
new Cesium.PostProcessStage({
fragmentShader: fs,
uniforms: {
fogByDistance: new Cesium.Cartesian4(10, 0.0, 200, 1.0),
fogColor: Cesium.Color.BLACK,
},
})
);
}
},
/**
* 默认场景配置
*/
setDefSceneConfig: function () {
if (this._viewer) {
this._viewer.scene.sun.show = false;
this._viewer.scene.moon.show = false;
this._viewer.scene.fxaa = true;
this._viewer.scene.globe.depthTestAgainstTerrain = true;
this._viewer.scene.undergroundMode = false;
this._viewer.scene.terrainProvider.isCreateSkirt = false;
this._viewer.scene.skyAtmosphere.show = false;
this._viewer.scene.globe.showGroundAtmosphere = false
this._viewer.scene.globe.enableLighting = true
this._viewer.scene.fog.enabled = false
this._viewer.cesiumWidget.creditContainer.style.display = "none";
}
},
/**
* 场景泛光
*/
setBloomLightScene: function () {
if (this._viewer) {
this._viewer.scene.postProcessStages.bloom.enabled = true
this._viewer.scene.postProcessStages.bloom.uniforms.contrast = 119
this._viewer.scene.postProcessStages.bloom.uniforms.brightness = -0.4
this._viewer.scene.postProcessStages.bloom.uniforms.glowOnly = false
this._viewer.scene.postProcessStages.bloom.uniforms.delta = 0.9
this._viewer.scene.postProcessStages.bloom.uniforms.sigma = 3.78
this._viewer.scene.postProcessStages.bloom.uniforms.stepSize = 5
this._viewer.scene.postProcessStages.bloom.uniforms.isSelected = false
}
},
//相机定位
setView: function (options) {
if (this._viewer && options && options.position) {
if (options.distance) { //距离
var pos1 = new Cesium.Cartesian3(0, options.distance, opt.distance);
options.position = Cesium.Cartesian3.add(options.position, pos1, new Cesium.Cartesian3());
}
this._viewer.scene.camera.setView({
destination: options.position,
orientation: options.orientation || {
heading: Cesium.Math.toRadians(90.0),
pitch: Cesium.Math.toRadians(90.0),
roll: Cesium.Math.toRadians(0.0)
},
});
}
},
//相机飞行
flyTo: function (options) {
if (this._viewer && options && options.position) {
if (options.distance) { //距离
var pos1 = new Cesium.Cartesian3(0, options.distance, options.distance);
options.position = Cesium.Cartesian3.add(options.position, pos1, new Cesium.Cartesian3());
}
this._viewer.scene.camera.flyTo({
destination: options.position,
orientation: options.orientation || {
heading: Cesium.Math.toRadians(90.0),
pitch: Cesium.Math.toRadians(90.0),
roll: Cesium.Math.toRadians(0.0)
},
// pitchAdjustHeight: 500,
easingFunction: options.easingFunction || Cesium.EasingFunction.LINEAR_NONE,
duration: options.duration || 3,
complete: options.callback
})
}
},
//坐标转换 笛卡尔转84
transformCartesianToWGS84: function (cartesian) {
if (this._viewer && cartesian) {
var ellipsoid = Cesium.Ellipsoid.WGS84
var cartographic = ellipsoid.cartesianToCartographic(cartesian)
return {
lng: Cesium.Math.toDegrees(cartographic.longitude),
lat: Cesium.Math.toDegrees(cartographic.latitude),
alt: cartographic.height
}
}
},
//坐标数组转换 笛卡尔转84
transformWGS84ArrayToCartesianArray: function (WSG84Arr, alt) {
if (this._viewer && WSG84Arr) {
var $this = this
return WSG84Arr
? WSG84Arr.map(function (item) { return $this.transformWGS84ToCartesian(item, alt) })
: []
}
},
//坐标转换 84转笛卡尔
transformWGS84ToCartesian: function (position, alt) {
if (this._viewer) {
return position
? Cesium.Cartesian3.fromDegrees(
position.lng || position.lon,
position.lat,
position.alt = alt || position.alt,
Cesium.Ellipsoid.WGS84
)
: Cesium.Cartesian3.ZERO
}
},
//坐标数组转换 84转笛卡尔
transformCartesianArrayToWGS84Array: function (cartesianArr) {
if (this._viewer) {
var $this = this
return cartesianArr
? cartesianArr.map(function (item) { return $this.transformCartesianToWGS84(item) })
: []
}
},
/**
* 相机绕点旋转
* @param viewer
* let options = {
lng: 117.1423291616,
lat: 39.0645831633,
height: 15.8,
heading: 0.0,
pitch: 0.0,
roll: 0.0
};
viewer.clock.stopTime = viewer.clock.startTime
*/
setCameraEotateHeading(options) {
if (options) {
let viewer = this._viewer
let position = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.height);
// 相机看点的角度,如果大于0那么则是从地底往上看,所以要为负值,这里取-30度
let pitch = Cesium.Math.toRadians(-30);
// 给定飞行一周所需时间,比如10s, 那么每秒转动度数
let angle = 360 / 30;
// 给定相机距离点多少距离飞行,这里取值为5000m
let distance = 5000;
let startTime = Cesium.JulianDate.fromDate(new Date());
viewer.clock.startTime = startTime.clone(); // 开始时间
viewer.clock.currentTime = startTime.clone(); // 当前时间
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
//相机的当前heading
let initialHeading = viewer.camera.heading;
let Exection = function TimeExecution() {
// 当前已经过去的时间,单位s
let delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
let heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
viewer.scene.camera.setView({
destination: position, // 点的坐标
orientation: {
heading: heading,
pitch: pitch,
}
});
viewer.scene.camera.moveBackward(distance);
if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
viewer.clock.onTick.removeEventListener(Exection);
}
};
viewer.clock.onTick.addEventListener(Exection);
}
},
/**
*
* @param {*} position
* 84坐标转制图坐标
*/
transformWGS84ToCartographic: function (position) {
return position
? Cesium.Cartographic.fromDegrees(
position.lng || position.lon,
position.lat,
position.alt
)
: Cesium.Cartographic.ZERO
},
// 拾取位置点
getCatesian3FromPX: function (px) {
if (this._viewer && px) {
// var picks = this._viewer.scene.drillPick(px); // 3dtilset
// for (var i = 0; i < picks.length; i++) {
// if (picks[i] instanceof Cesium.Cesium3DTileFeature) { //模型上拾取
// isOn3dtiles = true;
// }
// }
var picks = this._viewer.scene.pick(px)
var cartesian = null;
var isOn3dtiles = false, isOnTerrain = false;
if (picks instanceof Cesium.Cesium3DTileFeature) { //模型上拾取
isOn3dtiles = true;
}
// 3dtilset
if (isOn3dtiles) {
cartesian = this._viewer.scene.pickPosition(px);
if (cartesian) {
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
if (cartographic.height < 0) cartographic.height = 0;
let lon = Cesium.Math.toDegrees(cartographic.longitude)
, lat = Cesium.Math.toDegrees(cartographic.latitude)
, height = cartographic.height;//模型高度
cartesian = this.transformWGS84ToCartesian({ lng: lon, lat: lat, alt: height })
}
}
// 地形
if (!picks && !viewer.terrainProvide instanceof Cesium.EllipsoidTerrainProvider) {
var ray = this._viewer.scene.camera.getPickRay(px);
if (!ray) return null;
cartesian = this._viewer.scene.globe.pick(ray, this._viewer.scene);
isOnTerrain = true
}
// 地球
if (!isOn3dtiles && !isOnTerrain) {
cartesian = this._viewer.scene.camera.pickEllipsoid(px, this._viewer.scene.globe.ellipsoid);
}
if (cartesian) {
let position = this.transformCartesianToWGS84(cartesian)
if (position.alt < 0) {
cartesian = this.transformWGS84ToCartesian(position, 0.1)
}
return cartesian;
}
return false;
}
},
//获取相机位置
getCameraPosition: function () {
if (this._viewer) {
var result = this._viewer.scene.camera.pickEllipsoid(new Cesium.Cartesian2(this._viewer.canvas.clientWidth / 2, this._viewer.canvas
.clientHeight / 2));
if (result) {
var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result),
lon = curPosition.longitude * 180 / Math.PI
, lat = curPosition.latitude * 180 / Math.PI;
var direction = this._viewer.camera._direction,
x = Cesium.Math.toDegrees(direction.x),
y = Cesium.Math.toDegrees(direction.y),
z = Cesium.Math.toDegrees(direction.z),
height = this._viewer.camera.positionCartographic.height,
heading = Cesium.Math.toDegrees(this._viewer.camera.heading),
pitch = Cesium.Math.toDegrees(this._viewer.camera.pitch),
roll = Cesium.Math.toDegrees(this._viewer.camera.roll);
var rectangle = this._viewer.camera.computeViewRectangle(),
west = rectangle.west / Math.PI * 180,
north = rectangle.north / Math.PI * 180,
east = rectangle.east / Math.PI * 180,
south = rectangle.south / Math.PI * 180,
centerx = (west + east) / 2,
cnetery = (north + south) / 2;
return {
lon: lon,
lat: lat,
height: height,
heading: heading,
pitch: pitch,
roll: roll,
position: this._viewer.camera.position,
center: { x: centerx, y: cnetery },
direction: new Cesium.Cartesian3(x, y, z)
};
}
}
},
//修改相机状态
updateCameraState: function (flag) {
this._viewer.scene._screenSpaceCameraController.enableRotate = flag;
this._viewer.scene._screenSpaceCameraController.enableTranslate = flag;
this._viewer.scene._screenSpaceCameraController.enableZoom = flag;
this._viewer.scene._screenSpaceCameraController.enableTilt = flag;
this._viewer.scene._screenSpaceCameraController.enableLook = flag;
},
//鼠标事件注册
bindHandelEvent: function (_mouseClickHandler, _mouseMoveHandler, _mouseDbClickHandler) {
if (this._viewer) {
var _handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.canvas)
_handlers.setInputAction(function (movement) {
_mouseClickHandler && _mouseClickHandler(movement, _handlers)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
_handlers.setInputAction(function (movement) {
_mouseMoveHandler && _mouseMoveHandler(movement, _handlers)
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
_handlers.setInputAction(function (movement) {
_mouseDbClickHandler && _mouseDbClickHandler(movement, _handlers)
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
}
},
//获取鼠标信息
getHandelPosition: function (callback) {
if (this._viewer) {
var _handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas), $this = this;
_handler.setInputAction(function (movement) {
var cartesian = $this._viewer.scene.camera.pickEllipsoid(movement.endPosition, $this._viewer.scene.globe.ellipsoid);
if (typeof callback === 'function') {
callback($this.transformCartesianToWGS84(cartesian), _handler);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
},
//保存当前场景png
saveSceneImages: function () {
if (this._viewer) {
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
var canvas = this._viewer.scene.canvas;
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
var link = document.createElement("a");
var strDataURI = image.substr(22, image.length);
var blob = dataURLtoBlob(image);
var objurl = URL.createObjectURL(blob);
link.download = "scene.png";
link.href = objurl;
link.click();
}
},
/**
* amap
*/
_installAmapImageryProvider: function () {
const IMG_URL =
'https://webst{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}';
const ELEC_URL =
'http://webrd{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}';
function AmapImageryProvider(options) {
options['url'] = options.style === 'img' ? IMG_URL : ELEC_URL
if (!options.subdomains) {
options['subdomains'] = ['01', '02', '03', '04']
}
return new Cesium.UrlTemplateImageryProvider(options)
}
Cesium.AmapImageryProvider = AmapImageryProvider
},
/**
* 天地图
*/
_installTdtImageryProvider: function () {
const MAP_URL =
'http://t{s}.tianditu.gov.cn/{layer}_c/wmts?service=WMTS&version=1.0.0&request=GetTile&tilematrix={TileMatrix}&layer={layer}&style={style}&tilerow={TileRow}&tilecol={TileCol}&tilematrixset={TileMatrixSet}&format=tiles&tk={key}';
function TdtImageryProvider(options) {
return new Cesium.UrlTemplateImageryProvider({
url: MAP_URL.replace(/\{layer\}/g, options.style || 'vec').replace(
/\{key\}/g,
options.key || ''
),
style: 'default',
format: 'tiles',
tileMatrixSetID: 'c',
subdomains: [...Array(6).keys()].map(item => (item + 1).toString()),
tileMatrixLabels: [...Array(18).keys()].map(item =>
(item + 1).toString()
),
tilingScheme: new Cesium.GeographicTilingScheme(),
maximumLevel: 18
})
}
Cesium.TdtImageryProvider = TdtImageryProvider
},
/**
* 腾讯
*/
_installTencentImageryProvider: function () {
const ELEC_URL =
'https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&styleid=1000&scene=0&version=347';
function TencentImageryProvider(options) {
options['url'] = ELEC_URL
if (!options.subdomains) {
options['subdomains'] = ['0', '1', '2']
}
return new Cesium.UrlTemplateImageryProvider(options)
}
Cesium.TencentImageryProvider = TencentImageryProvider
},
/**
* google
*/
_installGooGleImageryProvider: function () {
//标注 影像 地形三种
const ELEC_URL =
'http://mt{s}.google.cn/vt/lyrs=m@207000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Galile';
const IMG_URL =
'http://mt{s}.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}&s=Gali';
const TER_URL =
'http://mt{s}.google.cn/vt/lyrs=t@131,r@227000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Galile';
function GoogleImageryProvider(options) {
options['url'] =
options.style === 'img'
? IMG_URL
: options.style === 'ter'
? TER_URL
: ELEC_URL
if (!options.subdomains) {
options['subdomains'] = ['1', '2', '3', '4', '5']
}
return new Cesium.UrlTemplateImageryProvider(options)
}
Cesium.GoogleImageryProvider = GoogleImageryProvider
},
/**
* 百度影像拓展
*/
_installBaiduImageryProvider: function () {
var TEMP_MAP_URL =
'http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid={style}'
function BaiduImageryProvider(options) {
TEMP_MAP_URL = options.temp_url || TEMP_MAP_URL
this._url = TEMP_MAP_URL
this._tileWidth = 256
this._tileHeight = 256
this._maximumLevel = 18
this._minimumLevel = 1
this._tilingScheme = new Cesium.WebMercatorTilingScheme({
rectangleSouthwestInMeters: new Cesium.Cartesian2(-33554054, -33746824),
rectangleNortheastInMeters: new Cesium.Cartesian2(33554054, 33746824)
})
this._rectangle = this._tilingScheme.rectangle
this._credit = undefined
this._style = options.style || 'normal'
}
Object.defineProperties(BaiduImageryProvider.prototype, {
url: {
get: function () {
return this._url;
}
},
token: {
get: function () {
return this._token;
}
},
tileWidth: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tileWidth must not be called before the imagery provider is ready.'
)
}
return this._tileWidth
}
},
tileHeight: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tileHeight must not be called before the imagery provider is ready.'
)
}
return this._tileHeight
}
},
maximumLevel: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tileHeight must not be called before the imagery provider is ready.'
)
}
return this._tileHeight
}
},
minimumLevel: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'minimumLevel must not be called before the imagery provider is ready.'
)
}
return 0
}
},
tilingScheme: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tilingScheme must not be called before the imagery provider is ready.'
)
}
return this._tilingScheme
}
},
rectangle: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError(
'rectangle must not be called before the imagery provider is ready.'
)
}
return this._rectangle
}
},
ready: {
get: function () {
return !!this._url
}
},
credit: {
get: function () {
return this._credit
}
}
});
BaiduImageryProvider.prototype.getTileCredits = function (x, y, level) { }
BaiduImageryProvider.prototype.requestImage = function (x, y, level) {
if (!this.ready) {
throw new Cesium.DeveloperError(
'requestImage must not be called before the imagery provider is ready.'
)
}
var xTiles = this._tilingScheme.getNumberOfXTilesAtLevel(level)
var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level)
var url = this._url
.replace('{x}', x - xTiles / 2)
.replace('{y}', yTiles / 2 - y - 1)
.replace('{z}', level)
.replace('{s}', 1)
.replace('{style}', this._style)
return Cesium.ImageryProvider.loadImage(this, url)
}
Cesium.BaiduImageryProvider = BaiduImageryProvider
}
}
/**
* dom 工具
* @param {*} viewer
*/
function DomUtil(viewer) { }
DomUtil.prototype = {
/**
* 创建dom元素
* @param {*} tagName
* @param {*} className
* @param {*} container
*/
createDom: function (tagName, className, container) {
var el = document.createElement(tagName)
el.className = className || ''
if (container) {
container.appendChild(el)
}
return el
},
//删除 element
removeDom: function (el) {
var parent = el.parentNode
if (parent) {
parent.removeChild(el)
}
},
//清空 element
emptyDom: function (el) {
while (el.firstChild) {
el.removeChild(el.firstChild)
}
},
//添加 class
addDomClass: function (el, name) {
if (el.classList !== undefined) {
var classes = this.splitWords(name)
for (var i = 0, len = classes.length; i < len; i++) {
el.classList.add(classes[i])
}
} else if (!this.hasClass(el, name)) {
var className = this.getClass(el)
this.setClass(el, (className ? className + ' ' : '') + name)
}
},
//删除class
removeDomClass: function (el, name) {
if (el.classList !== undefined) {
el.classList.remove(name)
} else {
this.setClass(el, this.trim((' ' + this.getClass(el) + ' ').replace(' ' + name + ' ', ' ')))
}
},
//设置 class
setDomClass: function (el, name) {
if (el.className.baseVal === undefined) {
el.className = name
} else {
// in case of SVG element
el.className.baseVal = name
}
},
//获取 el class
getDomClass: function (el) {
// Check if the element is an SVGElementInstance and use the correspondingElement instead
// (Required for linked SVG elements in IE11.)
if (el.correspondingElement) {
el = el.correspondingElement
}
return el.className.baseVal === undefined ? el.className : el.className.baseVal
},
//创建 svg
createDomSvg: function (width, height, path, container) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg:svg')
svg.setAttribute('class', 'svg-path')
svg.setAttribute('width', width)
svg.setAttribute('height', height)
svg.setAttribute('viewBox', '0 0 ' + width + ' ' + height)
var pathEl = document.createElementNS('http://www.w3.org/2000/svg', 'path')
pathEl.setAttribute('d', path)
svg.appendChild(pathEl)
if (container) {
container.appendChild(svg)
}
return svg
},
//生成uuid
createUUID: function (prefix) {
prefix = prefix || 'D'
const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(
''
)
let uuid = []
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
uuid[14] = '4'
let r
for (let i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | (Math.random() * 16)
uuid[i] = CHARS[i == 19 ? (r & 0x3) | 0x8 : r]
}
}
return prefix + '-' + uuid.join('')
}
}
/**
* 超图模块
* @param {*} viewer
*/
function SuperMap(viewer) {
if (viewer) {
this._superMapLayer = new Cesium.CustomDataSource('superMapLayer')
viewer && viewer.dataSources.add(this._superMapLayer)
}
}
SuperMap.prototype = {
//发光纹理纹理
setHypsometric: function (layer, option) {
option = option || {}
if (this._viewer && layer && option) {
var hyp = new Cesium.HypsometricSetting();
// hypsometricSetting.DisplayMode= Cesium.HysometricSettingEnum.DisplayMode.FACE;LineColor
hyp.emissionTextureUrl = option.emissionTextureUrl || "data/images/Textures/lly2.png";
hyp.Opacity = 1
hyp.emissionTexCoordUSpeed = option.emissionTexCoordUSpeed || 0.3;
// var hyp = new Cesium.HypsometricSetting();
// //设置颜色表
// var colorTable = new Cesium.ColorTable();
// colorTable.insert(300, new Cesium.Color(1, 1, 0));
// colorTable.insert(200, new Cesium.Color(1, 0, 0));
// colorTable.insert(100, new Cesium.Color(0, 0, 1));
// hyp.ColorTable = colorTable;
layer.hypsometricSetting = {
hypsometricSetting: hyp
}
}
},
//点光源
setPointLight: function (position, options) {
if (this._viewer && position) {
var DEF_OPTS = {
color: options.color || new Cesium.Color(1, 1, 2, 0.8),
cutoffDistance: options.cutoffDistance || 1000,
decay: options.decay || 0.5,
intensity: options.intensity || 1
};
options = options || DEF_OPTS
var pointLight = new Cesium.PointLight(position, options)
this._viewer.scene.addLightSource(pointLight);
return pointLight
}
},
//平行光
setDirectionalLight: function (position, options) {
if (this._viewer && position) {
var DEF_OPTS = {
targetPosition: options.targetPosition, //方向
color: options.color || new Cesium.Color(1, 1, 2, 0.8),
intensity: options.intensity || 1
};
options = options || DEF_OPTS
var directionalLight = new Cesium.DirectionalLight(position, options)
this._viewer.scene.addLightSource(directionalLight);
return directionalLight
}
},
//扫描圆
setScanCircleEffect: function (options) {
if (this._viewer && options && options.position) {
this._viewer.scene.scanEffect.color = options.color || new Cesium.Color(2.0, 1.0, 1.0, 1);
this._viewer.scene.scanEffect.period = options.period || 3.0;
this._viewer.scene.scanEffect.centerPostion = options.position
this._viewer.scene.scanEffect.speed = 800
this._viewer.scene.scanEffect.textureUrl = options.textureUrl || 'examples/images/cc2.jpg'
this._viewer.scene.scanEffect.mode = Cesium.ScanEffectMode.CIRCLE
setTimeout(() => {
this._viewer.scene.scanEffect.show = true
}, 5000)
}
},
//扫描线
setScanLineEffect: function (options) {
if (this._viewer && options && options.positions) {
var dir = new Cesium.Cartesian3();
Cesium.Cartesian3.subtract(options.positions[0], options.positions[1], dir); // 获取扫描方向向量
this._viewer.scene.scanEffect.color = options.color || new Cesium.Color(1.0, 1.0, 1.0, 1.0);
this._viewer.scene.scanEffect.period = options.period || 3.0;
this._viewer.scene.scanEffect.centerPostion = options.positions[0]
this._viewer.scene.scanEffect.textureUrl = options.textureUrl || 'examples/images/ll1.jpg'
this._viewer.scene.scanEffect.lineMoveDirection = dir;
this._viewer.scene.scanEffect.mode = Cesium.ScanEffectMode.LINE
setTimeout(() => {
this._viewer.scene.scanEffect.show = true
}, 5000)
}
},
//添加火焰粒子
setFlameParticle: function (options) {
if (this._viewer && options && options.position) {
var entity = this._viewer.entities.add({
position: options.position,
}), emitterModelMatrix = new Cesium.Matrix4(),
translation = new Cesium.Cartesian3(),
rotation = new Cesium.Quaternion(),
hpr = new Cesium.HeadingPitchRoll(),
trs = new Cesium.TranslationRotationScale(),
flameParticleSystem = this._viewer.scene.primitives.add(new Cesium.ParticleSystem({
image: options.image || 'examples/images/ParticleSystem/fire4.png',
startColor: options.startColor || new Cesium.Color(1, 1, 1, 1),
endColor: options.endColor || new Cesium.Color(0.5, 0, 0, 0),
startScale: options.startScale || 5.0,
endScale: options.endScale || 3.5,
minimumParticleLife: options.minimumParticleLife || 1.5,
maximumParticleLife: options.maximumParticleLife || 1.8,
minimumSpeed: options.minimumSpeed || 7.0,
maximumSpeed: options.maximumSpeed || 9.0,
imageSize: options.imageSize || new Cesium.Cartesian2(2, 2),
emissionRate: options.emissionRate || 200.0,
lifetime: options.lifetime || 6.0,
//循环是否开启
loop: true,
emitter: options.emitter || new Cesium.BoxEmitter(new Cesium.Cartesian3(10.0, 10.0, 10.0)),
// emitterModelMatrix: computeEmitterModelMatrix(),
// updateCallback: applyGravity,
sizeInMeters: true,
}));
this._viewer.scene.preUpdate.addEventListener(function (scene, time) {
flameParticleSystem.modelMatrix = computeModelMatrix(entity, time);
// Account for any changes to the emitter model matrix.
flameParticleSystem.emitterModelMatrix = computeEmitterModelMatrix();
});
// 计算矩阵
function computeModelMatrix(entity, time) {
return entity.computeModelMatrix(time, new Cesium.Matrix4());
}
//改变粒子系统的位置
function computeEmitterModelMatrix() {
hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr);
trs.translation = Cesium.Cartesian3.fromElements(options.tx, options.ty, options.tz, translation);
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, rotation);
return Cesium.Matrix4.fromTranslationRotationScale(trs, emitterModelMatrix);
}
return flameParticleSystem;
}
},
//添加雨滴粒子
setRainParticle: function (options) {
options = options || {}
if (this._viewer && options) {
this._viewer.scene.logarithmicDepthBuffer = true;
// rain
var rainParticleSize = this._viewer.scene.drawingBufferWidth / 80.0, rainRadius = 4000.0, //降雨范围
rainImageSize = new Cesium.Cartesian2(rainParticleSize, rainParticleSize * 3.0),
rainGravityScratch = new Cesium.Cartesian3(), $this = this;
var rainUpdate = function (particle, dt) {
rainGravityScratch = Cesium.Cartesian3.normalize(particle.position, rainGravityScratch);
rainGravityScratch = Cesium.Cartesian3.multiplyByScalar(rainGravityScratch, -40, rainGravityScratch);
particle.position = Cesium.Cartesian3.add(particle.position, rainGravityScratch, particle.position);
var distance = Cesium.Cartesian3.distance($this._viewer.scene.camera.position, particle.position);
if (distance > rainRadius) {
particle.endColor.alpha = 0.0;
} else {
particle.endColor.alpha = rainSystem.endColor.alpha / (distance / rainRadius + 0.1);
}
};
var rainSystem = new Cesium.ParticleSystem({
modelMatrix: new Cesium.Matrix4.fromTranslation(this._viewer.scene.camera.position),
speed: -1.0,
lifetime: 10.0,
scale: 0.8,
emitter: new Cesium.SphereEmitter(rainRadius),
startScale: 1.0,
endScale: 1.0,
image: 'examples/images/ParticleSystem/rain.png',
emissionRate: 3000.0,
startColor: new Cesium.Color(1, 1, 1, 0.8),
endColor: new Cesium.Color(1, 1, 1, 0.8),
imageSize: rainImageSize,
updateCallback: rainUpdate,
performance: false,
});
rainSystem.lodRangeScale = 10000;
return this._viewer.scene.primitives.add(rainSystem);
}
},
// 鼠标旋转
setFlyCircle: function (init) {
if (this._viewer) {
var camera = this._viewer.scene.camera,
flag = false, $this = this;
camera.flyCircleLoop = true
camera.speedRatio = 0.2
if (init) {
setTimeout(() => {
var center = Cesium.Cartesian3.fromDegrees(106.56185470893745, 29.538553141480676, 50.0);
camera.flyCircle(center);
}, 2000)
}
_handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
_handler.setInputAction(function (movement) {
if (camera) {
camera.stopFlyCircle();
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
_handler.setInputAction(function (movement) {
var cartesian = $this._viewer.scene.camera.pickEllipsoid(movement.position, $this._viewer.scene.globe.ellipsoid);
if (cartesian && cartesian.x) {
camera.flyCircle(cartesian);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
return _handler;
}
},
//拓展热力图
createSuperMapHeatMaps: function () {
if (h337 && document.querySelector('.heatmap')) {
var heatmapInstance = h337.create({
container: document.querySelector('.heatmap')
});
var points = [], max = 0, width = 840, height = 400, len = 200;
while (len--) {
var val = Math.floor(Math.random() * 100);
max = Math.max(max, val);
var point = {
x: Math.floor(Math.random() * width),
y: Math.floor(Math.random() * height),
value: val
};
points.push(point)
}
var data = {
max: max,
data: points
}
heatmapInstance.setData(data);
return heatmapInstance
}
},
// 旋转聚光灯
createRotateSpotLightGraphics: function (options) {
if (this._viewer && options && options.center) {
var ellipse = this.computeEllipseEdgePositions({
semiMinorAxis: options.semiMinorAxis || 500,
semiMajorAxis: options.semiMajorAxis || 500,
rotation: 0,
center: options.center,
granularity: Math.PI / 150.0//间隔
})
var positions = [], index = 0
for (let i = 0; i < ellipse.outerPositions.length; i += 3) {
let cartesian = new Cesium.Cartesian3(ellipse.outerPositions[i], ellipse.outerPositions[i + 1], ellipse.outerPositions[i + 2]);
positions.push(cartesian)
}
var spotLight = new Cesium.SpotLight(options.center, positions[0], {
color: options.color || new Cesium.Color(9, 15, 160, 0.8),
intesity: options.intesity || 5,
distance: options.distance || 500,
decay: options.decay || 2,
})
this._viewer.scene.addLightSource(spotLight)
// 修改每一帧事件
this._viewer.scene.preUpdate.addEventListener(function () {
if (index == 0) {
spotLight.targetPosition = positions[0], index += 1
} else if (index < positions.length - 1) {
spotLight.targetPosition = positions[index], index += 1
} else if (index == positions.length - 1) {
spotLight.targetPosition = positions[index], index = 0
}
})
}
},
}
/**
* 图形模块
* @param {*} viewer
*/
function Graphics(viewer) {
if (viewer) {
this._graphicsLayer = new Cesium.CustomDataSource('graphicsLayer')
viewer && viewer.dataSources.add(this._graphicsLayer)
}
}
Graphics.prototype = {
// 创建一个实体图形
createGraphics: function () {
return new Cesium.Entity()
},
//点
getPointGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.PointGraphics({
color: options.color || Cesium.Color.GREEN,
pixelSize: options.pixelSize || 5,
outlineColor: options.outlineColor || Cesium.Color.WHITE,
outlineWidth: options.outlineWidth || 1
});
}
},
//线
getLineGraphics: function (options) {
options = options || {}
if (options && options.positions) {
return new Cesium.PolylineGraphics({
show: true,
positions: options.positions,
material: options.material || Cesium.Color.YELLOW,
width: options.width || 1,
clampToGround: options.clampToGround || false,
});
}
},
// 面
getPolygonGraphics: function (options) {
options = options || {}
if (options && options.positions) {
return new Cesium.PolygonGraphics({
hierarchy: { positions: options.positions },
material: options.material || Cesium.Color.RED.withAlpha(0.2),
clampToGround: options.clampToGround || false
})
}
},
//标签
getLabelGraphics: function (options) {
options = options || {}
if (options && options.l_text) {
return new Cesium.LabelGraphics({ //文字标签
text: options.l_text,
font: options.l_font || '14px sans-serif',
fillColor: options.l_fillColor || Cesium.Color.GOLD,
style: options.l_style || Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: options.l_outlineWidth || 2,
showBackground: options.l_showBackground || false,
backgroundColor: options.l_backgroundColor || new Cesium.Color(0.165, 0.165, 0.165, 0.8),
verticalOrigin: options.l_verticalOrigin || Cesium.VerticalOrigin.BOTTOM,
pixelOffset: options.l_pixelOffset || new Cesium.Cartesian2(0, -30),
//heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND
});
}
},
//广告牌
getBillboardGraphics: function (options) {
options = options || {}
if (options && options.b_img) {
return new Cesium.BillboardGraphics({
image: options.b_img,
width: options.b_width || 35,
height: options.b_height || 35,
clampToGround: options.b_clampToGround || true,
scale: options.b_scale || 1,
// eyeOffset :new Cesium.Cartesian2(0, -20),
pixelOffset: options.b_pixelOffset || new Cesium.Cartesian2(0, -20),
scaleByDistance: options.b_scaleByDistance || undefined
// heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND
})
}
},
//路径
getPathGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.PathGraphics({
resolution: options.resolution || 1,
//设置航线样式,线条颜色,内发光粗细,航线宽度等
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: options.glowPower || 0.1,
color: options.color || Cesium.Color.YELLOW
}),
width: options.width || 30
})
}
},
//模型
getModelGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.ModelGraphics({
uri: options.m_url,
scale: options.m_scale || 28,
minimumPixelSize: options.m_minimumPixelSize || 30,
color: options.m_color || Cesium.Color.WHITE
})
}
},
//椭圆
getEllipseGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.EllipseGraphics({
semiMajorAxis: options.e_semiMinorAxis || 1000000.0,
semiMinorAxis: options.e_semiMinorAxis || 1000000.0,
metarial: options.e_metarial || Cesium.Color.RED.withAlpha(0.5),
outline: options.e_outline || true
})
}
},
//球
getEllipsoidGraphics: function (options) {
options = options || {}
if (options) {
var r = options.radii || 1000000.0 //默认100公里
return new Cesium.EllipsoidGraphics({
radii: new Cesium.Cartesian3(r, r, r), //单位 米
// innerRadii : options.innerRadii || new Cesium.Cartesian3(r /1.5, r /1.5, r /1.5),
maximumCone: options.maximumCone || Cesium.Math.PI_OVER_TWO,
stackPartitions: options.stackPartitions || 56,
slicePartitions: options.slicePartitions || 56,
outlineWidth: options.outlineWidth || 2.0,
outlineColor: options.outlineColor || Cesium.Color.YELLOW,
outline: options.outline || true,
fill: options.fill || true,
material: options.material || Cesium.Color.RED.withAlpha(0.1)
//heightReference:Cesium.HeightReference.NONE,
});
}
},
// 面
getPlaneGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.PlaneGraphics({
plane: options.plane || new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),
dimensions: options.dimensions || new Cesium.Cartesian2(170.0, 130.0),
material: options.material || Cesium.Color.BLUE
})
}
},
// 锥体
getCylinderGraphics: function (options) {
options = options || {}
if (options) {
return new Cesium.CylinderGraphics({
HeightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
length: options.length || 500 / 2,
topRadius: options.topRadius || 0,
bottomRadius: options.bottomRadius || 0,
material: options.material || new Cesium.Color(0, 1, 1, .4),
slices: options.slices || 128
})
}
},
//创建点信息
createPointsGraphics: function (options) {
if (options && options.positions) {
let positions = []
for (let i in options.positions) {
let position = options.positions[i]
let entity = this.createGraphics()
entity.name = options.name || ''
entity.oid = options.oid || 'point';
entity.position = position;
if (options.point) entity.point = this.getPointGraphics();
if (options.billboard) entity.billboard = this.getBillboardGraphics(options.billboard);
if (options.label) entity.label = this.getLabelGraphics(options.label);
positions.push(this._graphicsLayer.entities.add(entity))
}
return positions;
}
},
//创建线
createLineGraphics: function (options) {
if (options && options.positions) {
var entity = this.createGraphics();
entity.name = options.name || ''
entity.oid = options.oid || 'line';
entity.position = options.positions;
entity.polyline = this.getLineGraphics(options);
return this._graphicsLayer.entities.add(entity);
}
},
//创建面
createPolygonGraphics: function (options) {
options = options || {}
if (options) {
var entity = this.createGraphics();
entity.polygon = this.getPolygonGraphics(options)
entity.clampToS3M = options.clampToS3M || false
return this._graphicsLayer.entities.add(entity);
}
},
//创建模型
createModelGraphics: function (options) {
if (options && options.position) {
var entity = this.createGraphics();
entity.model = this.getModelGraphics(options)
entity.position = options.position
return this._graphicsLayer.entities.add(entity);
}
},
// 创建地面指示
craeteCorridorGraphics: function (options) {
if (options && options.positions) {
var entity = this.createGraphics()
entity.corridor = {
positions: options.positions,
height: options.height || 6.0,
width: options.width || 15.0,
material: options.material ||
new Cesium.WarnLinkMaterialProperty({ freely: 'cross', color: Cesium.Color.YELLOW, duration: 1000, count: 1.0, direction: '+' }),
}
return this._graphicsLayer.entities.add(entity)
}
},
//构建动态线
craeteDynamicPolyLineGraphics: function (options) {
if (options && options.positions) {
var entity = this.createGraphics()
entity.polyline = {
show: true,
positions: [],
material: options.material || Cesium.Color.CHARTREUSE,
width: options.width || 5,
clampToGround: options.clampToGround || false
}
entity.polyline.positions = new Cesium.CallbackProperty(function () {
return options.positions;
}, false);
return this._graphicsLayer.entities.add(entity);
}
},
//动态椎体
craeteDynamicCylinderGraphics: function (options) {
if (options && options.cylinder) {
var entity = options.entity, cylinder = options.cylinder, $this = this;
param.cylinder = this.getCylinderGraphics(cylinder)
param.position = new Cesium.CallbackProperty(function () {
var positions = entity.position.getValue($this._viewer.clock.currentTime);
var cartographic = $this._viewer.scene.globe.ellipsoid.cartesianToCartographic(positions);
var lat = Cesium.Math.toDegrees(cartographic.latitude)
, lng = Cesium.Math.toDegrees(cartographic.longitude)
, hei = parseFloat(cartographic.height / 4);
return Cesium.Cartesian3.fromDegrees(lng, lat, 0);
}, false);
param.cylinder.length = new Cesium.CallbackProperty(function () {
var positions = entity.position.getValue($this._viewer.clock.currentTime);
var cartographic = $this._viewer.scene.globe.ellipsoid.cartesianToCartographic(positions);
return cartographic.height * 2;
}, false);
return param;
}
},
// 创建渐变锥体
createFadeCylinderGraphics: function (options) {
options = options || {}
if (options && options.position) {
let entity = this.createGraphics()
entity.position = options.position
options.material = new Cesium.CircleFadeMaterialProperty({
color: options.color || Cesium.Color.fromCssColorString("#02ff00"),
duration: options.duration || 2000,
})
entity.cylinder = this.getCylinderGraphics(options)
return this._drawLayer.entities.add(entity)
}
},
// 创建旋转圆柱
craeteRotateCylinderGraphics: function (options) {
if (options && options.position) {
var cylinderEntity = this.createGraphics()
cylinderEntity.cylinder = {
HeightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
length: options.length || 500,
topRadius: options.topRadius || 500,
bottomRadius: options.bottomRadius || 500,
material: options.material || new Cesium.ImageMaterialProperty({
image: "data/images/file/cc2.jpg",
transparent: true,
repeat: {
x: 1,
y: -1
}
}),
slices: options.slices || 128
}
cylinderEntity.position = options.position
this.setGraphicsRotate({
entity: cylinderEntity,
position: this.transformCartesianToWGS84(options.position),
rotateAmount: 4
})
return this._graphicsLayer.entities.add(cylinderEntity)
}
},
//闪烁圆
craeteDynamicBlinkCircleGraphics: function (options) {
if (options && options.position) {
var entity = this.createGraphics(), alp = options.alp || 1, flog = options.flog || true;
entity.position = options.position
entity.ellipse = {
semiMinorAxis: options.semiMinorAxis || 2000.0,
semiMajorAxis: options.semiMajorAxis || 2000.0,
height: options.height || 10,
material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(function () {
if (flog) {
alp = alp - 0.05;
if (alp <= 0) {
flog = false; // hide
}
} else {
alp = alp + 0.05;
if (alp >= 1) {
flog = true; // show
}
}
return Cesium.Color.RED.withAlpha(alp);
}, false))
}
return this._graphicsLayer.entities.add(entity)
}
},
//动态旋转圆
craeteDynamicCricleGraphics: function (options) {
if (options && options.center) {
var entity = this.createGraphics(), $this = this,
_center = options.center, _radius = options.radius || 800,
_rotateAmount = options.rotateAmount || 0.05, _stRotation = 0,
_height = options.height || 1, heading = 0, pitch = 0, roll = 0,
_scale = options.scale || null, _scale2 = options.scale2 || null,
_material = options.material || new Cesium.ImageMaterialProperty({
image: options.imge || 'data/images/Textures/circle_bg.png',
transparent: true
});
entity.position = new Cesium.CallbackProperty(function () {
return $this.transformWGS84ToCartesian(_center)
}, false)
entity.orientation = new Cesium.CallbackProperty(function () {
return Cesium.Transforms.headingPitchRollQuaternion(
$this.transformWGS84ToCartesian(_center),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(heading),
Cesium.Math.toRadians(pitch),
Cesium.Math.toRadians(roll)
)
)
}, false)
let bg_scale = _radius, flag = false;
var updateScalerAxis = () => {
if (_radius >= _scale || _radius <= bg_scale) {
flag = !flag
}
flag ? _radius += 2 : _radius -= 2;
}
var updateScalerAxis2 = () => {
_scale2 >= _radius ? _radius += 2 : _radius = bg_scale;
}
entity.ellipse = {
material: _material,
height: _height,
semiMajorAxis: new Cesium.CallbackProperty(function () {
return _radius
}, false),
semiMinorAxis: new Cesium.CallbackProperty(function () {
return _radius
}, false),
stRotation: new Cesium.CallbackProperty(function () {
if (_rotateAmount > 0) {
_stRotation += _rotateAmount
if (_stRotation >= 360) {
_stRotation = 0
}
}
if (_scale) updateScalerAxis()
if (_scale2) updateScalerAxis2()
return _stRotation
}, false)
}
return this._graphicsLayer.entities.add(entity)
}
},
//动态渐变墙
craeteDynamicShadeWallGraphics: function (options) {
if (options && options.positions) {
var alp = options.alp || 1, num = options.num || 20,
color = options.color || Cesium.Color.RED, speed = options.speed || 0.003;
var wallEntity = this.createGraphics()
wallEntity.wall = {
positions: options.positions,
material: new Cesium.ImageMaterialProperty({
image: "data/images/Textures/fence.png",
transparent: true,
color: new Cesium.CallbackProperty(function () {
if ((num % 2) === 0) {
alp -= speed;
} else {
alp += speed;
}
if (alp <= 0.1) {
num++;
} else if (alp >= 1) {
num++;
}
return color.withAlpha(alp)
}, false)
})
}
return this._graphicsLayer.entities.add(wallEntity)
}
},
// 默认自定义标牌气泡框
createCustomDefBillboardGraphics: function (options) {
if (options && options.position) {
var $this = this, img = document.createElement('img');
img.src = options.img || 'data/images/file/div1.png'
// 绘制canvas
function drawCompanyTip(options) {
if (!options.image) return
var canvas = document.createElement("canvas");
canvas.width = options.width || 150;
canvas.height = options.height || 80;
var context = canvas.getContext('2d');
context.drawImage(options.image, 0, 0);
var dom = options.text;
context.font = '15px bold 宋体';
context.fillStyle = "#f4fff0";
context.fillText(dom, 55, 36);
return canvas;
}
img.onload = function () {
options.image = img;
var entity = $this._graphicsLayer.entities.add({
position: options.position,
billboard: {
image: drawCompanyTip(options),
scaleByDistance: new Cesium.NearFarScalar(1.5e2, 0.7, 1.5e7, 0.5),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: options.b_pixelOffset || new Cesium.Cartesian2(80, -35),
width: 140,
height: 100,
scale: options.b_scale || 1.5,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
imageSubRegion: { x: 0, y: 0, width: 200, height: 150 }
},
})
if (typeof options.callback === 'function') {
options.callback(entity)
}
};
}
},
// 旋转面
craeteRotatePlaneGraphics: function (options) {
if (options && options.center && options.positions) {
var entity = this.createGraphics(), index = 0, _center = options.center,
_plane, positions = options.positions, _position = positions[0];
entity.position = new Cesium.CallbackProperty(function () {
if (index == 0) {
_position = positions[0], index += 1
} else if (index < positions.length - 1) {
_position = positions[index], index += 1
} else if (index == positions.length - 1) {
_position = positions[index], index = 0
}
return _position;
}, false)
entity.plane = {
// plane: new Cesium.CallbackProperty(function () {
// var normaB = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_center, _position, new Cesium.Cartesian3()), new Cesium.Cartesian3())
// _plane = new Cesium.Plane(Cesium.Cartesian3.normalize(Cesium.Cartesian3.add(normaB, _center, new Cesium.Cartesian3()), new Cesium.Cartesian3()), 0.0)
// _plane = Cesium.Plane.fromPointNormal(coefficients, result)
// return _plane;
// }, false),
plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),
dimensions: options.dimensions || new Cesium.Cartesian2(200.0, 150.0),
material: new Cesium.ImageMaterialProperty({
image: options.image
})
}
return this._graphicsLayer.entities.add(entity)
}
},
// 视频投放
createVideoPlaneGraphics: function (options) {
if (options && options.position) {
var entity = this.createGraphics()
entity.position = options.position
entity.plane = {
plane: new Cesium.Plane(options.normal || Cesium.Cartesian3.UNIT_Y, 0.0),
dimensions: options.dimensions || new Cesium.Cartesian2(200.0, 150.0),
material: new Cesium.ImageMaterialProperty({
image: options.videoElement
})
}
return this._graphicsLayer.entities.add(entity)
}
},
//gif 图片投影
createGifBillboardGraphics: function (options) {
if (SuperGif && options && options.position) {
var gif = [], url = options.url, i = 0, speed = 6;
// 遍历gif的每一帧
function parseGifImages(url, imageArr) {
var img = document.createElement('img');
img.src = url
img.setAttribute('rel:animated_src', url) // gif库需要img标签配置下面两个属性
img.setAttribute('rel:auto_play', '0')
document.body.appendChild(img)
// 新建gif实例
var rub = new SuperGif({ gif: img });
return new Promise((resolve) => {
rub.load(() => {
for (let i = 1; i <= rub.get_length(); i++) {
rub.move_to(i); // 遍历gif实例的每一帧
imageArr.push(rub.get_canvas().toDataURL())
}
resolve(imageArr)
// document.body.removeChild(img)
});
})
}
parseGifImages(url, gif)
return this._graphicsLayer.entities.add({
position: options.position,
billboard: {
verticalOrigin: Cesium.VerticalOrigin.BASELINE,
image: new Cesium.CallbackProperty(function () {
if (gif.length) { // 解析每一帧
if (i < speed * (gif.length - 1)) {
i++
} else {
i = 0
}
return gif[Math.floor(i / speed)]
} else {
return url//因为loadGif是异步的,在解析完成之前先使用原图
}
}, false),
scale: 0.2
}
})
}
},
//图形旋转
setGraphicsRotate: function (options) {
if (options && options.entity && options.rotateAmount) {
var entity = options.entity, rotateAmount = options.rotateAmount, _position = options.position, $this = this;
_position.heading = 0, _position.pitch = 0, _position.roll = 0;
entity.position = new Cesium.CallbackProperty(function () {
return $this.transformWGS84ToCartesian(_position)
}, false)
entity.orientation = new Cesium.CallbackProperty(function () {
if (rotateAmount > 0) {
_position.heading += rotateAmount
if (_position.heading === 360) {
_position.heading = 0
}
}
return Cesium.Transforms.headingPitchRollQuaternion(
$this.transformWGS84ToCartesian(_position),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(_position.heading),
Cesium.Math.toRadians(_position.pitch),
Cesium.Math.toRadians(_position.roll)
)
)
}, false)
}
},
// 图形浮动
setGraphicsFloat: function (options) {
if (options && options.entity && options.maxHeiht) {
var entity = options.entity, minHeiht = options.minHeiht || 5,
maxHeiht = options.maxHeiht || 100, cartesians = options.cartesians, speed = options.speed || 0.06,
$this = this, bg_minHeiht = minHeiht, flag = false;
if (cartesians.length) {
entity.positions = new Cesium.CallbackProperty(function () {
var positions = $this.transformCartesianArrayToWGS84Array(cartesians)
for (var i in positions) {
var position = positions[i]
if (minHeiht >= maxHeiht || minHeiht <= bg_minHeiht) {
flag = !flag
}
flag ? minHeiht += speed : minHeiht -= speed;
position.alt = minHeiht;
}
return $this.transformWGS84ArrayToCartesianArray(positions);
}, false);
} else {
entity.position = new Cesium.CallbackProperty(function () {
var position = $this.transformCartesianToWGS84(cartesians)
if (minHeiht >= maxHeiht || minHeiht <= bg_minHeiht) {
flag = !flag
}
flag ? minHeiht += speed : minHeiht -= speed;
position.alt = minHeiht;
return $this.transformWGS84ToCartesian(position);
}, false);
}
}
},
//canvas 贴图
createCanvasGraphics: function (options) {
if (options && options.positions) {
function drawCanvasImage() {
var canvas = document.createElement('canvas')
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = options.img || "../../images/ysCesium/logo.png";
ctx.clearRect(0, 0, options.cwidth, options.cheight);
if (i <= cwidth) {
ctx.drawImage(img, i, 0);
} else
i = 0;
i += 3;
curCanvas = curCanvas === 'c' ? 'd' : 'c';
return canvas;
}
this._graphicsLayer.entities.add({
rectangle: {
coordinates: options.positions,
material: new Cesium.ImageMaterialProperty({
image: new Cesium.CallbackProperty(drawCanvasImage, false),
transparent: true
})
}
});
if (typeof options.callback === 'function') {
options.callback()
}
}
}
}
/**
* 着色器模块
* @param {*} viewer
*/
function Shaders(viewer) { }
Shaders.prototype = {
// 流动线
_getFlowLineShader: function (options) {
if (options && options.get) {
return "uniform vec4 color;\n\
uniform float duration;\n\
\n\
czm_material czm_getMaterial(czm_materialInput materialInput){\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
float t =fract(czm_frameNumber / duration);\n\
t *= 1.03;\n\
float alpha = smoothstep(t- 0.03, t, st.s) * step(-t, -st.s);\n\
alpha += 0.1;\n\
vec4 fragColor;\n\
fragColor.rgb = (color.rgb) / 0.5;\n\
fragColor = czm_gammaCorrect(fragColor);\n\
material.diffuse = fragColor.rgb;\n\
material.alpha = alpha;\n\
material.emission = fragColor.rgb;\n\
return material;\n\
}\n\
";
}
},
// 动态线
_getDynamicLineShader: function (options) {
if (options && options.get) {
return "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
\n\
if(texture2D(image, vec2(0.0, 0.0)).a == 1.0){\n\
discard;\n\
}else{\n\
material.alpha = texture2D(image, vec2(1.0 - fract(time - st.s), st.t)).a * color.a;\n\
}\n\
\n\
material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);\n\
\n\
return material;\n\
}\n\
";
}
},
// 动态泛光线
_getDynamicLightLineShader: function (options) {
if (options && options.get) {
return "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
\n\
vec4 colorImage = texture2D(image, vec2(fract(1.0 *st.s - time), fract(st.t)));\n\
\n\
vec4 fragColor;\n\
fragColor.rgb = (colorImage.rgb+color.rgb) / 1.0;\n\
fragColor = czm_gammaCorrect(fragColor);\n\
material.diffuse = colorImage.rgb;\n\
material.alpha = colorImage.a;\n\
material.emission = fragColor.rgb;\n\
\n\
return material;\n\
}\n\
";
// material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);\n\
// material.alpha = texture2D(image, vec2(1.0 - fract(time - st.s), st.t)).a * color.a;\n\
}
},
/**
* 带方向的墙体
* @param {*} options
*/
_getDirectionWallShader: function (options) {
if (options && options.get) {
var materail =
"czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
\n\ ";
if (options.freely == "vertical") { //(由下到上)
materail += "vec4 colorImage = texture2D(image, vec2(fract(float(" + options.count + ")*st.t " + options.direction + " time), fract(st.s)));\n\ ";
} else { //(逆时针)
materail += "vec4 colorImage = texture2D(image, vec2(fract(float(" + options.count + ")*st.s " + options.direction + " time), fract(st.t)));\n\ ";
}
//泛光
materail += "vec4 fragColor;\n\
fragColor.rgb = (colorImage.rgb+color.rgb) / 1.0;\n\
fragColor = czm_gammaCorrect(fragColor);\n\ "
materail += " material.diffuse = colorImage.rgb;\n\
material.alpha = colorImage.a;\n\
material.emission = fragColor.rgb;\n\
\n\
return material;\n\
}\n\
";
return materail
}
},
_getCircleFadeShader: function (options) {
if (options && options.get) {
return `czm_material czm_getMaterial(czm_materialInput materialInput)\n
{\n
czm_material material = czm_getDefaultMaterial(materialInput);\n
material.diffuse = 1.5 * color.rgb;\n
vec2 st = materialInput.st;\n
float dis = distance(st, vec2(0.5, 0.5));\n
float per = fract(time);\n
if(dis > per * 0.5){\n
//material.alpha = 0.0;\n
discard;\n
}else {\n
material.alpha = color.a * dis / per / 2.0;\n
}\n
return material;\n
}`
}
},
// 波动圆
_getDynamicCircleShader: function (options) {
if (options && options.get) {
return "uniform vec4 color;\n\
uniform float duration;\n\
uniform float count;\n\
uniform float gradient;\n\
\n\
czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
material.diffuse = 1.5 * color.rgb;\n\
vec2 st = materialInput.st;\n\
vec3 str = materialInput.str;\n\
float dis = distance(st, vec2(0.5, 0.5));\n\
float per = fract(czm_frameNumber / duration);\n\
if(abs(str.z) > 0.001){\n\
discard;\n\
}\n\
if(dis > 0.5){\n\
discard;\n\
} else {\n\
float perDis = 0.5 / count;\n\
float disNum;\n\
float bl = .0;\n\
for (int i = 0; i <= 10; i++) {\n\
if (float(i) <= count) {\n\
disNum = perDis * float(i) - dis + per / count;\n\
if (disNum > 0.0) {\n\
if (disNum < perDis) {\n\
bl = 1.0 - disNum / perDis;\n\
} else if (disNum - perDis < perDis) {\n\
bl = 1.0 - abs(1.0 - disNum / perDis);\n\
}\n\
material.alpha = pow(bl, gradient);\n\
}\n\
}\n\
}\n\
}\n\
return material;\n\
}\n\
";
}
},
// 雷达扫描
_getRadarScanShader: function (options) {
if (options && options.get) {
return "uniform sampler2D colorTexture;\n\
uniform sampler2D depthTexture;\n\
varying vec2 v_textureCoordinates;\n\
uniform vec4 u_scanCenterEC;\n\
uniform vec3 u_scanPlaneNormalEC;\n\
uniform vec3 u_scanLineNormalEC;\n\
uniform float u_radius;\n\
uniform vec4 u_scanColor;\n\
\n\
vec4 toEye(in vec2 uv, in float depth){\n\
vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n\
vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\n\
posInCamera =posInCamera / posInCamera.w;\n\
return posInCamera;\n\
}\n\
\n\
bool isPointOnLineRight(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt){\n\
vec3 v01 = testPt - ptOnLine;\n\
normalize(v01);\n\
vec3 temp = cross(v01, lineNormal);\n\
float d = dot(temp, u_scanPlaneNormalEC);\n\
return d > 0.5;\n\
}\n\
\n\
vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point){\n\
vec3 v01 = point -planeOrigin;\n\
float d = dot(planeNormal, v01) ;\n\
return (point - planeNormal * d);\n\
}\n\
\n\
float distancePointToLine(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt){\n\
vec3 tempPt = pointProjectOnPlane(lineNormal, ptOnLine, testPt);\n\
return length(tempPt - ptOnLine);\n\
}\n\
\n\
float getDepth(in vec4 depth){\n\
float z_window = czm_unpackDepth(depth);\n\
z_window = czm_reverseLogDepth(z_window);\n\
float n_range = czm_depthRange.near;\n\
float f_range = czm_depthRange.far;\n\
return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n\
}\n\
\n\
void main(){\n\
gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n\
float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));\n\
vec4 viewPos = toEye(v_textureCoordinates, depth);\n\
vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n\
float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n\
float twou_radius = u_radius * 2.0;\n\
if(dis < u_radius){\n\
float f0 = 1.0 -abs(u_radius - dis) / u_radius;\n\
f0 = pow(f0, 64.0);\n\
vec3 lineEndPt = vec3(u_scanCenterEC.xyz) + u_scanLineNormalEC * u_radius;\n\
float f = 0.0;\n\
if(isPointOnLineRight(u_scanCenterEC.xyz, u_scanLineNormalEC.xyz, prjOnPlane.xyz)){\n\
float dis1= length(prjOnPlane.xyz - lineEndPt);\n\
f = abs(twou_radius -dis1) / twou_radius;\n\
f = pow(f, float("+ options.width + "));\n\
}\n\
if(float("+ options.border + ") > 0.0){\n\
gl_FragColor = mix(gl_FragColor, u_scanColor, f + f0);\n\
} else {\n\
gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n\
}\n\
}\n\
}\n\
";
}
},
// 圆形扫描
_getCircleScanShader: function (options) {
if (options && options.get) {
return "uniform sampler2D colorTexture;\n\
uniform sampler2D depthTexture;\n\
varying vec2 v_textureCoordinates;\n\
uniform vec4 u_scanCenterEC;\n\
uniform vec3 u_scanPlaneNormalEC;\n\
uniform float u_radius;\n\
uniform vec4 u_scanColor;\n\
\n\
vec4 toEye(in vec2 uv, in float depth){\n\
vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n\
vec4 posInCamera = czm_inverseProjection * vec4(xy, depth, 1.0);\n\
posInCamera =posInCamera / posInCamera.w;\n\
return posInCamera;\n\
}\n\
\n\
vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point){\n\
vec3 v01 = point - planeOrigin;\n\
float d = dot(planeNormal, v01) ;\n\
return (point - planeNormal * d);\n\
}\n\
\n\
float getDepth(in vec4 depth){\n\
float z_window = czm_unpackDepth(depth);\n\
z_window = czm_reverseLogDepth(z_window);\n\
float n_range = czm_depthRange.near;\n\
float f_range = czm_depthRange.far;\n\
return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n\
}\n\
\n\
void main(){\n\
gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n\
float depth = getDepth(texture2D(depthTexture, v_textureCoordinates));\n\
vec4 viewPos = toEye(v_textureCoordinates, depth);\n\
vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n\
float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n\
if(dis < u_radius){\n\
float f = 1.0 - abs(u_radius - dis) / u_radius;\n\
f = pow(f, float("+ options.border + "));\n\
gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n\
}\n\
}\n\
";
}
}
}
/**
* 后期效果模块
* @param {*} viewer
*/
function PassEffect() { }
PassEffect.prototype = {
// 圆形扩散效果 自定义
setCircleScanEffect: function (options) {
if (options && options.position) {
var id = options.id || 'CircleScan' + parseInt(Math.random() * 1000), cartesian = options.position
, radius = options.radius, color = options.color || Cesium.Color.RED
, duration = options.duration || 1500, $this = this
, circleMode = options.circleMode || 'CircleScan', border = options.border || 4.0;
var cartesian3Center = cartesian;
var cartesian4Center = new Cesium.Cartesian4(
cartesian3Center.x,
cartesian3Center.y,
cartesian3Center.z,
1
)
var position = this.transformCartesianToWGS84(cartesian)
var cartesian3Center1 = this.transformWGS84ToCartesian(
{
lng: position.lng,
lat: position.lat,
alt: position.alt + 500
}
)
var cartesian4Center1 = new Cesium.Cartesian4(
cartesian3Center1.x,
cartesian3Center1.y,
cartesian3Center1.z,
1
)
var _time = new Date().getTime()
var _delegate = new Cesium.PostProcessStage({
name: id,
fragmentShader: this._getCircleScanShader({ get: true, border: border }),
uniforms: {
u_scanCenterEC: function () {
return Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center,
new Cesium.Cartesian4()
)
},
u_scanPlaneNormalEC: function () {
var temp = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center,
new Cesium.Cartesian4()
)
var temp1 = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center1,
new Cesium.Cartesian4()
)
var _scratchCartesian3Normal = new Cesium.Cartesian3()
_scratchCartesian3Normal.x = temp1.x - temp.x
_scratchCartesian3Normal.y = temp1.y - temp.y
_scratchCartesian3Normal.z = temp1.z - temp.z
Cesium.Cartesian3.normalize(
_scratchCartesian3Normal,
_scratchCartesian3Normal
)
return _scratchCartesian3Normal
},
u_radius: function () {
if (circleMode == 'CircleScan') {
return (
(radius * ((new Date().getTime() - _time) % duration)) /
duration
)
} else {
return radius
}
},
u_scanColor: color
}
})
this._viewer.scene.postProcessStages.add(_delegate)
return _delegate;
}
},
// 雷达扫描 自定义
setRadarScanEffect: function (options) {
if (options && options.position) {
var id = options.id || 'radarScan' + parseInt(Math.random() * 1000), cartesian = options.position
, radius = options.radius, color = options.color || Cesium.Color.RED
, duration = options.duration || 1500, $this = this, border = options.border || 1
, width = options.width || 3.0;
var cartesian3Center = cartesian
var cartesian4Center = new Cesium.Cartesian4(
cartesian3Center.x,
cartesian3Center.y,
cartesian3Center.z,
1
)
var position = this.transformCartesianToWGS84(cartesian)
var cartesian3Center1 = this.transformWGS84ToCartesian(
{
lng: position.lng,
lat: position.lat,
alt: position.alt + 500
}
)
var cartesian4Center1 = new Cesium.Cartesian4(
cartesian3Center1.x,
cartesian3Center1.y,
cartesian3Center1.z,
1
)
var cartesian3Center2 = this.transformWGS84ToCartesian(
{
lng: position.lng + 0.001,
lat: position.lat,
alt: position.alt
}
)
var cartesian4Center2 = new Cesium.Cartesian4(
cartesian3Center2.x,
cartesian3Center2.y,
cartesian3Center2.z,
1
)
var _time = new Date().getTime()
var _RotateQ = new Cesium.Quaternion()
var _RotateM = new Cesium.Matrix3()
var _scratchCartesian4Center = new Cesium.Cartesian4()
var _scratchCartesian4Center1 = new Cesium.Cartesian4()
var _scratchCartesian4Center2 = new Cesium.Cartesian4()
var _scratchCartesian3Normal = new Cesium.Cartesian3()
var _scratchCartesian3Normal1 = new Cesium.Cartesian3()
var _delegate = new Cesium.PostProcessStage({
name: id,
fragmentShader: this._getRadarScanShader({ border: border, width: width, get: true }),
uniforms: {
u_scanCenterEC: function () {
return Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center,
_scratchCartesian4Center
)
},
u_scanPlaneNormalEC: function () {
var temp = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center,
_scratchCartesian4Center
)
var temp1 = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center1,
_scratchCartesian4Center1
)
_scratchCartesian3Normal.x = temp1.x - temp.x
_scratchCartesian3Normal.y = temp1.y - temp.y
_scratchCartesian3Normal.z = temp1.z - temp.z
Cesium.Cartesian3.normalize(
_scratchCartesian3Normal,
_scratchCartesian3Normal
)
return _scratchCartesian3Normal
},
u_scanLineNormalEC: function () {
var temp = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center,
_scratchCartesian4Center
)
var temp1 = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center1,
_scratchCartesian4Center1
)
var temp2 = Cesium.Matrix4.multiplyByVector(
$this._viewer.camera._viewMatrix,
cartesian4Center2,
_scratchCartesian4Center2
)
_scratchCartesian3Normal.x = temp1.x - temp.x
_scratchCartesian3Normal.y = temp1.y - temp.y
_scratchCartesian3Normal.z = temp1.z - temp.z
Cesium.Cartesian3.normalize(
_scratchCartesian3Normal,
_scratchCartesian3Normal
)
_scratchCartesian3Normal1.x = temp2.x - temp.x
_scratchCartesian3Normal1.y = temp2.y - temp.y
_scratchCartesian3Normal1.z = temp2.z - temp.z
var tempTime =
((new Date().getTime() - _time) % duration) / duration
Cesium.Quaternion.fromAxisAngle(
_scratchCartesian3Normal,
tempTime * Cesium.Math.PI * 2,
_RotateQ
)
Cesium.Matrix3.fromQuaternion(_RotateQ, _RotateM)
Cesium.Matrix3.multiplyByVector(
_RotateM,
_scratchCartesian3Normal1,
_scratchCartesian3Normal1
)
Cesium.Cartesian3.normalize(
_scratchCartesian3Normal1,
_scratchCartesian3Normal1
)
return _scratchCartesian3Normal1
},
u_radius: radius,
u_scanColor: color
}
})
this._viewer.scene.postProcessStages.add(_delegate)
return _delegate;
}
}
}
/**
* 画笔模块
* @param {*} viewer
*/
function Draw(viewer) {
if (viewer) {
this._drawLayer = new Cesium.CustomDataSource('drawLayer')
viewer && viewer.dataSources.add(this._drawLayer)
}
}
Draw.prototype = {
/**
* 画点
* @param {*} options
*/
drawPointGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
image: 'data/images/file/location4.png',
width: 35,
height: 40,
clampToGround: true,
scale: 1,
pixelOffset: new Cesium.Cartesian2(0, -20),
}
if (this._viewer && options) {
var _poiEntity = new Cesium.Entity(), position, positions = [], poiObj, $this = this,
_handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// left
_handlers.setInputAction(function (movement) {
var cartesian = $this._viewer.scene.camera.pickEllipsoid(movement.position, $this._viewer.scene.globe.ellipsoid);
if (cartesian && cartesian.x) {
position = cartesian
positions.push(cartesian)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// right
_handlers.setInputAction(function (movement) {
_handlers.destroy()
_handlers = null
if (typeof options.callback === 'function') {
options.callback($this.transformCartesianArrayToWGS84Array(positions), poiObj);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
_poiEntity.billboard = options.style
_poiEntity.position = new Cesium.CallbackProperty(function () {
return position
}, false)
poiObj = this._drawLayer.entities.add(_poiEntity)
}
},
/**
* 画线 or 测距
* @param {*} options
*/
drawLineGraphics: function (options) {
options = options || {}
if (this._viewer && options) {
var positions = [], _lineEntity = new Cesium.Entity(), $this = this, lineObj,
_handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// left
_handlers.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.position);
if (cartesian && cartesian.x) {
if (positions.length == 0) {
positions.push(cartesian.clone());
}
if (options.measure) {
_addInfoPoint(cartesian)
}
// 绘制直线 两个点
if (positions.length == 2 && options.type === "straightLine") {
_handlers.destroy()
_handlers = null
if (typeof options.callback === 'function') {
options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
}
}
positions.push(cartesian);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
_handlers.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.endPosition);
if (positions.length >= 2) {
if (cartesian && cartesian.x) {
positions.pop();
positions.push(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// right
_handlers.setInputAction(function (movement) {
_handlers.destroy()
_handlers = null
var cartesian = $this.getCatesian3FromPX(movement.position);
if (options.measure) {
_addInfoPoint(cartesian)
}
if (typeof options.callback === 'function') {
options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
_lineEntity.polyline = {
width: options.width || 5
, material: options.material || Cesium.Color.BLUE.withAlpha(0.8)
, clampToGround: options.clampToGround || false
, clampToS3M: options.clampToS3M || false
}
_lineEntity.polyline.positions = new Cesium.CallbackProperty(function () {
return positions
}, false)
lineObj = this._drawLayer.entities.add(_lineEntity)
//添加坐标点
function _addInfoPoint(position) {
_labelEntity = new Cesium.Entity()
_labelEntity.position = position
_labelEntity.point = {
pixelSize: 10,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 5
}
_labelEntity.label = {
text: ($this.getPositionDistance($this.transformCartesianArrayToWGS84Array(positions)) / 1000).toFixed(4) + '公里',
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-20, -80) //left top
}
$this._drawLayer.entities.add(_labelEntity)
}
}
},
/**
* 画面 or 测面积
* @param {*} options
*/
drawPolygonGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
width: 3
, material: Cesium.Color.BLUE.withAlpha(0.8)
, clampToGround: true
}
if (this._viewer && options) {
var positions = [], polygon = new Cesium.PolygonHierarchy(), _polygonEntity = new Cesium.Entity(), $this = this, polyObj = null, _label = '',
_handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// left
_handler.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.position);
if (cartesian && cartesian.x) {
if (positions.length == 0) {
polygon.positions.push(cartesian.clone())
positions.push(cartesian.clone());
}
positions.push(cartesian.clone());
polygon.positions.push(cartesian.clone())
if (!polyObj) create()
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
_handler.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.endPosition);
if (positions.length >= 2) {
if (cartesian && cartesian.x) {
positions.pop()
positions.push(cartesian);
polygon.positions.pop()
polygon.positions.push(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// right
_handler.setInputAction(function (movement) {
_handler.destroy();
positions.push(positions[0]);
if (options.height) { //立体
_polygonEntity.polygon.extrudedHeight = options.height
_polygonEntity.polygon.material = Cesium.Color.BLUE.withAlpha(0.5)
}
if (options.measure) { // 量测
_addInfoPoint(positions[0])
}
if (typeof options.callback === 'function') {
options.callback($this.transformCartesianArrayToWGS84Array(positions), polyObj);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
function create() {
_polygonEntity.polyline = options.style
_polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
return positions
}, false)
_polygonEntity.polygon = {
hierarchy: new Cesium.CallbackProperty(function () {
return polygon
}, false),
material: Cesium.Color.WHITE.withAlpha(0.1)
, clampToGround: options.clampToGround || false
}
_polygonEntity.clampToS3M = true
polyObj = $this._drawLayer.entities.add(_polygonEntity)
}
function _addInfoPoint(position) {
var _labelEntity = new Cesium.Entity()
_labelEntity.position = position
_labelEntity.point = {
pixelSize: 10,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 5
}
_labelEntity.label = {
text: ($this.getPositionsArea($this.transformCartesianArrayToWGS84Array(positions)) / 1000000.0).toFixed(4) + '平方公里',
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-20, -50) //left top
}
$this._drawLayer.entities.add(_labelEntity)
}
}
},
/**
* 画矩形
* @param {*} options
*/
drawRectangleGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
width: 3
, material: Cesium.Color.BLUE.withAlpha(0.5)
, clampToGround: true
}
if (this._viewer && options) {
var _positions = [], _rectangleEntity = new Cesium.Entity(), _coordinates = new Cesium.Rectangle(), $this = this, rectangleObj,
_handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// left
_handler.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.position);
if (cartesian && cartesian.x) {
if (_positions.length == 0) {
_positions.push(cartesian.clone());
} else {
_handler.destroy();
_positions.push(cartesian.clone());
_coordinates = Cesium.Rectangle.fromCartesianArray([..._positions, cartesian], Cesium.Ellipsoid.WGS84)
if (typeof options.callback === 'function') {
options.callback($this.transformCartesianArrayToWGS84Array(_positions), rectangleObj);
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
_handler.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.endPosition);
if (cartesian) {
_coordinates = Cesium.Rectangle.fromCartesianArray([..._positions, cartesian], Cesium.Ellipsoid.WGS84)
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
_rectangleEntity.rectangle = options.style
if (options.height) _rectangleEntity.rectangle.extrudedHeight = options.height
_rectangleEntity.rectangle.coordinates = new Cesium.CallbackProperty(function () {
return _coordinates
}, false)
rectangleObj = this._drawLayer.entities.add(_rectangleEntity)
}
},
/**
* 画圆
* @param {*} options
*/
drawCircleGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
width: 3
, material: Cesium.Color.BLUE.withAlpha(0.5)
, clampToGround: true
}
if (this._viewer && options) {
var _center = undefined, _circleEntity = new Cesium.Entity(), $this = this, circleObj, _radius = 1
_handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// 计算半径
function computeRadius(src, dest) {
let srcCartographic = Cesium.Cartographic.fromCartesian(src)
let destCartographic = Cesium.Cartographic.fromCartesian(dest)
let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(srcCartographic, destCartographic)
let s = geodesic.surfaceDistance
_radius = Math.sqrt( //开平方
Math.pow(s, 2) +
Math.pow(destCartographic.height - srcCartographic.height, 2)
)
}
//
function drawGraphics() {
_circleEntity.ellipse = options.style
_circleEntity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(function () {
return _radius
}, false)
_circleEntity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(function () {
return _radius
}, false)
_circleEntity.position = new Cesium.CallbackProperty(function () {
return _center
}, false)
_circleEntity.point = {
pixelSize: 5,
outlineColor: Cesium.Color.RED,
outlineWidth: 3
}
if (options.height) _circleEntity.ellipse.extrudedHeight = options.height
circleObj = $this._drawLayer.entities.add(_circleEntity)
}
// left
_handler.setInputAction(function (movement) {
var cartesian = $this.getCatesian3FromPX(movement.position);
if (cartesian && cartesian.x) {
if (!_center) {
_center = cartesian
drawGraphics()
} else {
computeRadius(_center, cartesian)
_handler.destroy();
if (typeof options.callback === 'function') {
options.callback({ center: _center, radius: _radius }, circleObj);
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
_handler.setInputAction(function (movement) {
var cartesian = $this._viewer.scene.camera.pickEllipsoid(movement.endPosition, $this._viewer.scene.globe.ellipsoid);
if (_center && cartesian && cartesian.x) {
computeRadius(_center, cartesian)
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
},
/**
* 画三角量测
* @param {*} options
*/
drawTrianglesGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
width: 3
, material: Cesium.Color.BLUE.withAlpha(0.5)
}
if (this._viewer && options) {
var _trianglesEntity = new Cesium.Entity(), _tempLineEntity = new Cesium.Entity(), _tempLineEntity2 = new Cesium.Entity(),
_positions = [], _tempPoints = [], _tempPoints2 = [], $this = this,
_handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
// 高度
function _getHeading(startPosition, endPosition) {
if (!startPosition && !endPosition) return 0
if (Cesium.Cartesian3.equals(startPosition, endPosition)) return 0
let cartographic = Cesium.Cartographic.fromCartesian(startPosition);
let cartographic2 = Cesium.Cartographic.fromCartesian(endPosition);
return (cartographic2.height - cartographic.height).toFixed(2)
}
// 偏移点
function _computesHorizontalLine(positions) {
let cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
let cartographic2 = Cesium.Cartographic.fromCartesian(positions[1]);
return Cesium.Cartesian3.fromDegrees(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude),
cartographic2.height
)
}
// left
_handler.setInputAction(function (movement) {
var position = $this.getCatesian3FromPX(movement.position);
if (!position) return false
if (_positions.length == 0) {
_positions.push(position.clone())
_positions.push(position.clone())
_tempPoints.push(position.clone())
_tempPoints.push(position.clone())
} else {
_handler.destroy();
if (typeof options.callback === 'function') {
options.callback({ e: _trianglesEntity, e2: _tempLineEntity, e3: _tempLineEntity2 });
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
_handler.setInputAction(function (movement) {
var position = $this.getCatesian3FromPX(movement.endPosition);
if (position && _positions.length > 0) {
//直线
_positions.pop()
_positions.push(position.clone());
let horizontalPosition = _computesHorizontalLine(_positions)
//高度
_tempPoints.pop()
_tempPoints.push(horizontalPosition.clone())
//水平线
_tempPoints2.pop(), _tempPoints2.pop()
_tempPoints2.push(position.clone())
_tempPoints2.push(horizontalPosition.clone())
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
// create entity
//直线
_trianglesEntity.polyline = {
positions: new Cesium.CallbackProperty(function () {
return _positions
}, false),
...options.style
}
_trianglesEntity.position = new Cesium.CallbackProperty(function () {
return _positions[0]
}, false)
_trianglesEntity.point = {
pixelSize: 5,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 5
}
_trianglesEntity.label = {
text: new Cesium.CallbackProperty(function () {
return '直线:' + $this.getPositionDistance($this.transformCartesianArrayToWGS84Array(_positions)) + '米'
}, false),
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(50, -100) //left top
}
//高度
_tempLineEntity.polyline = {
positions: new Cesium.CallbackProperty(function () {
return _tempPoints
}, false),
...options.style
}
_tempLineEntity.position = new Cesium.CallbackProperty(function () {
return _tempPoints2[1]
}, false)
_tempLineEntity.point = {
pixelSize: 5,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 5
}
_tempLineEntity.label = {
text: new Cesium.CallbackProperty(function () {
return '高度:' + _getHeading(_tempPoints[0], _tempPoints[1]) + '米'
}, false),
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-20, 100) //left top
}
//水平
_tempLineEntity2.polyline = {
positions: new Cesium.CallbackProperty(function () {
return _tempPoints2
}, false),
...options.style
}
_tempLineEntity2.position = new Cesium.CallbackProperty(function () {
return _positions[1]
}, false)
_tempLineEntity2.point = {
pixelSize: 5,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 5
}
_tempLineEntity2.label = {
text: new Cesium.CallbackProperty(function () {
return '水平距离:' + $this.getPositionDistance($this.transformCartesianArrayToWGS84Array(_tempPoints2)) + '米'
}, false),
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-150, -20) //left top
}
this._drawLayer.entities.add(_tempLineEntity2)
this._drawLayer.entities.add(_tempLineEntity)
this._drawLayer.entities.add(_trianglesEntity)
}
},
/**
* 画围栏
* @param {*} options
*/
drawWallGraphics: function (options) {
options = options || {}
options.style = options.style ||
{
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.WHITE
}
if (this._viewer && options) {
var $this = this;
this.drawPolygonGraphics({
callback: function (polygon, polygonObj) {
var wallEntity = $this._drawLayer.entities.add({
wall: {
positions: $this.transformWGS84ArrayToCartesianArray(polygon),
...options.style
}
})
if (typeof options.callback === 'function') {
options.callback(polygon, wallEntity);
}
}
})
}
},
/**
* 绘制球体
* @param {*} options
*/
drawEllipsoidGraphics: function (options) {
options = options || {}
options.style = options.style || {}
if (this._viewer && options) {
var $this = this;
this.drawCircleGraphics({
callback: function (result, obj) {
var entity = $this.createGraphics()
entity.ellipsoid = $this.getEllipsoidGraphics({
radii: result.radius
})
entity.position = result.center
$this._drawLayer.entities.remove(obj)
var ellipsoidObj = $this._drawLayer.entities.add(entity)
if (typeof options.callback === 'function') {
options.callback({ center: result.center, radius: result.radius }, ellipsoidObj);
}
}
})
}
},
/**
* 绘制圆柱体 or 圆锥
* @param {*} options
*/
drawCylinderGraphics: function (options) {
options = options || {}
options.style = options.style || {}
if (this._viewer && options) {
var $this = this;
this.drawCircleGraphics({
callback: function (result, obj) {
var cylinderObj = $this._drawLayer.entities.add({
position: result.center,
cylinder: {
length: result.radius * 2 || options.length,
topRadius: options.topRadius || result.radius,
bottomRadius: options.bottomRadius || result.radius,
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.WHITE,
},
})
$this._drawLayer.entities.remove(obj)
if (typeof options.callback === 'function') {
options.callback({ center: result.center, radius: result.radius }, cylinderObj);
}
}
})
}
},
/**
* 绘制走廊
* @param {*} options
*/
drawCorridorGraphics: function (options) {
options = options || {}
options.style = options.style || {}
if (this._viewer && options) {
var $this = this;
$this.drawLineGraphics({
callback: function (line, lineObj) {
var entity = $this.createGraphics()
entity.corridor = {
positions: $this.transformWGS84ArrayToCartesianArray(line),
height: options.height || 1,
width: options.width || 100,
cornerType: Cesium.CornerType.BEVELED,
extrudedHeight: options.extrudedHeight || 1,
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true, // height required for outlines to display
outlineColor: Cesium.Color.WHITE
}
$this._drawLayer.entities.remove(lineObj)
var corridorObj = $this._drawLayer.entities.add(entity)
if (typeof options.callback === 'function') {
options.callback(line, corridorObj);
}
}
})
}
},
/**
* 绘制管道
* @param {*} options
*/
drawPolylineVolumeGraphics: function (options) {
options = options || {}
options.style = options.style || {}
if (this._viewer && options) {
var $this = this;
$this.drawLineGraphics({
callback: function (line, lineObj) {
var entity = $this.createGraphics()
entity.polylineVolume = {
positions: $this.transformWGS84ArrayToCartesianArray(line),
shape: $this.computeStar2d(7, 1500, 3000),
cornerType: Cesium.CornerType.MITERED,
material: Cesium.Color.BLUE,
}
$this._drawLayer.entities.remove(lineObj)
var polylineVolumeObj = $this._drawLayer.entities.add(entity)
if (typeof options.callback === 'function') {
options.callback(line, polylineVolumeObj);
}
}
})
}
}
}
/**
* 平面数学工具
* 二维模块
* @param {*} viewer
*/
function Math2d(viewer) { }
Math2d.prototype = {
/**
* 计算两个坐标之间的距离
* @param pnt1
* @param pnt2
* @returns {number}
* @constructor
*/
mathDistance2d: function (pnt1, pnt2) {
return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
},
/**
* 求圆周上等分点的坐标
* @param {*} r r为半径
* @param {*} ox ox,oy为圆心坐标
* @param {*} oy d
* @param {*} count count为等分个数
*/
getCirclePoints2d: function (r, ox, oy, count) {
var point = []; //结果
var radians = (Math.PI / 180) * Math.round(360 / count), //弧度
i = 0;
for (; i < count; i++) {
var x = ox + r * Math.sin(radians * i),
y = oy + r * Math.cos(radians * i);
point.unshift({ x: x, y: y }); //为保持数据顺时针
}
return point
},
/**
* 计算点集合的总距离
* @param points
* @returns {number}
*/
wholeDistance2d: function (points) {
let distance = 0
if (points && Array.isArray(points) && points.length > 0) {
points.forEach((item, index) => {
if (index < points.length - 1) {
distance += (this.mathDistance2d(item, points[index + 1]))
}
})
}
return distance
},
/**
* 获取基础长度
* @param points
* @returns {number}
*/
getBaseLength2d: function (points) {
return Math.pow(this.wholeDistance2d(points), 0.99)
},
/**
* 计算星型
* @param {*} arms
* @param {*} rOuter
* @param {*} rInner
*/
computeStar2d(arms, rOuter, rInner) {
var angle = Math.PI / arms;
var length = 2 * arms;
var positions = new Array(length);
for (var i = 0; i < length; i++) {
var r = i % 2 === 0 ? rOuter : rInner;
positions[i] = new Cesium.Cartesian2(
Math.cos(i * angle) * r,
Math.sin(i * angle) * r
);
}
return positions;
},
/**
* 求取两个坐标的中间值
* @param point1
* @param point2
* @returns {[*,*]}
* @constructor
*/
mid2d: function (point1, point2) {
return [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
},
/**
* 通过三个点确定一个圆的中心点
* @param point1
* @param point2
* @param point3
*/
getCircleCenterOfThreePoints2d: function (point1, point2, point3) {
let pntA = [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
let pntB = [pntA[0] - point1[1] + point2[1], pntA[1] + point1[0] - point2[0]]
let pntC = [(point1[0] + point3[0]) / 2, (point1[1] + point3[1]) / 2]
let pntD = [pntC[0] - point1[1] + point3[1], pntC[1] + point1[0] - point3[0]]
return this.getIntersectPoint2d(pntA, pntB, pntC, pntD)
},
/**
* 获取交集的点
* @param pntA
* @param pntB
* @param pntC
* @param pntD
* @returns {[*,*]}
*/
getIntersectPoint2d: function (pntA, pntB, pntC, pntD) {
if (pntA[1] === pntB[1]) {
let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
let x = f * (pntA[1] - pntC[1]) + pntC[0]
let y = pntA[1]
return [x, y]
}
if (pntC[1] === pntD[1]) {
let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
let x = e * (pntC[1] - pntA[1]) + pntA[0]
let y = pntC[1]
return [x, y]
}
let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
let y = (e * pntA[1] - pntA[0] - f * pntC[1] + pntC[0]) / (e - f)
let x = e * y - e * pntA[1] + pntA[0]
return [x, y]
},
/**
* 获取方位角(地平经度)
* @param startPoint
* @param endPoint
* @returns {*}
*/
getAzimuth2d: function (startPoint, endPoint) {
let azimuth
let angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / (this.mathDistance2d(startPoint, endPoint)))
if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {
azimuth = angle + Math.PI
} else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {
azimuth = Math.PI * 2 - angle
} else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {
azimuth = angle
} else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) {
azimuth = Math.PI - angle
}
return azimuth
},
/**
* 通过三个点获取方位角
* @param pntA
* @param pntB
* @param pntC
* @returns {number}
*/
getAngleOfThreePoints2d: function (pntA, pntB, pntC) {
let angle = this.getAzimuth2d(pntB, pntA) - this.getAzimuth2d(pntB, pntC)
return ((angle < 0) ? (angle + Math.PI * 2) : angle)
},
/**
* 判断是否是顺时针
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {boolean}
*/
isClockWise2d: function (pnt1, pnt2, pnt3) {
return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
},
/**
* 获取线上的点
* @param t
* @param startPnt
* @param endPnt
* @returns {[*,*]}
*/
getPointOnLine2d: function (t, startPnt, endPnt) {
let x = startPnt[0] + (t * (endPnt[0] - startPnt[0]))
let y = startPnt[1] + (t * (endPnt[1] - startPnt[1]))
return [x, y]
},
/**
* 获取立方值
* @param t
* @param startPnt
* @param cPnt1
* @param cPnt2
* @param endPnt
* @returns {[*,*]}
*/
getCubicValue2d: function (t, startPnt, cPnt1, cPnt2, endPnt) {
t = Math.max(Math.min(t, 1), 0)
let [tp, t2] = [(1 - t), (t * t)]
let t3 = t2 * t
let tp2 = tp * tp
let tp3 = tp2 * tp
let x = (tp3 * startPnt[0]) + (3 * tp2 * t * cPnt1[0]) + (3 * tp * t2 * cPnt2[0]) + (t3 * endPnt[0])
let y = (tp3 * startPnt[1]) + (3 * tp2 * t * cPnt1[1]) + (3 * tp * t2 * cPnt2[1]) + (t3 * endPnt[1])
return [x, y]
},
/**
* 根据起止点和旋转方向求取第三个点
* @param startPnt
* @param endPnt
* @param angle
* @param distance
* @param clockWise
* @returns {[*,*]}
*/
getThirdPoint2d: function (startPnt, endPnt, angle, distance, clockWise) {
let azimuth = this.getAzimuth2d(startPnt, endPnt)
let alpha = clockWise ? (azimuth + angle) : (azimuth - angle)
let dx = distance * Math.cos(alpha)
let dy = distance * Math.sin(alpha)
return ([endPnt[0] + dx, endPnt[1] + dy])
},
/**
* 函数继承
* @param childCtor
* @param parentCtor
*/
inherits2d: function (childCtor, parentCtor) {
/** @constructor */
function TempCtor() {
}
TempCtor.prototype = parentCtor.prototype
childCtor.superClass_ = parentCtor.prototype
childCtor.prototype = new TempCtor()
/** @override */
childCtor.prototype.constructor = childCtor
childCtor.base = function (me, methodName, varArgs) {
let args = Array.prototype.slice.call(arguments, 2)
return parentCtor.prototype[methodName].apply(me, args)
}
},
/**
* 插值弓形线段点
* @param center
* @param radius
* @param startAngle
* @param endAngle
* @returns {null}
*/
getArcPoints2d: function (center, radius, startAngle, endAngle) {
let [x, y, pnts, angleDiff] = [null, null, [], (endAngle - startAngle)]
angleDiff = ((angleDiff < 0) ? (angleDiff + (Math.PI * 2)) : angleDiff)
for (let i = 0; i <= 100; i++) {
let angle = startAngle + angleDiff * i / 100
x = center[0] + radius * Math.cos(angle)
y = center[1] + radius * Math.sin(angle)
pnts.push([x, y])
}
return pnts
},
/**
* getBisectorNormals
* @param t
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {[*,*]}
*/
getBisectorNormals2d: function (t, pnt1, pnt2, pnt3) {
let normal = this.getNormal2d(pnt1, pnt2, pnt3)
let [bisectorNormalRight, bisectorNormalLeft, dt, x, y] = [null, null, null, null, null]
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
let uX = normal[0] / dist
let uY = normal[1] / dist
let d1 = this.mathDistance2d(pnt1, pnt2)
let d2 = this.mathDistance2d(pnt2, pnt3)
if (dist > 0.0001) {
if (this.isClockWise(pnt1, pnt2, pnt3)) {
dt = t * d1
x = pnt2[0] - dt * uY
y = pnt2[1] + dt * uX
bisectorNormalRight = [x, y]
dt = t * d2
x = pnt2[0] + dt * uY
y = pnt2[1] - dt * uX
bisectorNormalLeft = [x, y]
} else {
dt = t * d1
x = pnt2[0] + dt * uY
y = pnt2[1] - dt * uX
bisectorNormalRight = [x, y]
dt = t * d2
x = pnt2[0] - dt * uY
y = pnt2[1] + dt * uX
bisectorNormalLeft = [x, y]
}
} else {
x = pnt2[0] + t * (pnt1[0] - pnt2[0])
y = pnt2[1] + t * (pnt1[1] - pnt2[1])
bisectorNormalRight = [x, y]
x = pnt2[0] + t * (pnt3[0] - pnt2[0])
y = pnt2[1] + t * (pnt3[1] - pnt2[1])
bisectorNormalLeft = [x, y]
}
return [bisectorNormalRight, bisectorNormalLeft]
},
/**
* 获取默认三点的内切圆
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {[*,*]}
*/
getNormal2d: function (pnt1, pnt2, pnt3) {
let dX1 = pnt1[0] - pnt2[0]
let dY1 = pnt1[1] - pnt2[1]
let d1 = Math.sqrt(dX1 * dX1 + dY1 * dY1)
dX1 /= d1
dY1 /= d1
let dX2 = pnt3[0] - pnt2[0]
let dY2 = pnt3[1] - pnt2[1]
let d2 = Math.sqrt(dX2 * dX2 + dY2 * dY2)
dX2 /= d2
dY2 /= d2
let uX = dX1 + dX2
let uY = dY1 + dY2
return [uX, uY]
},
/**
* 获取左边控制点
* @param controlPoints
* @returns {[*,*]}
*/
getLeftMostControlPoint2d: function (controlPoints, t) {
let [pnt1, pnt2, pnt3, controlX, controlY] = [controlPoints[0], controlPoints[1], controlPoints[2], null, null]
let pnts = this.getBisectorNormals2d(0, pnt1, pnt2, pnt3)
let normalRight = pnts[0]
let normal = this.getNormal2d(pnt1, pnt2, pnt3)
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
if (dist > 0.0001) {
let mid = this.mid2d(pnt1, pnt2)
let pX = pnt1[0] - mid[0]
let pY = pnt1[1] - mid[1]
let d1 = this.mathDistance2d(pnt1, pnt2)
let n = 2.0 / d1
let nX = -n * pY
let nY = n * pX
let a11 = nX * nX - nY * nY
let a12 = 2 * nX * nY
let a22 = nY * nY - nX * nX
let dX = normalRight[0] - mid[0]
let dY = normalRight[1] - mid[1]
controlX = mid[0] + a11 * dX + a12 * dY
controlY = mid[1] + a12 * dX + a22 * dY
} else {
controlX = pnt1[0] + t * (pnt2[0] - pnt1[0])
controlY = pnt1[1] + t * (pnt2[1] - pnt1[1])
}
return [controlX, controlY]
},
/**
* 获取右边控制点
* @param controlPoints
* @param t
* @returns {[*,*]}
*/
getRightMostControlPoint2d: function (controlPoints, t) {
let count = controlPoints.length
let pnt1 = controlPoints[count - 3]
let pnt2 = controlPoints[count - 2]
let pnt3 = controlPoints[count - 1]
let pnts = this.getBisectorNormals2d(0, pnt1, pnt2, pnt3)
let normalLeft = pnts[1]
let normal = this.getNormal2d(pnt1, pnt2, pnt3)
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
let [controlX, controlY] = [null, null]
if (dist > 0.0001) {
let mid = this.mid2d(pnt2, pnt3)
let pX = pnt3[0] - mid[0]
let pY = pnt3[1] - mid[1]
let d1 = this.mathDistance2d(pnt2, pnt3)
let n = 2.0 / d1
let nX = -n * pY
let nY = n * pX
let a11 = nX * nX - nY * nY
let a12 = 2 * nX * nY
let a22 = nY * nY - nX * nX
let dX = normalLeft[0] - mid[0]
let dY = normalLeft[1] - mid[1]
controlX = mid[0] + a11 * dX + a12 * dY
controlY = mid[1] + a12 * dX + a22 * dY
} else {
controlX = pnt3[0] + t * (pnt2[0] - pnt3[0])
controlY = pnt3[1] + t * (pnt2[1] - pnt3[1])
}
return [controlX, controlY]
},
/**
* 插值曲线点
* @param t
* @param controlPoints
* @returns {null}
*/
getCurvePoints2d: function (t, controlPoints) {
let leftControl = this.getLeftMostControlPoint2d(controlPoints, t)
let [pnt1, pnt2, pnt3, normals, points] = [null, null, null, [leftControl], []]
for (let i = 0; i < controlPoints.length - 2; i++) {
[pnt1, pnt2, pnt3] = [controlPoints[i], controlPoints[i + 1], controlPoints[i + 2]]
let normalPoints = this.getBisectorNormals2d(t, pnt1, pnt2, pnt3)
normals = normals.concat(normalPoints)
}
let rightControl = this.getRightMostControlPoint2d(controlPoints, t)
if (rightControl) {
normals.push(rightControl)
}
for (let i = 0; i < controlPoints.length - 1; i++) {
pnt1 = controlPoints[i]
pnt2 = controlPoints[i + 1]
points.push(pnt1)
for (let t = 0; t < 100; t++) {
let pnt = this.getCubicValue2d(t / 100, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
points.push(pnt)
}
points.push(pnt2)
}
return points
},
/**
* 贝塞尔曲线
* @param points
* @returns {*}
*/
getBezierPoints2d: function (points) {
if (points.length <= 2) {
return points
} else {
let bezierPoints = []
let n = points.length - 1
for (let t = 0; t <= 1; t += 0.01) {
let [x, y] = [0, 0]
for (let index = 0; index <= n; index++) {
let factor = this.getBinomialFactor2d(n, index)
let a = Math.pow(t, index)
let b = Math.pow((1 - t), (n - index))
x += factor * a * b * points[index][0]
y += factor * a * b * points[index][1]
}
bezierPoints.push([x, y])
}
bezierPoints.push(points[n])
return bezierPoints
}
},
/**
* 获取阶乘数据
* @param n
* @returns {number}
*/
getFactorial2d: function (n) {
let result = 1
switch (n) {
case (n <= 1):
result = 1
break
case (n === 2):
result = 2
break
case (n === 3):
result = 6
break
case (n === 24):
result = 24
break
case (n === 5):
result = 120
break
default:
for (let i = 1; i <= n; i++) {
result *= i
}
break
}
return result
},
/**
* 获取二项分布
* @param n
* @param index
* @returns {number}
*/
getBinomialFactor2d: function (n, index) {
return (this.getFactorial2d(n) / (this.getFactorial2d(index) * this.getFactorial2d(n - index)))
},
/**
* 插值线性点
* @param points
* @returns {*}
*/
getQBSplinePoints2d: function (points) {
if (points.length <= 2) {
return points
} else {
let [n, bSplinePoints] = [2, []]
let m = points.length - n - 1
bSplinePoints.push(points[0])
for (let i = 0; i <= m; i++) {
for (let t = 0; t <= 1; t += 0.05) {
let [x, y] = [0, 0]
for (let k = 0; k <= n; k++) {
let factor = this.getQuadricBSplineFactor2d(k, t)
x += factor * points[i + k][0]
y += factor * points[i + k][1]
}
bSplinePoints.push([x, y])
}
}
bSplinePoints.push(points[points.length - 1])
return bSplinePoints
}
},
/**
* 得到二次线性因子
* @param k
* @param t
* @returns {number}
*/
getQuadricBSplineFactor2d: function (k, t) {
let res = 0
if (k === 0) {
res = Math.pow(t - 1, 2) / 2
} else if (k === 1) {
res = (-2 * Math.pow(t, 2) + 2 * t + 1) / 2
} else if (k === 2) {
res = Math.pow(t, 2) / 2
}
return res
}
}
/**
* 三维数学工具
* 默认三维
* @param {*} viewer
*/
function Math3d(viewer) { }
Math3d.prototype = {
/**
* 拆分组合坐标数组
* @param {*} cartesianArr
*/
splitCartesians3: function (cartesianArr) {
var positions = []
for (var i = 0; i < cartesianArr.length; i += 3) {
var cartesian = new Cesium.Cartesian3(cartesianArr[i], cartesianArr[i + 1], cartesianArr[i + 2]);
positions.push(cartesian)
}
positions.push(positions[0])
return positions
},
/**
* 计算链路的点集
* @param startPoint 开始节点
* @param endPoint 结束节点
* @param angularityFactor 曲率
* @param numOfSingleLine 点集数量
* @returns {Array}
*/
getLinkedPointList: function (startPoint, endPoint, angularityFactor, numOfSingleLine) {
if (this._viewer) {
var result = [];
var startPosition = Cesium.Cartographic.fromCartesian(startPoint);
var endPosition = Cesium.Cartographic.fromCartesian(endPoint);
var startLon = startPosition.longitude * 180 / Math.PI;
var startLat = startPosition.latitude * 180 / Math.PI;
var endLon = endPosition.longitude * 180 / Math.PI;
var endLat = endPosition.latitude * 180 / Math.PI;
var dist = Math.sqrt((startLon - endLon) * (startLon - endLon) + (startLat - endLat) * (startLat - endLat));
//var dist = Cesium.Cartesian3.distance(startPoint, endPoint);
var angularity = dist * angularityFactor;
var startVec = Cesium.Cartesian3.clone(startPoint);
var endVec = Cesium.Cartesian3.clone(endPoint);
var startLength = Cesium.Cartesian3.distance(startVec, Cesium.Cartesian3.ZERO);
var endLength = Cesium.Cartesian3.distance(endVec, Cesium.Cartesian3.ZERO);
Cesium.Cartesian3.normalize(startVec, startVec);
Cesium.Cartesian3.normalize(endVec, endVec);
if (Cesium.Cartesian3.distance(startVec, endVec) == 0) {
return result;
}
var omega = Cesium.Cartesian3.angleBetween(startVec, endVec);
result.push(startPoint);
for (var i = 1; i < numOfSingleLine - 1; i++) {
var t = i * 1.0 / (numOfSingleLine - 1);
var invT = 1 - t;
var startScalar = Math.sin(invT * omega) / Math.sin(omega);
var endScalar = Math.sin(t * omega) / Math.sin(omega);
var startScalarVec = Cesium.Cartesian3.multiplyByScalar(startVec, startScalar, new Cesium.Cartesian3());
var endScalarVec = Cesium.Cartesian3.multiplyByScalar(endVec, endScalar, new Cesium.Cartesian3());
var centerVec = Cesium.Cartesian3.add(startScalarVec, endScalarVec, new Cesium.Cartesian3());
var ht = t * Math.PI;
var centerLength = startLength * invT + endLength * t + Math.sin(ht) * angularity;
centerVec = Cesium.Cartesian3.multiplyByScalar(centerVec, centerLength, centerVec);
result.push(centerVec);
}
result.push(endPoint);
return result;
}
},
/**
* 计算两点的角度
* @param {*} option
*/
getPositionsAngle: function (option) {
if (option) {
var position1 = option.position1, position2 = option.position2,
localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position1),//以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4()),//求世界坐标到局部坐标的变换矩阵
localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position1, new Cesium.Cartesian3()), //a点在局部坐标的位置,其实就是局部坐标原点
localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position2, new Cesium.Cartesian3()), //B点在以A点为原点的局部的坐标位置
angle;//弧度
if ('pitch' === option.type) { //俯仰角
angle = Math.atan2((localPosition_B.z - localPosition_A.z), (localPosition_B.x - localPosition_A.x))
} else if ('heading ' === option.type) { //偏航角
angle = Math.atan2((localPosition_B.y - localPosition_A.y), (localPosition_B.x - localPosition_A.x))
}
var theta = angle * (180 / Math.PI);//角度
if (theta < 0) {
theta = theta + 360;
}
return theta;
}
},
/**
* 计算一组坐标组成的面的面积
* @param {*} positions
*/
getPositionsArea: function (positions) {
let result = 0
if (positions) {
let h = 0
let ellipsoid = Cesium.Ellipsoid.WGS84
positions.push(positions[0])
for (let i = 1; i < positions.length; i++) {
let oel = ellipsoid.cartographicToCartesian(
this.transformWGS84ToCartographic(positions[i - 1])
)
let el = ellipsoid.cartographicToCartesian(
this.transformWGS84ToCartographic(positions[i])
)
h += oel.x * el.y - el.x * oel.y
}
result = Math.abs(h).toFixed(2)
}
return result
},
/**
* 计算多边形的面积
* @param {*} points
*/
getPolygonArea: function (points) {
if (this._viewer) {
var Bearing = function (from, to) {
var lat1 = from.lat * radiansPerDegree,
lon1 = from.lon * radiansPerDegree,
lat2 = to.lat * radiansPerDegree,
lon2 = to.lon * radiansPerDegree, angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
if (angle < 0) {
angle += Math.PI * 2.0;
}
angle = angle * degreesPerRadian;//角度
return angle;
}
var Angle = function (p1, p2, p3) {
var bearing21 = Bearing(p2, p1),
bearing23 = Bearing(p2, p3),
angle = bearing21 - bearing23;
if (angle < 0) {
angle += 360;
}
return angle;
}
var res = 0;
//拆分三角曲面
for (var i = 0; i < points.length - 2; i++) {
var j = (i + 1) % points.length, k = (i + 2) % points.length,
totalAngle = Angle(points[i], points[j], points[k]),
dis_temp1 = this.getPositionsDistance(positions[i], positions[j]),
dis_temp2 = this.getPositionsDistance(positions[j], positions[k]);
res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
}
return (res / 1000000.0).toFixed(4);
}
},
/**
* 获取两点距离
* @param {*} point1
* @param {*} point2
*/
getPointDistance: function (point1, point2) {
if (this._viewer) {
var point1cartographic = Cesium.Cartographic.fromCartesian(point1),
point2cartographic = Cesium.Cartographic.fromCartesian(point2);
/**根据经纬度计算出距离**/
var geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
var s = geodesic.surfaceDistance;
//返回两点之间的距离
s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
return s;
}
},
/**
* 获取84坐标的距离
* @param {*} positions
*/
getPositionDistance: function (positions) {
let distance = 0
for (let i = 0; i < positions.length - 1; i++) {
let point1cartographic = this.transformWGS84ToCartographic(positions[i])
let point2cartographic = this.transformWGS84ToCartographic(positions[i + 1])
let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(point1cartographic, point2cartographic)
let s = geodesic.surfaceDistance
s = Math.sqrt(
Math.pow(s, 2) +
Math.pow(point2cartographic.height - point1cartographic.height, 2)
)
distance = distance + s
}
return distance.toFixed(3)
},
/**
* 获取相交对象
* @param {*} startPos
* @param {*} endPos
* @param {*} excludeArr
* @param {*} bDrillPick
*/
getIntersectObj: function (startPos, endPos, excludeArr = [], bDrillPick = false) {
if (this._viewer) {
var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(endPos, startPos, new Cesium.Cartesian3()), new Cesium.Cartesian3());
var ray = new Cesium.Ray(startPos, direction); //无限延长的射线
var results = [];
if (bDrillPick) {
results = this._viewer.scene.drillPickFromRay(ray, 10, excludeArr);
} else //只pick首个物体
{
var result = this._viewer.scene.pickFromRay(ray, excludeArr);
if (Cesium.defined(result)) {
results = [result];
}
}
return results;
}
},
/**
* 椭圆计算
* @param {*} theta
* @param {*} rotation
* @param {*} northVec
* @param {*} eastVec
* @param {*} aSqr
* @param {*} ab
* @param {*} bSqr
* @param {*} mag
* @param {*} unitPos
* @param {*} result
*/
getPointOnEllipsoid: function (theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) {
if (this._viewer) {
var rotAxis = new Cesium.Cartesian3();
var tempVec = new Cesium.Cartesian3();
var unitQuat = new Cesium.Quaternion();
var rotMtx = new Cesium.Matrix3();
var azimuth = theta + rotation;
Cesium.Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
Cesium.Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
Cesium.Cartesian3.add(rotAxis, tempVec, rotAxis);
var cosThetaSquared = Math.cos(theta);
cosThetaSquared = cosThetaSquared * cosThetaSquared;
var sinThetaSquared = Math.sin(theta);
sinThetaSquared = sinThetaSquared * sinThetaSquared;
var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
var angle = radius / mag;
// Create the quaternion to rotate the position vector to the boundary of the ellipse.
Cesium.Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
Cesium.Matrix3.fromQuaternion(unitQuat, rotMtx);
Cesium.Matrix3.multiplyByVector(rotMtx, unitPos, result);
Cesium.Cartesian3.normalize(result, result);
Cesium.Cartesian3.multiplyByScalar(result, mag, result);
return result;
}
},
/**
* 计算点的插值高度
* Returns the positions raised to the given heights
* @private
*/
raisePositionsToHeight: function (positions, options, extrude) {
if (this._viewer) {
var scratchCartesian1 = new Cesium.Cartesian3();
var scratchCartesian2 = new Cesium.Cartesian3();
var scratchCartesian3 = new Cesium.Cartesian3();
var scratchNormal = new Cesium.Cartesian3();
var ellipsoid = options.ellipsoid;
var height = options.height;
var extrudedHeight = options.extrudedHeight;
var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3;
var finalPositions = new Float64Array(size * 3);
var length = positions.length;
var bottomOffset = (extrude) ? length : 0;
for (var i = 0; i < length; i += 3) {
var i1 = i + 1;
var i2 = i + 2;
var position = Cesium.Cartesian3.fromArray(positions, i, scratchCartesian1);
ellipsoid.scaleToGeodeticSurface(position, position);
var extrudedPosition = Cesium.Cartesian3.clone(position, scratchCartesian2);
var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);
var scaledNormal = Cesium.Cartesian3.multiplyByScalar(normal, height, scratchCartesian3);
Cesium.Cartesian3.add(position, scaledNormal, position);
if (extrude) {
Cesium.Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal);
Cesium.Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition);
finalPositions[i + bottomOffset] = extrudedPosition.x;
finalPositions[i1 + bottomOffset] = extrudedPosition.y;
finalPositions[i2 + bottomOffset] = extrudedPosition.z;
}
finalPositions[i] = position.x;
finalPositions[i1] = position.y;
finalPositions[i2] = position.z;
}
return finalPositions;
}
},
/**
* options.semiMinorAxis:短半轴
* options.semiMajorAxis:长半轴
* options.rotation:旋转角度 弧度
* options.center:中心点 笛卡尔坐标
* options.granularity:粒度 弧度
* Returns an array of positions that make up the ellipse.
* @private
*/
computeEllipseEdgePositions: function (options) {
if (this._viewer) {
var unitPosScratch = new Cesium.Cartesian3();
var eastVecScratch = new Cesium.Cartesian3();
var northVecScratch = new Cesium.Cartesian3();
var scratchCartesian1 = new Cesium.Cartesian3();
var semiMinorAxis = options.semiMinorAxis;
var semiMajorAxis = options.semiMajorAxis;
var rotation = options.rotation;//法线
var center = options.center;
var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
if (granularity > Math.PI / 12.0) { granularity = Math.PI / 12.0; }//最小分24
if (granularity < Math.PI / 180.0) { granularity = Math.PI / 180.0; }//最大分360
var aSqr = semiMinorAxis * semiMinorAxis;
var bSqr = semiMajorAxis * semiMajorAxis;
var ab = semiMajorAxis * semiMinorAxis;
var mag = Cesium.Cartesian3.magnitude(center);//
var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
var numPts = Math.ceil(Cesium.Math.PI * 2 / granularity);
var deltaTheta = granularity;
var theta = 0;
var position = scratchCartesian1;
var i;
var outerIndex = 0;
var outerPositions = [];
for (i = 0; i < numPts; i++) {
theta = i * deltaTheta;
position = this.getPointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
outerPositions[outerIndex++] = position.x;
outerPositions[outerIndex++] = position.y;
outerPositions[outerIndex++] = position.z;
}
var r = {};
r.numPts = numPts;
r.outerPositions = outerPositions;
return r;
}
},
/**
* options.semiMinorAxis:短半轴
* options.semiMajorAxis:长半轴
* options.rotation:旋转角度 弧度
* options.center:中心点 笛卡尔坐标
* options.granularity:粒度 弧度
* options.angle:角度 弧度
* Returns an array of positions that make up the ellipse.
* @private
*/
computeSectorEdgePositions: function (options) {
if (this._viewer) {
var unitPosScratch = new Cesium.Cartesian3();
var eastVecScratch = new Cesium.Cartesian3();
var northVecScratch = new Cesium.Cartesian3();
var scratchCartesian1 = new Cesium.Cartesian3();
var semiMinorAxis = options.semiMinorAxis;
var semiMajorAxis = options.semiMajorAxis;
var rotation = options.rotation;
var angle = options.angle ? options.angle : Math.PI * 2.0;
var center = options.center;
var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
if (granularity > Math.PI / 12.0) { granularity = Math.PI / 12.0; }//最小分24
if (granularity < Math.PI / 180.0) { granularity = Math.PI / 180.0; }//最大分360
var aSqr = semiMinorAxis * semiMinorAxis;
var bSqr = semiMajorAxis * semiMajorAxis;
var ab = semiMajorAxis * semiMinorAxis;
var mag = Cesium.Cartesian3.magnitude(center);//
var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
var numPts = Math.ceil(angle / granularity);//Math.ceil(Cesium.Math.PI * 2 / granularity);
var deltaTheta = granularity;
var theta = 0;
var position = scratchCartesian1;
var i;
var outerIndex = 0;
var outerPositions = [];
for (i = 0; i < numPts; i++) {
theta = i * deltaTheta;
position = this.getPointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
outerPositions[outerIndex++] = position.x;
outerPositions[outerIndex++] = position.y;
outerPositions[outerIndex++] = position.z;
}
var r = {};
r.numPts = numPts;
r.outerPositions = outerPositions;
return r;
}
},
/**
* 获取3DTiles高度
* 传入lonlat数组 角度制的lon lat
* @param {*} lonlats
* @param {*} callback
*/
computeLonlatPointsTerrainData: function (lonlats, callback) {
if (this._viewer) {
var pointArrInput = [];
for (var i = 0; i < lonlats.length; i++) {
pointArrInput.push(Cesium.Cartographic.fromDegrees(lonlats[i].lon, lonlats[i].lat));
}
var promise = this._viewer.scene.clampToHeightMostDetailed(pointArrInput);//pointArrInput
promise.then(function (updatedPositions) {
callback(updatedPositions);
});
}
},
/**
* 获取3DTiles高度
* 传入Cartographic类型数组 弧度制经纬度
* @param {*} Cartographics
* @param {*} callback
*/
computeCartographicPointsTerrainData: function (Cartographics, callback) {
if (this._viewer) {
if (Cartographics.length && Cartographics.length > 0) { } else { return; }
var pointArrInput = [];
for (var i = 0; i < Cartographics.length; i++) {
pointArrInput.push(Cesium.Cartesian3.fromRadians(Cartographics[i].longitude, Cartographics[i].latitude, Cartographics[i].height));
}
var promise = this._viewer.scene.clampToHeightMostDetailed(pointArrInput), $this = this;//pointArrInput
promise.then(function (updatedPositions) {
var result = [];
var ellipsoid = $this._viewer.scene.globe.ellipsoid;
for (var j = 0; j < updatedPositions.length; j++) {
result.push(ellipsoid.cartesianToCartographic(updatedPositions[j]));
}
callback(result);
}).otherwise(function (error) {
console.log(error)
});
}
},
_checkLonDegree: function (value) {
if (value > 180 || value < -180) {
return false;
}
return true;
},
_checkLatDegree: function (value) {
if (value > 90 || value < -90) {
return false;
}
return true;
},
/*
线段插值
经纬度坐标插值
start.lon start.lat 单位:度
return [[lon,lat],...]
*/
computeInterpolateLineLonlat: function (start, end) {
if (start && end) { } else { return null; }
if (start.lon && start.lat && end.lon && end.lat) { } else { return null; }
if (this._checkLonDegree(start.lon) && this._checkLonDegree(end.lon) && this._checkLatDegree(start.lat) && this._checkLatDegree(end.lat)) { } else { return null; }
var result = [];
result.push([start.lon, start.lat]);
var interval = Math.sqrt(Math.pow((end.lon - start.lon), 2) + Math.pow((end.lat - start.lat), 2));
if (interval <= 0.00001) {
//小于最小间隔
result.push([end.lon, end.lat]);
return result;
} else {
var num = interval / 0.00001;
var stepLon = (end.lon - start.lon) / num;
var stepLat = (end.lat - start.lat) / num;
for (var i = 0; i < num; i++) {
var lon = start.lon + (i + 1) * stepLon;
var lat = start.lat + (i + 1) * stepLat;
result.push([lon, lat]);
}
}
return result;
},
/*
线段插值
经纬度坐标插值
Cartographic start.longitude start.latitude 单位:弧度
return [Cartographic,...]
*/
computeInterpolateLineCartographic: function (start, end, _Delta) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
var result = [];
//开始点
result.push(new Cesium.Cartographic(start.longitude, start.latitude));
var interval = Math.sqrt(Math.pow((end.longitude - start.longitude), 2) + Math.pow((end.latitude - start.latitude), 2));
var delta = _Delta && (typeof _Delta === 'number') ? _Delta : 0.00001 * Math.PI / 180.0;
if (interval <= delta) {
//小于最小间隔
result.push(new Cesium.Cartographic(end.longitude, end.latitude));
return result;
} else {
var num = interval / delta;
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
for (var i = 0; i < num; i++) {
var lon = start.longitude + (i + 1) * stepLon;
var lat = start.latitude + (i + 1) * stepLat;
result.push(new Cesium.Cartographic(lon, lat));//与最后一个点有偏差
}
result.push(new Cesium.Cartographic(end.longitude, end.latitude, end.height));
}
return result;
},
/*
线段插值
经纬度高程插值
Cartographic start.longitude start.latitude 单位:弧度 start.height 高程单位m
return [Cartographic,...]
*/
computeInterpolateLineHeightCartographic: function (start, end) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
var result = [];
result.push(new Cesium.Cartographic(start.longitude, start.latitude, start.height));
var interval = Math.sqrt(Math.pow((end.longitude - start.longitude), 2) + Math.pow((end.latitude - start.latitude), 2));
if (interval <= 0.00001 * Math.PI / 180.0) {
//小于最小间隔
result.push(new Cesium.Cartographic(end.longitude, end.latitude, end.height));
return result;
} else {
var num = interval / 0.00001 * Math.PI / 180.0;
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
var stepHeight = (end.height - start.height) / num;
for (var i = 0; i < num; i++) {
var lon = start.longitude + (i + 1) * stepLon;
var lat = start.latitude + (i + 1) * stepLat;
var hieght = start.height + (i + 1) * stepHeight;
result.push(new Cesium.Cartographic(lon, lat, hieght));
}
result.push(new Cesium.Cartographic(end.longitude, end.latitude, end.height));
}
return result;
},
/*
线段插值
经纬度高程插值
Cartographic start.longitude start.latitude 单位:弧度 start.height 高程单位m
num:分总段数 传入数组长度-1
index:获取到第index点的所有插值 0点是开始点
return [Cartographic,...]
*/
computeInterpolate2IndexLineHeightCartographic: function (start, end, num, curIndex) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
var result = [];
result.push(new Cesium.Cartographic(start.longitude, start.latitude, start.height));
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
var stepHeight = (end.height - start.height) / num;
for (var i = 0; i < curIndex; i++) {
var lon = start.longitude + (i + 1) * stepLon;
var lat = start.latitude + (i + 1) * stepLat;
var hieght = start.height + (i + 1) * stepHeight;
result.push(new Cesium.Cartographic(lon, lat, hieght));
}
//result.push(new Cesium.Cartographic(end.longitude, end.latitude, end.height));
return result;
},
/*
线段插值 指定第index值
经纬度高程插值
Cartographic start.longitude start.latitude 单位:弧度 start.height 高程单位m
num:分总段数 传入数组长度-1
index:获取第index个插值点 0点是开始点
return Cartographic
*/
computeInterpolateIndexLineHeightCartographic: function (start, end, num, index) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
//var delta = _Delta && (typeof _Delta === 'number') ? _Delta : 0.00001 * Math.PI / 180.0;
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
var stepHeight = (end.height - start.height) / num;
var lon = start.longitude + index * stepLon;
var lat = start.latitude + index * stepLat;
var hieght = start.height + index * stepHeight;
var result = new Cesium.Cartographic(lon, lat, hieght);
return result;
}
}
/**
* 材质模块
* @param {*} viewer
*/
function Material(viewer) {
if (viewer) {
this._installMaterial()
}
}
Material.prototype = {
/**
* 添加材质线
* 动态炫光线
* @param {*} options
*/
addMaterialLineGraphics: function (options) {
if (this._viewer && options && options.image) {
// 初始化自定义材质线
this._initPolylineCustomMaterialProperty(options)
var _entity = this.createGraphics()
_entity.polyline = {
positions: options.positions,
material: new Cesium.PolylineCustomMaterialProperty({ color: options.color || Cesium.Color.RED, duration: options.duration || 500 }),
width: options.width
}
return this._viewer.entities.add(_entity)
}
},
/**
* 获取一个材质线
* @param {*} options
*/
getCustomMaterialLine: function (options) {
if (this._viewer && options && options.image) {
// 初始化自定义材质线
return this._initPolylineCustomMaterialProperty(options)
}
},
// 动态初始化材质线
_initPolylineCustomMaterialProperty(options) {
if (options) {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defined = Cesium.defined,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
createPropertyDescriptor = Cesium.createPropertyDescriptor,
Property = Cesium.Property,
Material = Cesium.Material,
defaultColor = Color.WHITE,
MaterialType = options.MaterialType || 'wallType' + parseInt(Math.random() * 1000);
function PolylineCustomMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = options.color || Cesium.Color.BLUE;
this.duration = options.duration || 1000;
this._time = undefined;
}
defineProperties(PolylineCustomMaterialProperty.prototype, {
isvarant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
},
color: createPropertyDescriptor('color')
});
PolylineCustomMaterialProperty.prototype.getType = function (time) {
return MaterialType;
};
PolylineCustomMaterialProperty.prototype.getValue = function (time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);
result.image = options.image;
if (this._time === undefined) {
this._time = time.secondsOfDay;
}
result.time = (time.secondsOfDay - this._time) * 1000 / this.duration;
return result;
};
PolylineCustomMaterialProperty.prototype.equals = function (other) {
return this === other || //
(other instanceof PolylineCustomMaterialProperty &&
Property.equals(this._color, other._color));
};
Material._materialCache.addMaterial(MaterialType, {
fabric: {
type: MaterialType,
uniforms: {
color: options.color || new Cesium.Color(1.0, 0.0, 0.0, 0.5),
image: options.image,
time: options.color.time || 0
},
source: this._getDynamicLineShader({ get: true })
},
translucent: function (material) {
return true;
}
})
return new PolylineCustomMaterialProperty(options);
}
},
/**
* 动态围栏
* 炫光墙体
* @param {*} options
*/
addMaterialWallGraphics: function (options) {
if (this._viewer && options && options.image) {
// 初始化自定义材质
this._initWallCustomMaterialProperty(options)
var _entity = this.createGraphics()
_entity.wall = {
positions: options.positions,
material: new Cesium.WallLinkCustomMaterialProperty({ color: options.color || Cesium.Color.RED, duration: options.duration || 500 }),
width: options.width
}
return this._viewer.entities.add(_entity)
}
},
/**
* 获取一个材质围栏
* @param {*} options
*/
getCustomMaterialWall: function (options) {
if (this._viewer && options && options.image) {
return this._initWallCustomMaterialProperty(options)
}
},
// 动态初始化材质线
_initWallCustomMaterialProperty(options) {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defined = Cesium.defined,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
createPropertyDescriptor = Cesium.createPropertyDescriptor,
Property = Cesium.Property,
Material = Cesium.Material,
MaterialType = options.MaterialType || 'wallType' + parseInt(Math.random() * 1000);
function WallLinkCustomMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = options.color || Color.BLUE;
this.duration = options.duration || 3000;
this._time = new Date().getTime();
}
defineProperties(WallLinkCustomMaterialProperty.prototype, {
isvarant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
},
color: createPropertyDescriptor('color')
});
WallLinkCustomMaterialProperty.prototype.getType = function (time) {
return MaterialType;
};
WallLinkCustomMaterialProperty.prototype.getValue = function (time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(
this._color,
time,
Color.WHITE,
result.color
);
result.image = options.image;;
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration;
return result;
};
WallLinkCustomMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof WallLinkCustomMaterialProperty &&
Property.equals(this._color, other._color))
);
};
//动态墙
Material._materialCache.addMaterial(MaterialType,
{
fabric: {
type: MaterialType,
uniforms: {
color: new Color(1.0, 0.0, 0.0, 0.5),
image: options.image,
time: 0
},
source: this._getDirectionWallShader({
get: true,
count: options.count,
freely: options.freely,
direction: options.direction
})
},
translucent: function (material) {
return true;
}
}
);
return new WallLinkCustomMaterialProperty(options)
},
/**
* 安装默认拓展材质
*/
_installMaterial: function () {
this._installWaveCircleMaterial()
this._installCircleFadeMaterial()
this._installCityLineMaterial()
this._installWarnMaterial()
this._installFlowMaterial()
},
// 波动圆材质
_installWaveCircleMaterial: function () {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
Property = Cesium.Property,
Material = Cesium.Material;
function CircleWaveMaterialProperty(options) {
options = options || {}
this._definitionChanged = new Event()
this._color = undefined
this._colorSubscription = undefined
this._duration = undefined
this._durationSubscription = undefined
this.color = defaultValue(
options.color,
Color.fromBytes(0, 255, 255, 255)
)
this.duration = defaultValue(options.duration, 45)
this.count = Math.max(defaultValue(options.count, 2), 1)
this.gradient = defaultValue(options.gradient, 0.1)
if (this.gradient < 0) {
this.gradient = 0
} else if (this.gradient > 1) {
this.gradient = 1
}
}
defineProperties(CircleWaveMaterialProperty.prototype, {
isConstant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
}
});
CircleWaveMaterialProperty.prototype.getType = function (time) {
return Material.CircleWaveType
};
CircleWaveMaterialProperty.prototype.getValue = function (time, result) {
if (!result) {
result = {}
}
result.color = Property.getValueOrUndefined(this._color, time)
result.duration = this._duration
result.count = this.count
result.gradient = this.gradient
return result
};
CircleWaveMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof CircleWaveMaterialProperty &&
Cesium.Property.equals(this._color, other._color))
)
};
defineProperties(CircleWaveMaterialProperty.prototype, {
color: Cesium.createPropertyDescriptor('color'),
duration: Cesium.createPropertyDescriptor('duration')
})
Cesium.CircleWaveMaterialProperty = CircleWaveMaterialProperty
Material.CircleWaveType = 'CircleWave'
Material._materialCache.addMaterial(Material.CircleWaveType, {
fabric: {
type: Material.CircleWaveType,
uniforms: {
color: new Color(1.0, 0.0, 0.0, 0.7),
duration: 45,
count: 1,
gradient: 0.1
},
source: this._getDynamicCircleShader({ get: true })
},
translucent: function (material) {
return true
}
})
},
// 渐变圆
_installCircleFadeMaterial: function () {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
Property = Cesium.Property,
Material = Cesium.Material,
_color = new Color(0, 0, 0, 0);
function CircleFadeMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT)
this._definitionChanged = new Event
this._color = void 0
this._colorSubscription = void 0
this.color = defaultValue(options.color, _color)
this._duration = options.duration || 1e3
this._time = void 0
}
defineProperties(CircleFadeMaterialProperty.prototype, {
isConstant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
}
});
CircleFadeMaterialProperty.prototype.getType = function (time) {
return Material.CircleFadeMaterialType
};
CircleFadeMaterialProperty.prototype.getValue = function (time, result) {
if (!result) {
result = {}
}
result.color = Property.getValueOrClonedDefault(this._color, time, _color, result.color),
void 0 === this._time && (this._time = (new Date).getTime()),
result.time = ((new Date).getTime() - this._time) / this._duration
return result
};
CircleFadeMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof CircleFadeMaterialProperty &&
Cesium.Property.equals(this._color, other._color))
)
};
defineProperties(CircleFadeMaterialProperty.prototype, {
color: Cesium.createPropertyDescriptor("color")
});
Cesium.CircleFadeMaterialProperty = CircleFadeMaterialProperty;
Material.CircleFadeMaterialType = "CircleFadeMaterial"
Material._materialCache.addMaterial(Material.CircleFadeMaterialType, {
fabric: {
type: Material.CircleFadeMaterialType,
uniforms:
{
color: new Color(1, 0, 0, 1),
time: 1
},
source: this._getCircleFadeShader({ get: true })
},
translucent: function () {
return !0
}
})
},
// 城市光效线
_installCityLineMaterial: function () {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defined = Cesium.defined,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
createPropertyDescriptor = Cesium.createPropertyDescriptor,
Property = Cesium.Property,
Material = Cesium.Material,
defaultColor = Color.WHITE;
function PolylineCityLinkMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = options.color || Cesium.Color.BLUE;
this.duration = options.duration || 1000;
this._time = undefined;
}
defineProperties(PolylineCityLinkMaterialProperty.prototype, {
isvarant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
},
color: createPropertyDescriptor('color')
});
PolylineCityLinkMaterialProperty.prototype.getType = function (time) {
return Material.PolylineCityLinkType;
};
PolylineCityLinkMaterialProperty.prototype.getValue = function (time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);
result.image = Material.PolylineCityLinkImage;
if (this._time === undefined) {
this._time = time.secondsOfDay;
}
result.time = (time.secondsOfDay - this._time) * 1000 / this.duration;
return result;
};
PolylineCityLinkMaterialProperty.prototype.equals = function (other) {
return this === other || //
(other instanceof PolylineCityLinkMaterialProperty &&
Property.equals(this._color, other._color));
};
Cesium.PolylineCityLinkMaterialProperty = PolylineCityLinkMaterialProperty
Material.PolylineCityLinkType = 'PolylineCityLink';
Material.PolylineCityLinkImage = 'data/images/Textures/meteor_01.png';
Material._materialCache.addMaterial(Material.PolylineCityLinkType,
{
fabric: {
type: Material.PolylineCityLinkType,
uniforms: {
color: new Color(1, 0, 0, 1.0),
image: Material.PolylineCityLinkImage,
time: 0,
},
source: this._getDynamicLightLineShader({ get: true })
},
translucent: function () {
return true;
}
});
},
// 城市警示墙
_installWarnMaterial: function () {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defined = Cesium.defined,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
createPropertyDescriptor = Cesium.createPropertyDescriptor,
Property = Cesium.Property,
Material = Cesium.Material;
function WarnLinkMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = options.color || Color.BLUE;
this.duration = options.duration || 3000;
this._time = new Date().getTime();
}
defineProperties(WarnLinkMaterialProperty.prototype, {
isvarant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
}
});
WarnLinkMaterialProperty.prototype.getType = function (time) {
return Material.WarnLinkType;
};
WarnLinkMaterialProperty.prototype.getValue = function (time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(
this._color,
time,
Color.WHITE,
result.color
);
result.image = Material.WarnLinkImage;
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration;
return result;
};
WarnLinkMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof WarnLinkMaterialProperty &&
Property.equals(this._color, other._color))
);
};
defineProperties(WarnLinkMaterialProperty.prototype, {
color: createPropertyDescriptor("color")
});
Cesium.WarnLinkMaterialProperty = WarnLinkMaterialProperty
Material.WarnLinkType = "WarnWallLinkType";
Material.WarnLinkImage = "data/images/Textures/jsx2.png";
Material._materialCache.addMaterial(Material.WarnLinkType,
{
fabric: {
type: Material.WarnLinkType,
uniforms: {
color: new Color(1.0, 0.0, 0.0, 0.5),
image: Material.WarnLinkImage,
time: 0
},
source: this._getDirectionWallShader({
get: true,
count: 10.0,
freely: 'cross',
direction: '-'
})
},
translucent: function (material) {
return true;
}
}
);
},
// 轨迹流动线
_installFlowMaterial: function () {
var Color = Cesium.Color,
defaultValue = Cesium.defaultValue,
defineProperties = Object.defineProperties,
Event = Cesium.Event,
createPropertyDescriptor = Cesium.createPropertyDescriptor,
Property = Cesium.Property,
Material = Cesium.Material;
function PolylineFlowMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event()
this._color = undefined
this._colorSubscription = undefined
this.color = options.color || Color.fromBytes(0, 255, 255, 255)
this._duration = undefined
this._durationSubscription = undefined
this.duration = defaultValue(options.duration, 45)
}
defineProperties(PolylineFlowMaterialProperty.prototype, {
isConstant: {
get: function () {
return false;
}
},
definitionChanged: {
get: function () {
return this._definitionChanged;
}
}
});
PolylineFlowMaterialProperty.prototype.getType = function (time) {
return Material.PolylineFlowType;
};
PolylineFlowMaterialProperty.prototype.getValue = function (time, result) {
if (!result) {
result = {}
}
result.color = Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
)
result.duration = this._duration
return result
};
PolylineFlowMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof PolylineFlowMaterialProperty &&
Property.equals(this._color, other._color))
)
};
defineProperties(PolylineFlowMaterialProperty.prototype, {
color: createPropertyDescriptor('color'),
duration: createPropertyDescriptor('duration')
})
Cesium.PolylineFlowMaterialProperty = PolylineFlowMaterialProperty
Material.PolylineFlowType = 'PolylineFlow'
Material._materialCache.addMaterial(Material.PolylineFlowType, {
fabric: {
type: Material.PolylineFlowType,
uniforms: {
color: new Color(1.0, 1.0, 2.0, 0.7),
duration: 45
},
source: this._getFlowLineShader({ get: true })
},
translucent: function (material) {
return true
}
})
}
}
/**
* 外部插件模块
* @param {*} viewer
*/
function Plugin(viewer) {
if (viewer) {
this._pluginLayer = new Cesium.CustomDataSource('pluginLayer')
viewer && viewer.dataSources.add(this._pluginLayer)
this._installPlugin()
}
}
Plugin.prototype = {
// 安装插件
_installPlugin: function () {
this._installCss3Renderer()
this._installGroundSkyBox()
this._installTerrainClipPlan()
},
/**
* 地形裁剪
*/
_installTerrainClipPlan: function () {
function TerrainClipPlan(t, i) {
this.viewer = t,
this.options = i || {},
this._positions = i.positions,
this._height = this.options.height || 0,
this.bottomImg = i.bottomImg,
this.wallImg = i.wallImg,
this.splitNum = Cesium.defaultValue(i.splitNum, 50),
this._positions && this._positions.length > 0 && this.updateData(this._positions)
}
Object.defineProperties(TerrainClipPlan.prototype, {
show: {
get: function () {
return this._show
},
set: function (e) {
this._show = e, this.viewer.scene.globe.clippingPlanes && (this.viewer.scene.globe.clippingPlanes.enabled = e), this._switchExcavate(e)
}
},
height: {
get: function () {
return this._height
},
set: function (e) {
this._height = e, this._updateExcavateDepth(e)
}
}
})
TerrainClipPlan.prototype.updateData = function (e) {
this.clear();
var t = [],
i = e.length,
a = new Cesium.Cartesian3,
n = Cesium.Cartesian3.subtract(e[0], e[1], a);
n = n.x > 0, this.excavateMinHeight = 9999;
for (var r = 0; r < i; ++r) {
var s = (r + 1) % i,
l = Cesium.Cartesian3.midpoint(e[r], e[s], new Cesium.Cartesian3),
u = Cesium.Cartographic.fromCartesian(e[r]),
c = this.viewer.scene.globe.getHeight(u) || u.height;
c < this.excavateMinHeight && (this.excavateMinHeight = c);
var d, h = Cesium.Cartesian3.normalize(l, new Cesium.Cartesian3);
d = n ? Cesium.Cartesian3.subtract(e[r], l, new Cesium.Cartesian3) : Cesium.Cartesian3.subtract(e[s], l, new Cesium.Cartesian3), d = Cesium.Cartesian3.normalize(d, d);
var f = Cesium.Cartesian3.cross(d, h, new Cesium.Cartesian3);
f = Cesium.Cartesian3.normalize(f, f);
var p = new Cesium.Plane(f, 0),
m = Cesium.Plane.getPointDistance(p, l);
t.push(new Cesium.ClippingPlane(f, m))
}
this.viewer.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
planes: t,
edgeWidth: 1,
edgeColor: Cesium.Color.WHITE,
enabled: !0
}), this._prepareWell(e), this._createWell(this.wellData)
}
TerrainClipPlan.prototype.clear = function () {
this.viewer.scene.globe.clippingPlanes && (this.viewer.scene.globe.clippingPlanes.enabled = !1, this.viewer.scene.globe.clippingPlanes.removeAll(), this.viewer.scene.globe.clippingPlanes.isDestroyed() || this.viewer.scene.globe.clippingPlanes.destroy()), this.viewer.scene.globe.clippingPlanes = void 0, this.bottomSurface && this.viewer.scene.primitives.remove(this.bottomSurface), this.wellWall && this.viewer.scene.primitives.remove(this.wellWall), delete this.bottomSurface, delete this.wellWall, this.viewer.scene.render()
}
TerrainClipPlan.prototype._prepareWell = function (e) {
var t = this.splitNum,
i = e.length;
if (0 != i) {
for (var a = this.excavateMinHeight - this.height, n = [], r = [], s = [], l = 0; l < i; l++) {
var u = l == i - 1 ? 0 : l + 1,
c = Cesium.Cartographic.fromCartesian(e[l]),
d = Cesium.Cartographic.fromCartesian(e[u]),
h = [c.longitude, c.latitude],
f = [d.longitude, d.latitude];
0 == l && (
s.push(new Cesium.Cartographic(h[0], h[1])),
r.push(Cesium.Cartesian3.fromRadians(h[0], h[1], a)),
n.push(Cesium.Cartesian3.fromRadians(h[0], h[1], 0)));
for (var p = 1; p <= t; p++) {
var m = Cesium.Math.lerp(h[0], f[0], p / t),
g = Cesium.Math.lerp(h[1], f[1], p / t);
l == i - 1 && p == t || (
s.push(new Cesium.Cartographic(m, g)),
r.push(Cesium.Cartesian3.fromRadians(m, g, a)),
n.push(Cesium.Cartesian3.fromRadians(m, g, 0)))
}
}
this.wellData = {
lerp_pos: s,
bottom_pos: r,
no_height_top: n
}
}
}
TerrainClipPlan.prototype._createWell = function (e) {
if (Boolean(this.viewer.terrainProvider._layers)) {
var t = this;
this._createBottomSurface(e.bottom_pos);
var i = Cesium.sampleTerrainMostDetailed(this.viewer.terrainProvider, e.lerp_pos);
Cesium.when(i, function (i) {
for (var a = i.length, n = [], r = 0; r < a; r++) {
var s = Cesium.Cartesian3.fromRadians(i[r].longitude, i[r].latitude, i[r].height);
n.push(s)
}
t._createWellWall(e.bottom_pos, n)
})
} else {
this._createBottomSurface(e.bottom_pos);
this._createWellWall(e.bottom_pos, e.no_height_top)
}
}
TerrainClipPlan.prototype._getMinHeight = function (e) {
let minHeight = 5000000;
let minPoint = null;
for (let i = 0; i < e.length; i++) {
let height = e[i]['z'];
if (height < minHeight) {
minHeight = height;
minPoint = this._ellipsoidToLonLat(e[i]);
}
}
return minPoint.altitude;
}
TerrainClipPlan.prototype._ellipsoidToLonLat = function (c) {
let ellipsoid = this.viewer.scene.globe.ellipsoid;
let cartesian3 = new Cesium.Cartesian3(c.x, c.y, c.z);
let cartographic = ellipsoid.cartesianToCartographic(cartesian3);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let lng = Cesium.Math.toDegrees(cartographic.longitude);
let alt = cartographic.height;
return {
longitude: lng,
latitude: lat,
altitude: alt
}
}
TerrainClipPlan.prototype._createBottomSurface = function (e) {
if (e.length) {
let minHeight = this._getMinHeight(e);
let positions = [];
for (let i = 0; i < e.length; i++) {
let p = this._ellipsoidToLonLat(e[i]);
positions.push(p.longitude);
positions.push(p.latitude);
positions.push(minHeight);
}
let polygon = new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArrayHeights(positions)
),
perPositionHeight: true
});
let geometry = Cesium.PolygonGeometry.createGeometry(polygon);
var i = new Cesium.Material({
fabric: {
type: "Image",
uniforms: {
image: this.bottomImg
}
}
}),
a = new Cesium.MaterialAppearance({
translucent: !1,
flat: !0,
material: i
});
this.bottomSurface = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: geometry
}),
appearance: a,
asynchronous: !1
}), this.viewer.scene.primitives.add(this.bottomSurface)
}
}
TerrainClipPlan.prototype._createWellWall = function (e, t) {
let minHeight = this._getMinHeight(e);
let maxHeights = [];
let minHeights = [];
for (let i = 0; i < t.length; i++) {
maxHeights.push(this._ellipsoidToLonLat(t[i]).altitude);
minHeights.push(minHeight);
}
let wall = new Cesium.WallGeometry({
positions: t,
maximumHeights: maxHeights,
minimumHeights: minHeights,
});
let geometry = Cesium.WallGeometry.createGeometry(wall);
var a = new Cesium.Material({
fabric: {
type: "Image",
uniforms: {
image: this.wallImg
}
}
}),
n = new Cesium.MaterialAppearance({
translucent: !1,
flat: !0,
material: a
});
this.wellWall = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: geometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GREY)
},
id: "PitWall"
}),
appearance: n,
asynchronous: !1
}), this.viewer.scene.primitives.add(this.wellWall)
}
TerrainClipPlan.prototype._switchExcavate = function (e) {
e ? (this.viewer.scene.globe.material = Cesium.Material.fromType("WaJue"), this.wellWall.show = !0, this.bottomSurface.show = !0) : (this.viewer.scene.globe.material = null, this.wellWall.show = !1, this.bottomSurface.show = !1)
}
TerrainClipPlan.prototype._updateExcavateDepth = function (e) {
this.bottomSurface && this.viewer.scene.primitives.remove(this.bottomSurface), this.wellWall && this.viewer.scene.primitives.remove(this.wellWall);
for (var t = this.wellData.lerp_pos, i = [], a = t.length, n = 0; n < a; n++) i.push(Cesium.Cartesian3.fromRadians(t[n].longitude, t[n].latitude, this.excavateMinHeight - e));
this.wellData.bottom_pos = i, this._createWell(this.wellData), this.viewer.scene.primitives.add(this.bottomSurface), this.viewer.scene.primitives.add(this.wellWall)
}
Cesium.TerrainClipPlan = TerrainClipPlan
},
// 灯光扫描插件
buildLightScanGraphics: function (data) {
if (this._viewer && data) {
var $this = this
//生成 entityCList面--形成圆锥
var createLightScan_entityCList = function (point, data) {
var lon = data.observer[0], lat = data.observer[1], h = data.observer[2];
var entityCList = [];
//创建 面
for (var i = 0; i < point.length; i++) {
var hierarchy;
if (i === (point.length - 1)) {
hierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(
[
lon, lat, h,
point[i].x, point[i].y, 0,
point[0].x, point[0].y, 0
]))
} else {
hierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(
[
lon, lat, h,
point[i].x, point[i].y, 0,
point[i + 1].x, point[i + 1].y, 0
]))
}
var entityC = $this._pluginLayer.entities.add({
name: "三角形",
polygon: {
hierarchy: hierarchy,
outline: false,
perPositionHeight: true,//允许三角形使用点的高度
material: data.material
}
});
entityCList.push(entityC);
}
return entityCList
}
/**
* 改变每个面的位置
* @param {*} data
* @param {*} entity
* @param {*} arr
*/
var createLightScan_changeOnePosition = function (data, entity, arr) {
var positionList = data.positionList;
var x, y, x0, y0, X0, Y0, n = 0, a = 0;//x代表差值 x0代表差值等分后的值,X0表示每次回调改变的值。a表示回调的循环窜次数,n表示扫描的坐标个数
function f(i) {
x = positionList[i + 1][0] - positionList[i][0];//差值
y = positionList[i + 1][1] - positionList[i][1];//差值
x0 = x / data.number;//将差值等分500份
y0 = y / data.number;
a = 0;
}
f(n);
entity.polygon.hierarchy = new Cesium.CallbackProperty(function () { //回调函数
if ((Math.abs(X0) >= Math.abs(x)) && (Math.abs(Y0) >= Math.abs(y))) { //当等分差值大于等于差值的时候 就重新计算差值和等分差值 Math.abs
n = n + 1;
if (n === positionList.length - 1) {
n = 0;
}
arr[0] = arr[0] + X0;
arr[1] = arr[1] + Y0;
arr[2] = arr[2] + X0;
arr[3] = arr[3] + Y0;
f(n);//重新赋值 x y x0 y0
}
X0 = a * x0;//将差值的等份逐渐递增。直到大于差值 会有精度丢失,所以扩大再加 x0=x0+0.0001
Y0 = a * y0;//将差值的等份逐渐递增。直到大于差值 会有精度丢失,所以扩大再加
a++;
return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(
[
data.observer[0], data.observer[1], data.observer[2],
arr[0] + X0, arr[1] + Y0, 0,
arr[2] + X0, arr[3] + Y0, 0
]))
}, false)
}
//生成分割点
var point = $this._getCirclePoints(data.circle[0], data.circle[1], data.circle[2], data.circle[3]); //生成分割点
//生成 entityCList 圆锥
var entityCList = createLightScan_entityCList(point, data) //生成 entityCList 圆锥
for (var i = 0; i < entityCList.length; i++) {
if (i !== entityCList.length - 1) {
createLightScan_changeOnePosition(data, entityCList[i], [point[i].x, point[i].y, point[i + 1].x, point[i + 1].y]) //中间arr 代表的是点的坐标
} else {
createLightScan_changeOnePosition(data, entityCList[i], [point[i].x, point[i].y, point[0].x, point[0].y])
}
}
return entityCList
}
},
// 路径漫游
buildPathRoaming: function (options) {
if (this._viewer && options && options.paths) {
var _paths = options.paths, _property = new Cesium.SampledPositionProperty(),
_rEntity = this.createGraphics(),
_startTime = new Cesium.JulianDate(),
_stopTime = Cesium.JulianDate.addSeconds(
_startTime,
(_paths.length - 1) * 120,
new Cesium.JulianDate()
);
var startTime = options.startTime || _startTime
var stopTime = options.stopTime || _stopTime
this._viewer.clock.startTime = startTime.clone(); // 设置始时钟始时间
this._viewer.clock.currentTime = startTime.clone(); // 设置时钟当前时间
this._viewer.clock.stopTime = stopTime.clone(); // 设置始终停止时间
this._viewer.clock.multiplier = options.multiplier || 10; // 时间速率,数字越大时间过的越快
this._viewer.clock.clockRange = options.clockRange || Cesium.ClockRange.LOOP_STOP; // 循环执行
for (var i = 0; i < _paths.length; i++) {
var cartesian = Cesium.Cartesian3.fromDegrees(
_paths[i].lon,
_paths[i].lat,
_paths[i].alt
);
var time = Cesium.JulianDate.addSeconds(
startTime,
_paths[i].time,
new Cesium.JulianDate()
);
_property.addSample(time, cartesian); // 添加位置,和时间对应
}
_rEntity.name = options.name || "路径漫游";
_rEntity.availability = new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({ start: startTime, stop: stopTime })
]); // 和时间轴关联
_rEntity.position = _property;
_rEntity.orientation = new Cesium.VelocityOrientationProperty(_property); //基于位置移动自动计算方向
// 添加图形
var polyline = [];
if (options.polyline) {
_rEntity.polyline = {
positions: new Cesium.CallbackProperty(function () {
return polyline;
}, false),
width: 10,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 1,
color: Cesium.Color.RED
}),
clampToGround: true
};
}
if (options.model) {
_rEntity.model = this.getModelGraphics(options)
}
if (options.label) {
_rEntity.label = this.getLabelGraphics(options)
}
if (options.billboard) {
_rEntity.billboard = this.getBillboardGraphics(options)
}
return this._pluginLayer.entities.add(_rEntity)
}
},
/**
* 拓展css3的动画 html元素
*/
_installCss3Renderer: function () {
/**
* 添加css3 html元素
* @param app
* @param elements
* @param isBackHide
* @constructor
*/
if (this._viewer) {
var viewer = this._viewer;
function Css3Renderer(elements, isBackHide) {
this._scratch = new Cesium.Cartesian2()
this._viewer = viewer
this._scene = viewer.scene,
this._camera = viewer.camera
this._container = null
this._elements = elements
this._isBackHide = isBackHide
this.init()
}
Css3Renderer.prototype.init = function () {
var container = document.createElement('div')
container.className = `ys-css3-container`
document.body.appendChild(container)
this._container = container
this._elements.forEach(function (e) {
container.insertAdjacentHTML('beforeend', e.element);
})
var $this = this
this._scene.preRender.addEventListener(function () {
//
for (var i = 0; i < container.children.length; i++) {
var p = Cesium.Cartesian3.fromDegrees($this._elements[i].position[0], $this._elements[i].position[1], $this._elements[i].position[2] || 0)
var canvasPosition = $this._scene.cartesianToCanvasCoordinates(p, $this._scratch)
if (Cesium.defined(canvasPosition)) {
container.children[i].style.left = parseFloat(canvasPosition.x) + parseFloat($this._elements[i].offset[0]) + 'px'
container.children[i].style.top = parseFloat(canvasPosition.y) + parseFloat($this._elements[i].offset[1]) + 'px'
if ($this._isBackHide) {
var j = $this._camera.position, n = $this._scene.globe.ellipsoid.cartesianToCartographic(j).height;
if (!(n += 1 * $this._scene.globe.ellipsoid.maximumRadius, Cesium.Cartesian3.distance(j, p) > n)) {
container.children[i].style.display = 'block'
} else {
container.children[i].style.display = 'none'
}
}
}
}
})
}
Css3Renderer.prototype.remove = function (id) {
this._elements = this._elements.filter(function (e) { e.id !== id })
this._container.removeChild(document.getElementById(id))
}
Css3Renderer.prototype.append = function (object) {
this._elements.push(object)
this._container.insertAdjacentHTML('beforeend', object.element)
}
Css3Renderer.prototype.removeEntityLayer = function (id) {
this._viewer.entities.removeById(id + "_1")
this._viewer.entities.removeById(id + "_2")
this._viewer.entities.removeById(id + "_3")
this.remove(id)
}
Css3Renderer.prototype.addEntityLayer = function (object) {
var lon = object.position[0],
lat = object.position[1],
sStartFlog = false,
$this = this,
s1 = 0.001,
s2 = s1,
s3 = s1,
s4 = s1
setTimeout(function (sStartFlog) { sStartFlog = true }, 300)
var rotation = Cesium.Math.toRadians(30);
var rotation2 = Cesium.Math.toRadians(30);
//构建entity
var height = object.boxHeight || 300, heightMax = object.boxHeightMax || 400, heightDif = object.boxHeightDif || 10;
var goflog = true
//添加正方体
if (object.boxShow) {
this._viewer.entities.add({
id: object.id + "_1",
name: "立方体盒子",
position: new Cesium.CallbackProperty(function () {
height = height + heightDif;
if (height >= heightMax) {
height = heightMax
}
return Cesium.Cartesian3.fromDegrees(lon, lat, height / 2)
}, false),
box: {
dimensions: new Cesium.CallbackProperty(function () {
height = height + heightDif
if (height >= heightMax) {
height = heightMax
if (goflog) { //需要增加判断 不然它会一直执行; 导致对div的dom操作 会一直重复
goflog = false
$this.append(object, true)
}
}
return new Cesium.Cartesian3(object.boxSide || 100, object.boxSide || 100, height)
}, false),
material: object.boxMaterial || Cesium.Color.DEEPSKYBLUE.withAlpha(0.5)
}
});
} else {
// 只要弹出框
setTimeout(function () { $this.append(object, true) }, 100)
}
if (object.circleShow) {
object.circleSize = object.circleSize || 120
//添加底座 一 外环
this._viewer.entities.add({
id: object.id + "_2",
name: "椭圆",
position: Cesium.Cartesian3.fromDegrees(lon, lat),
ellipse: {
// semiMinorAxis : object.circleSize, //直接这个大小 会有一个闪白的材质 因为cesium材质默认是白色 所以我们先将大小设置为0
// semiMajorAxis : object.circleSize,
semiMinorAxis: new Cesium.CallbackProperty(function () {
if (sStartFlog) {
s1 = s1 + object.circleSize / 20;
if (s1 >= object.circleSize) {
s1 = object.circleSize;
}
}
return s1;
}, false),
semiMajorAxis: new Cesium.CallbackProperty(function () {
if (sStartFlog) {
s2 = s2 + object.circleSize / 20;
if (s2 >= object.circleSize) {
s2 = object.circleSize
}
}
return s2;
}, false),
material: "data/images/Textures/circle2.png",
rotation: new Cesium.CallbackProperty(function () {
rotation += 0.05;
return rotation;
}, false),
stRotation: new Cesium.CallbackProperty(function () {
rotation += 0.05;
return rotation;
}, false),
zIndex: 2,
}
});
//添加底座二 内环
this._viewer.entities.add({
id: object.id + "_3",
name: "椭圆",
position: Cesium.Cartesian3.fromDegrees(lon, lat),
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(function () {
if (sStartFlog) {
s3 = s3 + object.circleSize / 20;
if (s3 >= object.circleSize / 2) {
s3 = object.circleSize / 2;
}
}
return s3;
}, false),
semiMajorAxis: new Cesium.CallbackProperty(function () {
if (sStartFlog) {
s4 = s4 + object.circleSize / 20;
if (s4 >= object.circleSize / 2) {
s4 = object.circleSize / 2;
}
}
return s4;
}, false),
material: "data/images/Textures/circle1.png",
rotation: new Cesium.CallbackProperty(function () {
rotation2 -= 0.03
return rotation2
}, false),
stRotation: new Cesium.CallbackProperty(function () {
rotation2 -= 0.03
return rotation2
}, false),
zIndex: 3
}
})
}
}
Cesium.Css3Renderer = Css3Renderer
}
},
// 拓展近景天空盒
_installGroundSkyBox: function () {
var BoxGeometry = Cesium.BoxGeometry,
Cartesian3 = Cesium.Cartesian3,
defaultValue = Cesium.defaultValue,
defined = Cesium.defined,
destroyObject = Cesium.destroyObject,
DeveloperError = Cesium.DeveloperError,
GeometryPipeline = Cesium.GeometryPipeline,
Matrix3 = Cesium.Matrix3,
Matrix4 = Cesium.Matrix4,
Transforms = Cesium.Transforms,
VertexFormat = Cesium.VertexFormat,
BufferUsage = Cesium.BufferUsage,
CubeMap = Cesium.CubeMap,
DrawCommand = Cesium.DrawCommand,
loadCubeMap = Cesium.loadCubeMap,
RenderState = Cesium.RenderState,
VertexArray = Cesium.VertexArray,
BlendingState = Cesium.BlendingState,
SceneMode = Cesium.SceneMode,
ShaderProgram = Cesium.ShaderProgram,
ShaderSource = Cesium.ShaderSource;
//片元着色器,直接从源码复制
var SkyBoxFS = "uniform samplerCube u_cubeMap;\n\
varying vec3 v_texCoord;\n\
void main()\n\
{\n\
vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));\n\
gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);\n\
}\n\
";
//顶点着色器有修改,主要是乘了一个旋转矩阵
var SkyBoxVS = "attribute vec3 position;\n\
varying vec3 v_texCoord;\n\
uniform mat3 u_rotateMatrix;\n\
void main()\n\
{\n\
vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\n\
gl_Position = czm_projection * vec4(p, 1.0);\n\
v_texCoord = position.xyz;\n\
}\n\
";
/**
* 为了兼容高版本的Cesium,因为新版cesium中getRotation被移除
*/
if (!defined(Matrix4.getRotation)) {
Matrix4.getRotation = Matrix4.getMatrix3
}
function SkyBoxOnGround(options) {
this.sources = options.sources;
this._sources = undefined;
/**
* Determines if the sky box will be shown.
*
* @type {Boolean}
* @default true
*/
this.show = defaultValue(options.show, true);
this._command = new DrawCommand({
modelMatrix: Matrix4.clone(Matrix4.IDENTITY),
owner: this
});
this._cubeMap = undefined;
this._attributeLocations = undefined;
this._useHdr = undefined;
}
var skyboxMatrix3 = new Matrix3();
SkyBoxOnGround.prototype.update = function (frameState, useHdr) {
var that = this;
if (!this.show) {
return undefined;
}
if ((frameState.mode !== SceneMode.SCENE3D) &&
(frameState.mode !== SceneMode.MORPHING)) {
return undefined;
}
if (!frameState.passes.render) {
return undefined;
}
var context = frameState.context;
if (this._sources !== this.sources) {
this._sources = this.sources;
var sources = this.sources;
if ((!defined(sources.positiveX)) ||
(!defined(sources.negativeX)) ||
(!defined(sources.positiveY)) ||
(!defined(sources.negativeY)) ||
(!defined(sources.positiveZ)) ||
(!defined(sources.negativeZ))) {
throw new DeveloperError('this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.');
}
if ((typeof sources.positiveX !== typeof sources.negativeX) ||
(typeof sources.positiveX !== typeof sources.positiveY) ||
(typeof sources.positiveX !== typeof sources.negativeY) ||
(typeof sources.positiveX !== typeof sources.positiveZ) ||
(typeof sources.positiveX !== typeof sources.negativeZ)) {
throw new DeveloperError('this.sources properties must all be the same type.');
}
if (typeof sources.positiveX === 'string') {
// Given urls for cube-map images. Load them.
loadCubeMap(context, this._sources).then(function (cubeMap) {
that._cubeMap = that._cubeMap && that._cubeMap.destroy();
that._cubeMap = cubeMap;
});
} else {
this._cubeMap = this._cubeMap && this._cubeMap.destroy();
this._cubeMap = new CubeMap({
context: context,
source: sources
});
}
}
var command = this._command;
command.modelMatrix = Transforms.eastNorthUpToFixedFrame(frameState.camera._positionWC);
if (!defined(command.vertexArray)) {
command.uniformMap = {
u_cubeMap: function () {
return that._cubeMap;
},
u_rotateMatrix: function () {
return Matrix4.getRotation(command.modelMatrix, skyboxMatrix3);
},
};
var geometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({
dimensions: new Cartesian3(2.0, 2.0, 2.0),
vertexFormat: VertexFormat.POSITION_ONLY
}));
var attributeLocations = this._attributeLocations = GeometryPipeline.createAttributeLocations(geometry);
command.vertexArray = VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
bufferUsage: BufferUsage._DRAW
});
command.renderState = RenderState.fromCache({
blending: BlendingState.ALPHA_BLEND
});
}
if (!defined(command.shaderProgram) || this._useHdr !== useHdr) {
var fs = new ShaderSource({
defines: [useHdr ? 'HDR' : ''],
sources: [SkyBoxFS]
});
command.shaderProgram = ShaderProgram.fromCache({
context: context,
vertexShaderSource: SkyBoxVS,
fragmentShaderSource: fs,
attributeLocations: this._attributeLocations
});
this._useHdr = useHdr;
}
if (!defined(this._cubeMap)) {
return undefined;
}
return command;
};
SkyBoxOnGround.prototype.isDestroyed = function () {
return false
};
SkyBoxOnGround.prototype.destroy = function () {
var command = this._command;
command.vertexArray = command.vertexArray && command.vertexArray.destroy();
command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy();
this._cubeMap = this._cubeMap && this._cubeMap.destroy();
return destroyObject(this);
}
Cesium.GroundSkyBox = SkyBoxOnGround
}
}
/**
* 图元拓展模块
* @param {*} viewer
*/
function Primitive(viewer) {
if (viewer) {
this._installPrimitives()
}
}
Primitive.prototype = {
/**
* 安装拓展图元
*/
_installPrimitives: function () {
this._installProbingPrimitive()
this._installTexturePrimitive()
this._installWaterPrimitive()
this._installPointsPrimitive()
this._installShadowPrimitive()
this._installArrowPolylinePrimitive()
this._installXyzAxisPrimitive()
this._installTetrahedronPrimitive()
this._installCustomPrimitive()
},
/**
* 自定义图元
*/
_installCustomPrimitive: function () {
function CustomPrimitive(options) {
}
},
/**
* 光锥图元
*/
_installTetrahedronPrimitive: function () {
try {
var Cartesian3 = Cesium.Cartesian3
, ComponentDatatype = Cesium.ComponentDatatype
, PrimitiveType = Cesium.PrimitiveType
, BoundingSphere = Cesium.BoundingSphere
, GeometryAttribute = Cesium.GeometryAttribute
, GeometryPipeline = Cesium.GeometryPipeline
, Geometry = Cesium.Geometry
, defined = Cesium.defined
, RenderState = Cesium.RenderState
, ShaderSource = Cesium.ShaderSource
, ShaderProgram = Cesium.ShaderProgram
, DrawCommand = Cesium.DrawCommand
, RenderState = Cesium.RenderState
, Pass = Cesium.Pass
, Appearance = Cesium.Appearance
, BufferUsage = Cesium.BufferUsage
, Color = Cesium.Color
, VertexArray = Cesium.VertexArray
, Pass = Cesium.Pass
, buildModuleUrl = Cesium.buildModuleUrl
, Matrix4 = Cesium.Matrix4
, Matrix3 = Cesium.Matrix3
, Texture = Cesium.Texture
, Resource = Cesium.Resource
, Transforms = Cesium.Transforms
, defaultValue = Cesium.defaultValue
, _viewer = this._viewer;
function TetrahedronPrimitive(options) {
this.show = true;
this._command = undefined;
this._enuMatrix = undefined;
this._scaleMatrix = undefined;
this._localPosition = options.position
this._createCommand = createCommand;
this._angle = 0;
this._distance = defaultValue(options.distance, 1);
this._setInterval = undefined;
this._viewer = _viewer;
this._speed = defaultValue(options.speed, 1.0);
this._color = defaultValue(options.color, new Color(1.0, 1.0, 0.0, 0.8));
this._scale = defaultValue(options.scale, new Cartesian3(10, 10, 15));
this._texture = undefined;
this._imageUrl = buildModuleUrl('ThirdParty/fence.png');
this._modelMatrix = computeModelMatrix(this);
this._height = computeHeight(this);
createTexture(this);
}
TetrahedronPrimitive.prototype.update = function (frameState) {
if (!this.show) {
return;
}
if (!defined(this._command)) {
this._command = this._createCommand(frameState.context, this);
this._command.pickId = 'v_pickColor';
}
if (defined(this._command)) {
frameState.commandList.push(this._command);
}
}
TetrahedronPrimitive.prototype.isDestroyed = function () {
return false;
}
TetrahedronPrimitive.prototype.destroy = function () {
if (defined(this._command)) {
this._command.shaderProgram = this._command.shaderProgram && this._command.shaderProgram.destroy();
}
return destroyObject(this);
}
//开启动画
TetrahedronPrimitive.prototype.startAnimate = function () {
let that = this;
this._setInterval = setInterval(animateFunc, 5);
function animateFunc() {
that._angle = that._angle + 0.01;
Math.sin(that._angle) > 0 ? that._height = 0.01 : that._height = -0.01;
let translation = new Cesium.Cartesian3(0, 0, that._height);
Matrix4.multiplyByTranslation(that._modelMatrix, translation, that._modelMatrix)
let rotationZ = Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(Cesium.Math.toRadians(that._speed)));
Matrix4.multiply(that._modelMatrix, rotationZ, that._modelMatrix);
}
}
//关闭动画
TetrahedronPrimitive.prototype.closeAnimate = function () {
clearInterval(this._setInterval);
}
//创建command
function createCommand(context, tetrahedronPrimitive) {
var translucent = false;
var closed = true;
var vs = creaateVertexShader();
var fs = createFragmentShader();
// 借用一下Appearance.getDefaultRenderState
var rawRenderState = Appearance.getDefaultRenderState(translucent, closed, undefined);
var renderState = RenderState.fromCache(rawRenderState);
var vertexShaderSource = new ShaderSource({
sources: [vs]
});
var fragmentShaderSource = new ShaderSource({
sources: [fs]
});
var uniformMap = {
color: function () {
return tetrahedronPrimitive._color;
},
myImage: function () {
if (defined(tetrahedronPrimitive._texture)) {
return tetrahedronPrimitive._texture;
} else {
return tetrahedronPrimitive._viewer.scene.context.defaultTexture;
}
}
}
let attributeLocations = {
position: 0,
textureCoordinates: 1
};
var shaderProgram = ShaderProgram.fromCache({
context: context,
vertexShaderSource: vertexShaderSource,
fragmentShaderSource: fragmentShaderSource,
attributeLocations: attributeLocations
});
return new DrawCommand({
vertexArray: createVertexArray(context),
primitiveType: PrimitiveType.TRIANGLES,
renderState: renderState,
shaderProgram: shaderProgram,
uniformMap: uniformMap,
owner: this,
pass: Pass.TRANSLUCENT,
modelMatrix: tetrahedronPrimitive._modelMatrix,
});
}
//创建vertexArray
function createVertexArray(context) {
let attributeLocations = {
position: 0,
textureCoordinates: 1
};
var positionsAndIndice = cereatePositionsAndIndice();
var geometry = new Geometry({
attributes: {
position: new GeometryAttribute({
// 使用double类型的position进行计算
// componentDatatype : Cesium.ComponentDatatype.DOUBLE,
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: positionsAndIndice.positions
}),
textureCoordinates: new GeometryAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: positionsAndIndice.sts
}),
},
// Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN
indices: positionsAndIndice.indices,
primitiveType: PrimitiveType.TRIANGLES,
boundingSphere: BoundingSphere.fromVertices(positionsAndIndice.positions)
});
//计算geometry的法向量
var geometryNormal = GeometryPipeline.computeNormal(geometry);
var vertexArray = VertexArray.fromGeometry({
context: context,
geometry: geometryNormal,
attributeLocations: attributeLocations,
bufferUsage: BufferUsage.STATIC_DRAW,
});
return vertexArray;
}
//创建顶点数组与索引
function cereatePositionsAndIndice() {
var positions = new Float64Array(5 * 3);
// position 0
positions[0] = 0.0;
positions[1] = 1.0;
positions[2] = 0.0;
// position 1
positions[3] = -1.0;
positions[4] = 0.0;
positions[5] = 0.0;
// position 2
positions[6] = 0.0;
positions[7] = -1.0;
positions[8] = 0.0;
// position 3
positions[9] = 1.0;
positions[10] = 0.0;
positions[11] = 0.0;
// position 4
positions[12] = 0.0;
positions[13] = 0.0;
positions[14] = -1.0;
var indices = new Uint16Array(6 * 3);
// back triangle
indices[0] = 4;
indices[1] = 2;
indices[2] = 3;
// left triangle
indices[3] = 4;
indices[4] = 3;
indices[5] = 0;
// right triangle
indices[6] = 4;
indices[7] = 0;
indices[8] = 1;
// bottom triangle
indices[9] = 4;
indices[10] = 1;
indices[11] = 2;
// bottom triangle
indices[12] = 1;
indices[13] = 2;
indices[14] = 3;
// bottom triangle
indices[15] = 1;
indices[16] = 3;
indices[17] = 0;
// 1.3 定义纹理数组
var sts = new Float32Array([
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 1.0, 0.5, 0.5,
]);
return {
indices: indices,
positions: positions,
sts: sts
}
}
//创建顶点着色器
function creaateVertexShader() {
var vertexShader =
`
attribute vec3 position;
attribute vec3 normal;
attribute vec2 st;
attribute float batchId;
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
varying vec4 v_pickColor;
void main()
{
v_positionEC = (czm_modelView * vec4(position, 1.0)).xyz; // position in eye coordinates
v_normalEC = czm_normal * normal; // normal in eye coordinates
v_st = st;
//v_pickColor = czm_batchTable_pickColor(batchId);
gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
`;
return vertexShader;
}
//创建片源着色器
function createFragmentShader() {
var fragmentShader =
`
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
uniform vec4 color;
varying vec4 v_pickColor;
uniform sampler2D myImage;
void main()
{
vec3 positionToEyeEC = -v_positionEC;
vec3 normalEC = normalize(v_normalEC);
#ifdef FACE_FORWARD
normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);
#endif
czm_materialInput materialInput;
materialInput.normalEC = normalEC;
materialInput.positionToEyeEC = positionToEyeEC;
materialInput.st = v_st;
vec2 st = materialInput.st;
czm_material material = czm_getDefaultMaterial(materialInput);
float dt_a11 = fract(czm_frameNumber / 100.0) * 3.14159265 * 2.0;
float dt_a12 = sin(dt_a11);
float vst=smoothstep(0.7, 1.0, dt_a12)+0.4;
vec4 colorImage = texture2D(myImage, vec2(fract(st.s- czm_frameNumber*0.003), st.t));
material.alpha =mix(0.1,1.0,clamp((1.0-st.t) * color.a,0.0,1.0)) +(1.0-sign(st.t-czm_frameNumber*0.001))*0.2*(1.0-colorImage.r)+0.4 ;
material.diffuse =(1.0-colorImage.a)*vec3(1.0,2.0,1.0)+colorImage.rgb*vec3(1.0,2.0,1.0);
#ifdef FLAT
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
#else
gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);
#endif
}
`;
return fragmentShader;
}
//创建纹理
function createTexture(tetrahedronPrimitive) {
Resource.createIfNeeded(tetrahedronPrimitive._imageUrl).fetchImage().then(function (image) {
var vTexture;
var context = tetrahedronPrimitive._viewer.scene.context;
if (defined(image.internalFormat)) {
vTexture = new Texture({
context: context,
pixelFormat: image.internalFormat,
width: image.naturalWidth,
height: image.naturalHeight,
source: {
arrayBufferView: image.bufferView
}
});
} else {
vTexture = new Texture({
context: context,
source: image
});
}
tetrahedronPrimitive._texture = vTexture;
});
}
//计算矩阵
function computeModelMatrix(tetrahedronPrimitive) {
let enuMatrix = Transforms.eastNorthUpToFixedFrame(tetrahedronPrimitive._localPosition);
let scaleMatrix = Matrix4.fromScale(tetrahedronPrimitive._scale);
let modelMatrix = Matrix4.multiply(enuMatrix, scaleMatrix, new Matrix4());
tetrahedronPrimitive._scaleMatrix = scaleMatrix;
tetrahedronPrimitive._enuMatrix = enuMatrix;
return modelMatrix;
}
//计算高度
function computeHeight(tetrahedronPrimitive) {
let point = Cartesian3.fromElements(0, 0, tetrahedronPrimitive._distance, new Cesium.Cartesian3());
let enuPoint = Cesium.Matrix4.multiplyByPoint(tetrahedronPrimitive._enuMatrix, point, new Cartesian3());
let upPositionEC = Matrix4.multiplyByPoint(tetrahedronPrimitive._viewer.scene.camera._viewMatrix, enuPoint, new Cartesian3());
let upPositionPC = Matrix4.multiplyByPoint(tetrahedronPrimitive._viewer.scene.camera.frustum.projectionMatrix, upPositionEC, new Cartesian3());
return Cartesian3.normalize(upPositionPC, new Cartesian3()).z;
}
Cesium.TetrahedronPrimitive = TetrahedronPrimitive;
} catch (error) {
console.log(error)
}
},
_installXyzAxisPrimitive: function () {
function XyzAxisPrimitive(option) {
this._viewer = option.viewer
this._model = option.model
this._matrix = option.matrix
this._radius = undefined
this._layer = new Cesium.CustomDataSource('xyz-axis')
this._viewer.dataSources.add(this._layer)
this._handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
this._xyzState = false
this._xyzPid = undefined
this._build()
}
XyzAxisPrimitive.prototype = {
_build() {
this._createAxisXYZ()
this._bindHandler()
},
remove() {
this._layer._primitives.removeAll()
this._handler.distory()
},
_createAxisXYZ: function () {
this._model.readyPromise.then(m => {
const center1 = Cesium.Matrix4.getTranslation(
m.modelMatrix,
new Cesium.Cartesian3()
);
const boundingShpere = m.boundingSphere;
const radius = boundingShpere.radius
const axisZ = new Cesium.ArrowPolylinePrimitive({
id: "axisZ",
color: Cesium.Color.RED,
position: center1,
width: 3,
headWidth: 5,
length: radius * 2 + 50,
headLength: 10
});
const axisX = new Cesium.ArrowPolylinePrimitive({
id: "axisX",
color: Cesium.Color.GREEN,
position: center1,
width: 3,
headWidth: 5,
length: radius * 2 + 50,
headLength: 10
});
const axisY = new Cesium.ArrowPolylinePrimitive({
id: "axisY",
color: Cesium.Color.BLUE,
position: center1,
width: 3,
headWidth: 5,
length: radius * 2 + 50,
headLength: 10
});
const mx = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90));
this._rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
Cesium.Matrix4.multiply(
axisX.geometryInstances[0].modelMatrix,
this._rotationX,
axisX.geometryInstances[0].modelMatrix
);
Cesium.Matrix4.multiply(
axisX.geometryInstances[1].modelMatrix,
this._rotationX,
axisX.geometryInstances[1].modelMatrix
);
const my = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(90));
this._rotationY = Cesium.Matrix4.fromRotationTranslation(my);
Cesium.Matrix4.multiply(
axisY.geometryInstances[0].modelMatrix,
this._rotationY,
axisY.geometryInstances[0].modelMatrix
);
Cesium.Matrix4.multiply(
axisY.geometryInstances[1].modelMatrix,
this._rotationY,
axisY.geometryInstances[1].modelMatrix
);
this._layer._primitives.add(axisZ)
this._layer._primitives.add(axisX)
this._layer._primitives.add(axisY)
this._radius = boundingShpere.radius
this._createAxisSphere()
});
},
_createAxisSphere: function () {
const position = [];
for (let i = 0; i <= 360; i += 3) {
const sin = Math.sin(Cesium.Math.toRadians(i));
const cos = Math.cos(Cesium.Math.toRadians(i));
const x = this._radius * cos;
const y = this._radius * sin;
position.push(new Cesium.Cartesian3(x, y, 0));
}
const axisSphereZ = this._createAxisSpheres(
"axisSphereZ",
position,
this._matrix,
Cesium.Color.RED
);
this._layer._primitives.add(axisSphereZ);
const axisSphereY = this._createAxisSpheres(
"axisSphereY",
position,
this._matrix,
Cesium.Color.GREEN
);
this._layer._primitives.add(axisSphereY);
Cesium.Matrix4.multiply(
axisSphereY.geometryInstances.modelMatrix,
this._rotationY,
axisSphereY.geometryInstances.modelMatrix
);
const axisSphereX = this._createAxisSpheres(
"axisSphereX",
position,
this._matrix,
Cesium.Color.BLUE
);
this._layer._primitives.add(axisSphereX);
Cesium.Matrix4.multiply(
axisSphereX.geometryInstances.modelMatrix,
this._rotationX,
axisSphereX.geometryInstances.modelMatrix
);
},
_createAxisSpheres: function (id, position, matrix, color) {
const geometry = new Cesium.PolylineGeometry({
positions: position,
width: 10
});
const instnce = new Cesium.GeometryInstance({
geometry: geometry,
id: id,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
}
});
return new Cesium.Primitive({
geometryInstances: instnce,
appearance: new Cesium.PolylineColorAppearance({
translucent: false
}),
modelMatrix: matrix
});
},
_updateAxis(cartesian) {
if (this._layer) {
let primitives = this._layer._primitives._primitives
for (let i = 1, j = primitives.length; i < j; i++) {
let primitive = primitives[i]
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(cartesian.x, cartesian.y, cartesian.z))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
}
}
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(cartesian.x, cartesian.y, cartesian.z))
Cesium.Matrix4.multiply(this._model.modelMatrix, translation, this._model.modelMatrix)
},
_updateAxisSphere(angel) {
if (this._layer) {
let primitives = this._layer._primitives._primitives
for (let i = 1, j = primitives.length; i < j; i++) {
let primitive = primitives[i]
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
Cesium.Matrix4.multiply(primitive.modelMatrix, rotation, primitive.modelMatrix)
}
}
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
Cesium.Matrix4.multiply(this._model.modelMatrix, rotation, this._model.modelMatrix)
},
_bindHandler() {
//拖动
this._handler.setInputAction((click) => {
if (this._xyzState && this._xyzPid) {
switch (this._xyzPid) {
case "axisX-line": this._updateAxis({ x: -1, y: 0, z: 0 }); break;
case "axisY-line": this._updateAxis({ x: 0, y: -1, z: 0 }); break;
case "axisZ-line": this._updateAxis({ x: 0, y: 0, z: -1 }); break;
case "axisX-arrow": this._updateAxis({ x: 1, y: 0, z: 0 }); break;
case "axisY-arrow": this._updateAxis({ x: 0, y: 1, z: 0 }); break;
case "axisZ-arrow": this._updateAxis({ x: 0, y: 0, z: 1 }); break;
case "axisSphereX": this._updateAxisSphere(Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(1))); break;
case "axisSphereY": this._updateAxisSphere(Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(1))); break;
case "axisSphereZ": this._updateAxisSphere(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(1))); break;
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//拾取
this._handler.setInputAction((click) => {
let pickObj = viewer.scene.pick(click.position)
if (pickObj && pickObj.id) {
this._xyzPid = pickObj.id
, this._xyzState = true
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
//结束
this._handler.setInputAction((click) => {
this._xyzState = false
, this._xyzPid = undefined;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
}
}
Cesium.XyzAxisPrimitive = XyzAxisPrimitive
},
/**
* 箭头线
*/
_installArrowPolylinePrimitive: function () {
function ArrowPolylinePrimitive(option = {}) {
this._color = option.color || Cesium.Color.RED;
this._width = option.width || 3;
this._headWidth = option.headWidth || 2 * this._width;
this._length = option.length || 300
this._headLength = option.headLength || 10
this._inverse = option.inverse || false
this.position = option.position
const id = option.id
//这里用的是圆锥几何对象,当topRadius和bottomRadius相同时,它就是一个圆柱
const line = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
length: this._length,
topRadius: this._width,
bottomRadius: this._width
}));
const arrow = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
length: this._headLength,
topRadius: 0,
bottomRadius: this._headWidth
}));
let offset = (this._length + this._headLength) / 2
if (this._inverse) {
offset = -offset
}
translate(arrow, [0, 0, offset]);
return new Cesium.Primitive({
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(this.position),
geometryInstances: [new Cesium.GeometryInstance(
{
id: id + '-line',
geometry: line,
}
),
new Cesium.GeometryInstance({
id: id + '-arrow',
geometry: arrow,
})],
appearance: new Cesium.MaterialAppearance({
material: Cesium.Material.fromType('Color', { color: this._color })
})
});
}
/**
* 按上面的方法画出的箭头在线的中间,我们需要把它平移到线的一端
*/
let translate = function (geometry, offset) {
const scratchOffset = new Cesium.Cartesian3();
if (offset.length) {
scratchOffset.x = offset[0];
scratchOffset.y = offset[1];
scratchOffset.z = offset[2];
} else {
Cesium.Cartesian3.clone(offset, scratchOffset);
}
for (let i = 0; i < geometry.attributes.position.values.length; i += 3) {
geometry.attributes.position.values[i] += scratchOffset.x;
geometry.attributes.position.values[i + 1] += scratchOffset.y;
geometry.attributes.position.values[i + 2] += scratchOffset.z;
}
}
Cesium.ArrowPolylinePrimitive = ArrowPolylinePrimitive
},
/**
* 阴影图元
*/
_installShadowPrimitive: function () {
const ViewshedLineVS = "ttribute vec3 position;\n\
uniform mat4 u_modelViewMatrix;\n\
void main()\n\
{\n\
gl_Position = czm_projection* u_modelViewMatrix* vec4(position.xyz,1.0);\n\
}\n\
";
const ViewshedLineFS = "uniform vec4 u_bgColor;\n\
void main()\n\
{\n\
gl_FragColor = u_bgColor;\n\
}\n\
";
function ShadowPrimitive(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
var scene = options.scene;
if (!Cesium.defined(scene)) {
throw new Cesium.DeveloperError('scene is required.');
}
this._scene = scene;
// options.context is an undocumented option
var context = scene._context;
// includeStart('debug', pragmas.debug);
if (!Cesium.defined(context)) {
throw new Cesium.DeveloperError('context is required.');
}
if (!Cesium.defined(options.viewerPosition)) {
throw new Cesium.DeveloperError('this view position is required.');
}
this._viewerPosition = options.viewerPosition;
this._positions = undefined
this._indices = undefined
this._drawLineCommand = undefined
this._depthCamera = new Cesium.Camera(scene);
this._depthCamera.position = this._viewerPosition;
this._direction = 0;
this._pitch = 0;
this._horizontalFov = Cesium.defaultValue(options.horizontalFov, 60);
this._verticalFov = Cesium.defaultValue(options.verticalFov, 45);
this._cameraUpdated = false;
this._targetPoint = this._viewerPosition.clone();
var t = new Cesium.Cartesian3(0, 0, 100);
var matrix_ENU = Cesium.Transforms.eastNorthUpToFixedFrame(this._viewerPosition);
//Cesium.Matrix4.inverse(matrix_ENU, matrix_ENU),
Cesium.Matrix4.multiplyByPoint(matrix_ENU, t, this._targetPoint);
this._distance = 100;
this._cameraUpdated = false;
this._modelMatrix = new Cesium.Matrix4,
this._shadowMap = new Cesium.ShadowMap({
context: context,
enabled: true,
lightCamera: this._depthCamera,
cascadesEnabled: false
});
//this._shadowMap.debugShow=true;
this.show = true;
this._invisiblyColor = Cesium.Color.RED;
this._visiblyColor = Cesium.Color.GREEN;
this._shadowMap.useCustomColor = true;
this.shadowMap._customColor = {
invisibly: Cesium.Color.RED,
visibly: Cesium.Color.GREEN
};
this._initialize = function () {
this._positions = new Float32Array(633),
this._indices = new Uint16Array(408);
var indices = this._indices
, r = 0;
indices[r++] = 0,
indices[r++] = 1,
indices[r++] = 0,
indices[r++] = 21,
indices[r++] = 0,
indices[r++] = 85,
indices[r++] = 0,
indices[r++] = 105;
for (var i = 0, n = 0; n < 5; ++n) {
i++;
for (var a = 0; a < 20; ++a)
indices[r++] = i++,
indices[r++] = i
}
i++;
for (var s = 0; s < 20; ++s)
for (var l = 0; l < 5; ++l)
indices[r++] = i,
indices[r++] = 5 + i++;
this._initialized = true;
};
//this._initialize();
this._debugLightFrustum = undefined;
this._debugShow = true;
}
Object.defineProperties(ShadowPrimitive.prototype, {
shadowMap: {
get: function () {
return this._shadowMap;
}
},
debugLightFrustum: {
get: function () {
return this._debugLightFrustum;
}
},
debugShow: {
get: function () {
return this._debugShow;
},
set: function (bShow) {
this.shadowMap.debugShow = bShow
this._debugShow = bShow;
}
},
invisiblyColor: {
get: function () {
return this._invisiblyColor;
},
set: function (color) {
this._invisiblyColor = color;
var shadowMap = this.shadowMap;
shadowMap._customColor.invisibly = color;
}
},
visiblyColor: {
get: function () {
return this._visiblyColor;
},
set: function (color) {
this._visiblyColor = color;
var shadowMap = this.shadowMap;
shadowMap._customColor.visibly = color;
}
},
viewerPosition: {
get: function () {
return this._viewerPosition
},
set: function (position) {
this._viewerPosition = position,
this._cameraUpdated = !1
}
},
direction: {
get: function () {
return this._direction
},
set: function (direction) {
this._direction = direction,
this._cameraUpdated = !1
}
},
pitch: {
get: function () {
return this._pitch
},
set: function (pitch) {
this._pitch = pitch,
this._cameraUpdated = !1
}
},
horizontalFov: {
get: function () {
return this._horizontalFov
},
set: function (e) {
this._horizontalFov = e,
this._cameraUpdated = !1,
this._hintLineUpdated = !1
}
},
verticalFov: {
get: function () {
return this._verticalFov
},
set: function (e) {
this._verticalFov = e,
this._cameraUpdated = !1,
this._hintLineUpdated = !1
}
},
distance: {
get: function () {
return this._distance
},
set: function (distance) {
this._distance = distance,
this._cameraUpdated = !1;
}
},
});
ShadowPrimitive.prototype.setDebugFrustumEffect = function (bShowPlane, bShowOutline) {
if (!this.debugShow) return;
var planesPrimitives = this.debugLightFrustum._planesPrimitives;
var outlinePrimitives = this.debugLightFrustum._outlinePrimitives;
planesPrimitives.forEach(function (plane) {
plane.show = bShowPlane;
});
outlinePrimitives.forEach(function (outline) {
outline.show = bShowOutline;
});
};
ShadowPrimitive.prototype.update = function (frameState) {
if (!this.show) return;
if (!this._cameraUpdated) {
this._updateCamera();
//更新debug
if (this.debugShow) {
if (!Cesium.defined(this.debugLightFrustum)) {
this._debugLightFrustum = new Cesium.DebugCameraPrimitive({
camera: this._depthCamera,
color: Cesium.Color.YELLOW,
updateOnChange: true
});
this.setDebugFrustumEffect(false, true);
}
}
}
var frustumSplitsFar = frameState.frustumSplits[1];
frameState.frustumSplits[1] = this._distance;
this._debugLightFrustum.update(frameState);
frameState.frustumSplits[1] = frustumSplitsFar;
//if(!this._initialized)this._initialize();
//if (!this._hintLineUpdated)this._updateHintLine(frameState);
frameState.shadowMaps.push(this.shadowMap);
};
ShadowPrimitive.prototype._updateCamera = function () {
this._depthCamera.frustum.near = .001 * this._distance,
this._depthCamera.frustum.far = this._distance,
this._depthCamera.frustum.fov = Cesium.Math.toRadians(Math.max(this._horizontalFov, this._verticalFov)),
this._depthCamera.frustum.aspectRatio = this._horizontalFov / this._verticalFov,
this._depthCamera.setView({
destination: this._viewerPosition,
orientation: {
heading: Cesium.Math.toRadians(this._direction),
pitch: Cesium.Math.toRadians(this._pitch)
}
}),
this._modelMatrix = this._depthCamera.inverseViewMatrix;
this._cameraUpdated = !0
};
ShadowPrimitive.prototype.setPoseByTargetPoint = function (point) {
this.distance = Cesium.Cartesian3.distance(this._viewerPosition, point);
var t = new Cesium.Cartesian3
, matrix_ENU = Cesium.Transforms.eastNorthUpToFixedFrame(this._viewerPosition);
Cesium.Matrix4.inverse(matrix_ENU, matrix_ENU),
Cesium.Matrix4.multiplyByPoint(matrix_ENU, point, t),
Cesium.Cartesian3.normalize(t, t),
this.direction = Cesium.Math.toDegrees(Math.atan2(t.x, t.y)),
this.pitch = Cesium.Math.toDegrees(Math.asin(t.z))
}
ShadowPrimitive.prototype._updateHintLine = function (frameState) {
var i, a, s, d, p = this._positions, m = Cesium.Math.toRadians(this._horizontalFov), v = Cesium.Math.toRadians(this._verticalFov), b = Math.tan(.5 * m), S = Math.tan(.5 * v);
a = this._distance * b,
d = this._distance * S,
i = -a,
s = -d;
var w = new Cesium.Cartesian3(i, s, -this._distance)
, x = new Cesium.Cartesian3(a, d, 0);
Cesium.Matrix4.multiplyByPoint(this._modelMatrix, w, w),
Cesium.Matrix4.multiplyByPoint(this._modelMatrix, x, x);
var boundingSphere = Cesium.BoundingSphere.fromCornerPoints(w, x);
if (frameState.cullingVolume.computeVisibility(boundingSphere) === Intersect.OUTSIDE)
return void (this._valid = !1);
this._valid = !0;
var P = 0;
p[P++] = 0,
p[P++] = 0,
p[P++] = 0;
for (var D, I, M = Math.PI - .5 * m, R = m / 4, L = 0; L < 5; ++L) {
D = M + L * R;
for (var B = d / (this._distance / Math.cos(D)), F = Math.atan(B), U = -F, V = F / 10, z = 0; z < 21; ++z)
I = U + z * V,
p[P++] = this._distance * Math.cos(I) * Math.sin(D),
p[P++] = this._distance * Math.sin(I),
p[P++] = this._distance * Math.cos(I) * Math.cos(D)
}
R = m / 20;
for (var G = 0; G < 21; ++G) {
D = M + G * R;
for (var B = d / (this._distance / Math.cos(D)), F = Math.atan(B), U = -F, V = F / 2, H = 0; H < 5; ++H)
I = U + H * V,
p[P++] = this._distance * Math.cos(I) * Math.sin(D),
p[P++] = this._distance * Math.sin(I),
p[P++] = this._distance * Math.cos(I) * Math.cos(D)
}
var context = frameState.context
, indexBuffer = Cesium.Buffer.createIndexBuffer({
context: context,
typedArray: new Uint32Array(this._indices),
usage: Cesium.BufferUsage.STATIC_DRAW,
indexDatatype: IndexDatatype.UNSIGNED_INT
})
, vertexBuffer = Cesium.Buffer.createVertexBuffer({
context: context,
typedArray: Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, this._positions),
usage: Cesium.BufferUsage.STATIC_DRAW
})
, attributes = [];
attributes.push({
index: 0,
vertexBuffer: vertexBuffer,
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
normalize: !1
});
var vertexArray = new Cesium.VertexArray({
context: context,
attributes: attributes,
indexBuffer: indexBuffer
});
if (Cesium.defined(this._drawLineCommand))
this._drawLineCommand.vertexArray.destroy(),
this._drawLineCommand.vertexArray = vertexArray,
this._drawLineCommand.modelMatrix = this._modelMatrix,
this._drawLineCommand.boundingVolume = boundingSphere;
else {
var shaderProgram = Cesium.ShaderProgram.fromCache({
context: context,
vertexShaderSource: ViewshedLineVS,
fragmentShaderSource: ViewshedLineFS
})
, renderState = Cesium.RenderState.fromCache({
depthTest: {
enabled: !0
}
})
, _this = this
, uniformMap = {
u_bgColor: function () {
return _this._lineColor
},
u_modelViewMatrix: function () {
return context.uniformState.modelView
}
};
this._drawLineCommand = new Cesium.DrawCommand({
boundingVolume: boundingSphere,
modelMatrix: _this._modelMatrix,
primitiveType: Cesium.PrimitiveType.LINES,
vertexArray: vertexArray,
shaderProgram: shaderProgram,
castShadows: !1,
receiveShadows: !1,
uniformMap: uniformMap,
renderState: renderState,
pass: Cesium.Pass.OPAQUE
})
}
this._hintLineUpdated = true;
}
Cesium.ShadowPrimitive = ShadowPrimitive;
},
/**
* 图元点
*/
_installPointsPrimitive: function () {
/**
*
* @param {*} options
*/
function PointsPrimitive(options) {
if (options && options.viewer && options.Cartesians) {
this._vertexShader = this.getVSPolylie();
this._fragmentShader = this.getFSPolyline();
this._geometry = null;
this._appearance = null;
this._viewer = options.viewer
this.build(options)
}
}
PointsPrimitive.prototype = {
build: function (options) {
if (options.Cartesians && options.Cartesians.length >= 2) {
var postionsTemp = [];
var colorsTemp = [];
var indicesTesm = [];
if (options.Colors && options.Colors.length === options.Cartesians.length * 4) {
for (var i = 0; i < options.Cartesians.length; i++) {
postionsTemp.push(options.Cartesians[i].x);
postionsTemp.push(options.Cartesians[i].y);
postionsTemp.push(options.Cartesians[i].z);
}
colorsTemp = options.Colors;
} else {
for (var i = 0; i < options.Cartesians.length; i++) {
postionsTemp.push(options.Cartesians[i].x);
postionsTemp.push(options.Cartesians[i].y);
postionsTemp.push(options.Cartesians[i].z);
//
colorsTemp.push(0.0);
colorsTemp.push(0.0);
colorsTemp.push(1.0);
colorsTemp.push(1.0);
}
}
for (var i = 0; i < options.Cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colorsTemp);
this.indiceArr = new Uint16Array(indicesTesm);
} else {
var p1 = Cesium.Cartesian3.fromDegrees(0, 0, -10);
var p2 = Cesium.Cartesian3.fromDegrees(0, 0.001, -10);
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
//默认蓝色
this.colorArr = new Float32Array([
0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0
]);
this.indiceArr = new Uint16Array([0, 1]);
}
this._geometry = this.createGeometry(this.positionArr, this.colorArr, this.indiceArr);
this._appearance = this.createAppearence(this._fragmentShader, this._vertexShader);
this.primitive = this._viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: this._geometry
}),
appearance: this._appearance,
asynchronous: false
}));
},
getVSPolylie: function () {
return "attribute vec3 position3DHigh;\
attribute vec3 position3DLow;\
attribute vec4 color;\
varying vec4 v_color;\
attribute float batchId;\
void main()\
{\
vec4 p = czm_computePosition();\
v_color =color;\
p = czm_modelViewProjectionRelativeToEye * p;\
gl_Position = p;\
gl_PointSize=4.0;\
}\
";
},
getFSPolyline: function () {
return "varying vec4 v_color;\
void main()\
{\
float d = distance(gl_PointCoord, vec2(0.5,0.5));\
if(d < 0.5){\
gl_FragColor = v_color;\
}else{\
discard;\
}\
}\
";
},
createAppearence: function (fs, vs) {
return new Cesium.Appearance({
renderState: {
blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
depthTest: { enabled: true },
depthMask: true
},
fragmentShaderSource: fs,
vertexShaderSource: vs
});
},
createGeometry: function (positions, colors, indices) {
return new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: positions
}),
color: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 4,
values: colors
})
},
indices: indices,
primitiveType: Cesium.PrimitiveType.POINTS,
boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
});
},
remove: function () {
if (this.primitive != null) {
this._viewer.scene.primitives.remove(this.primitive);
this.primitive = null;
}
},
updateCartesianPosition: function (cartesians) {
if (this.primitive != null) {
this._viewer.scene.primitives.remove(this.primitive);
if (cartesians && cartesians.length < 2) { return; }
if (cartesians.length === this.positionArr.length / 3) {
var p1 = cartesians[0];
var p2 = cartesians[1];
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
this._geometry = this.createGeometry(this.positionArr, this.colorArr, this.indiceArr);
} else {
//默认蓝色
var postionsTemp = [];
var colorsTemp = [];
var indicesTesm = [];
for (var i = 0; i < cartesians.length; i++) {
postionsTemp.push(cartesians[i].x);
postionsTemp.push(cartesians[i].y);
postionsTemp.push(cartesians[i].z);
colorsTemp.push(0.0);
colorsTemp.push(0.0);
colorsTemp.push(1.0);
colorsTemp.push(1.0);
}
for (var i = 0; i < cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colorsTemp);
this.indiceArr = new Uint16Array(indicesTesm);
geometry = this.createGeometry(this.positionArr, this.colorArr, this.indiceArr);
appearance = this.createAppearence(this._fragmentShader, this._vertexShader);
}
this.primitive = this._viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: this._geometry
}),
appearance: this._appearance,
asynchronous: false
}));
} else { return; }
},
updateCartesianPositionColor: function (cartesians, colors) {
if (colors.length === cartesians.length * 4) { } else { return; }
if (this.primitive != null) {
viewer.scene.primitives.remove(this.primitive);
if (cartesians && cartesians.length < 2) { return; }
if (cartesians.length === this.positionArr.length / 3) {
var p1 = cartesians[0];
var p2 = cartesians[1];
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
this.colorArr = new Float32Array(colors);
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
} else {
var postionsTemp = [];
var indicesTesm = [];
for (var i = 0; i < cartesians.length; i++) {
postionsTemp.push(cartesians[i].x);
postionsTemp.push(cartesians[i].y);
postionsTemp.push(cartesians[i].z);
}
for (var i = 0; i < cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colors);
this.indiceArr = new Uint16Array(indicesTesm);
this._geometry = this.createGeometry(this.positionArr, this.colorArr, this.indiceArr);
this._appearance = this.createAppearence(this._fragmentShader, this._vertexShader);
}
this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: this._geometry
}),
appearance: this._appearance,
asynchronous: false
}));
} else { return; }
}
}
Cesium.PointsPrimitive = PointsPrimitive
},
/**
* 水面效果
*/
_installWaterPrimitive: function () {
/**
*
* @param {*} options
*/
function WaterPrimitive(options) {
this._positions = opt.positions
this._url = opt.normalMapUrl || 'data/images/Textures/waterNormals.jpg'
this._frequency = opt.frequency || 1000.0
this._animationSpeed = opt.animationSpeed || 0.01
this._amplitude = opt.amplitude || 10.0
this._extrudedHeight = opt.extrudedHeight || 0
this._fs = this.getFS()
}
WaterPrimitive.prototype.build = function () {
this._geometry = this._createGeometry();
this._appearance = this._createAppearence();
this.primitive = this._viewer.scene.primitives.add(new Cesium.Primitive({
allowPicking: false,
geometryInstances: new Cesium.GeometryInstance({
geometry: this._geometry
}),
appearance: this._appearance,
asynchronous: false
}));
}
WaterPrimitive.prototype._createAppearence = function () {
return new Cesium.EllipsoidSurfaceAppearance({
material: new Cesium.Material({
fabric: {
type: 'Water',
uniforms: {
normalMap: this._url,
frequency: this._frequency,
animationSpeed: this._animationSpeed,
amplitude: this._amplitude
}
}
}),
fragmentShaderSource: this._fs
});
}
WaterPrimitive.prototype._createGeometry = function (_degreesArrayHeights, _extrudedHeight) {
return new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(this._positions)),
extrudedHeight: this._extrudedHeight,
perPositionHeight: true
});
}
WaterPrimitive.prototype.getFS = function () {
return 'varying vec3 v_positionMC;\n\
varying vec3 v_positionEC;\n\
varying vec2 v_st;\n\
\n\
void main()\n\
{\n\
czm_materialInput materialInput;\n\
vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n\
#ifdef FACE_FORWARD\n\
normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\
#endif\n\
materialInput.s = v_st.s;\n\
materialInput.st = v_st;\n\
materialInput.str = vec3(v_st, 0.0);\n\
materialInput.normalEC = normalEC;\n\
materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\n\
vec3 positionToEyeEC = -v_positionEC;\n\
materialInput.positionToEyeEC = positionToEyeEC;\n\
czm_material material = czm_getMaterial(materialInput);\n\
#ifdef FLAT\n\
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\
#else\n\
gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\
gl_FragColor.a = 0.5;\n\
#endif\n\
}\n\
';
}
_.prototype.updateDegreesPosition = function (_degreesArrayHeights, _extrudedHeight) {
if (this.primitive != null) {
this._viewer.scene.primitives.remove(this.primitive);
if (_degreesArrayHeights && _degreesArrayHeights.length < 3) { return; }
var geometry = this._createGeometry(_degreesArrayHeights, _extrudedHeight ? _extrudedHeight : 0);
this.primitive = this._viewer.scene.primitives.add(new Cesium.Primitive({
allowPicking: false,
geometryInstances: new Cesium.GeometryInstance({
geometry: geometry
}),
appearance: this._appearance,
asynchronous: false
}));
} else { return; }
}
Cesium.WaterPrimitive = WaterPrimitive
},
/**
* 纹理图 视频图像
*/
_installTexturePrimitive: function () {
/**
*
* @param {*} options
*/
function TexturePrimitive(options) {
this._vertexShader = this.getVS()
this._fragmentShader = this.getFS()
this._materialShader = this.getMS()
this._url = options.url
this._cartesians = options.cartesians
this._id = options.id || ''
}
// 构建
TexturePrimitive.prototype.build = function (opt) {
var postionsTemp = []
, stsTemp = [0, 0, 1, 0, 1, 1, 0, 1] //纹理坐标,调整纹理坐标顺序即可完成贴图的旋转
// var stsTemp = [1,1,0,1,0,0,1,0];
, indicesTesm = [0, 1, 2, 0, 2, 3]; //索引数组
for (var i = 0; i < this._cartesians.length; i++) {
postionsTemp.push(this._cartesians[i].x);
postionsTemp.push(this._cartesians[i].y);
postionsTemp.push(this._cartesians[i].z);
}
this._positionArr = new Float32Array(postionsTemp);
this._sts = new Uint8Array(stsTemp);
this._indiceArr = new Uint16Array(indicesTesm);
//通过坐标数组,索引数组,纹理坐标数组创建多边形
this._geometry = this._createGeometry();
this._appearance = this._createAppearence();
this.primitive = this._viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: this._geometry,
id: this._id
}),
appearance: this._appearance,
asynchronous: false
}));
}
// 生成几何
TexturePrimitive.prototype._createGeometry = function () {
var sess = new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: this._sts
})
return new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: this._positions
}),
st: sess
},
indices: this._indices,//索引指标,指示创建三角形的顺序
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
});
}
//生成外观
TexturePrimitive.prototype._createAppearence = function () {
return new Cesium.Appearance({
material: new Cesium.Material({
fabric: {
uniforms: {
image: this._url
},
source: this._materialShader
}
}),
aboveGround: true,
faceForward: true,
flat: true,
translucent: false,
renderState: {
blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
depthTest: { enabled: true },
depthMask: true,
},
fragmentShaderSource: this._fragmentShader,
vertexShaderSource: this._vertexShader
});
}
TexturePrimitive.prototype.getVS = function () {
return "attribute vec3 position3DHigh;\
attribute vec3 position3DLow;\
attribute vec2 st;\
attribute float batchId;\
varying vec2 v_st;\
void main()\
{\
vec4 p = czm_computePosition();\
v_st=st;\
p = czm_modelViewProjectionRelativeToEye * p;\
gl_Position = p;\
}\
";
}
TexturePrimitive.prototype.getFS = function () {
return "varying vec2 v_st;\
void main()\
{\
czm_materialInput materialInput;\
czm_material material=czm_getMaterial(materialInput,v_st);\
vec4 color=vec4(material.diffuse + material.emission,material.alpha);\
if(color.x==1.0&&color.y==1.0&&color.z==1.0&&color.w==1.0) color=vec4(vec3(0.0,0.0,0.0),0.0);\
gl_FragColor =color;\
}\
";
}
TexturePrimitive.prototype.getMS = function () {
return "czm_material czm_getMaterial(czm_materialInput materialInput,vec2 v_st)\
{\
vec4 color = texture2D(image, v_st);\
czm_material material = czm_getDefaultMaterial(materialInput);\
material.diffuse= color.rgb;\
material.alpha=color.a;\
return material;\
}\
";
}
Cesium.TexturePrimitive = TexturePrimitive
},
/**
* 卫星雷达波
*/
_installProbingPrimitive: function () {
var DEF_OPT = {
color: new Cesium.Color(1.0, 0.0, 1.0, 0.8),
repeat: 30.0,
offset: 0.0,
thickness: 0.3,
center: Cesium.Cartesian3.fromDegrees(116.39, 39.9),
length: 400000.0,
bottom: 1000,
top: 0.0
}
var viewer = this._viewer;
/**
*
* @param {*} option
*/
function ProbingPrimitive(option) {
this._viewer = viewer
this._length = option.length || DEF_OPT.length
this._center = option.center || DEF_OPT.center
this._color = option.color || DEF_OPT.color
this._repeat = option.repeat || DEF_OPT.repeat
this._offset = option.offset || DEF_OPT.offset
this._thickness = option.thickness || DEF_OPT.thickness
this._bottom = option.bottom || DEF_OPT.bottom
this._top = option.top || DEF_OPT.top
this._radar = undefined
this.build()
}
ProbingPrimitive.prototype.build = function () {
var cylinderGeometry = new Cesium.CylinderGeometry({
length: this._length,
topRadius: this._top,
bottomRadius: this._bottom,
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat
}), redCone = new Cesium.GeometryInstance({
geometry: cylinderGeometry,
modelMatrix: this.getModelMatrix(),
}), appearance = new Cesium.MaterialAppearance({
material: this.getMaterial(),
faceForward: false,
closed: true
}), $this = this;
this._radar = this._viewer.scene.primitives.add(
new Cesium.Primitive({
geometryInstances: [redCone],
appearance: appearance
}));
//监听渲染事件 动态修改雷达材质中的offset变量 从而实现动态效果
this._viewer.scene.preUpdate.addEventListener(function () {
var offset = $this._radar.appearance.material.uniforms.offset;
offset -= 0.001;
if (offset > 1.0) {
offset = 0.0;
}
$this._radar.appearance.material.uniforms.offset = offset;
})
}
ProbingPrimitive.prototype.getModelMatrix = function () {
return Cesium.Matrix4.multiplyByTranslation( //转换矩阵
Cesium.Transforms.eastNorthUpToFixedFrame(this._center), //矩阵
new Cesium.Cartesian3(0.0, 0.0, this._length * 0.5), //要转换的笛卡尔坐标
new Cesium.Matrix4() //返回新的矩阵
);
}
ProbingPrimitive.prototype.updateModelMatrix = function (position) {
}
ProbingPrimitive.prototype.getMaterial = function () {
var materialSource = `uniform vec4 color;
uniform float repeat;
uniform float offset;
uniform float thickness;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
float sp = 1.0/repeat;
vec2 st = materialInput.st;
float dis = distance(st, vec2(0.5));
float m = mod(dis + offset, sp);
float a = step(sp*(1.0-thickness), m);
material.diffuse = color.rgb;
material.alpha = a * color.a;
return material;
}`
return new Cesium.Material({
fabric: {
type: 'radarPrimitive',
uniforms: { //动态传递参数
color: this._color,
repeat: this._repeat,
offset: this._offset,
thickness: this._thickness,
},
source: materialSource
},
translucent: false
})
}
ProbingPrimitive.prototype.remove = function () {
if (this._radar) {
this._viewer.scene.primitives.remove(this._radar)
}
}
Cesium.ProbingPrimitive = ProbingPrimitive;
}
}
/**
* 控件模块
* @param {*} viewer
*/
function Control(viewer) {
if (viewer) {
this._installFileDragDropHandler()
}
}
Control.prototype = {
/**
* 拖拽加载
*/
_installFileDragDropHandler() {
function FileDragDropHandler(targetDiv, viewer) {
var dragBox = document.createElement("div");
dragBox.id = 'fileDragDrop'
dragBox.classList.add("filedragdrop");
dragBox.innerHTML = "请将Json文件拖拽到此区域";
this._dragBox = dragBox;
this._viewer = viewer;
this._parentDiv = targetDiv;
targetDiv.appendChild(dragBox);
this.fileDragDropCallBack = undefined;
this.callBackParms = undefined;
}
FileDragDropHandler.prototype.startuploadfile = function () {
var _this = this;
var oBox = _this._dragBox;
var timer = null;
document.ondragover = function () {
clearTimeout(timer);
timer = setTimeout(function () {
// oBox.style.display = 'none';
oBox.innerHTML = '请将文件拖拽到此区域';
}, 200);
// oBox.style.display = 'block';
};
//进入子集的时候 会触发ondragover 频繁触发 不给ondrop机会
oBox.ondragenter = function () {
oBox.innerHTML = '请释放鼠标';
};
oBox.ondragover = function () {
return false;
};
oBox.ondragleave = function () {
oBox.innerHTML = '请将文件拖拽到此区域';
};
oBox.ondrop = function (ev) {
ev.preventDefault();
var oFile = ev.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsText(oFile, "UTF-8");
//读取成功
reader.onload = function () {
var data = JSON.parse(this.result);
if (_this.fileDragDropCallBack) {
//回调函数,callBackParms为回调函数的参数,需要自己传入,data与_this._viewer不需要传入,但是声明的回调函数中要有该参数
_this.fileDragDropCallBack(_this.callBackParms, data, _this._viewer);
}
};
reader.onloadstart = function () {
//alert('读取开始');
};
reader.onloadend = function () {
// alert('读取结束');
};
reader.onabort = function () {
alert('读取数据中断');
};
reader.onerror = function () {
alert('读取数据失败');
};
return false;
};
}
function FileDragDropMixin(viewer) {
var fileDragDropHandler = new FileDragDropHandler(document.querySelector(".cesium-viewer"), viewer);
Object.defineProperties(viewer, {
fileDragDropMixin: {
get: function () {
return fileDragDropHandler;
}
}
});
}
Cesium.FileDragDropMixin = FileDragDropMixin
},
/**
* 加载本地数据
* @param {*} param
*/
showLoadDataToScenePanel(param) {
param = param || {}
if (param) {
let gui = new dat.GUI();
let viewer = this._viewer
let geojson = gui.addFolder('加载数据文件');
let commonUpload = (callback) => {
let inputUpload = document.createElement('input')
inputUpload.type = 'file'
inputUpload.className = 'datgui_upload'
inputUpload.onchange = function () {
if (typeof callback === 'function' && inputUpload.files.length) {
callback(URL.createObjectURL(inputUpload.files[0]))
}
}
document.getElementsByTagName('body') && document.getElementsByTagName('body')[0].appendChild(inputUpload)
inputUpload.click()
}
let geojsonParam = {
'point': () => {
commonUpload((fileData) => {
var promise = Cesium.GeoJsonDataSource.load(fileData);
promise.then(function (dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var o = 0; o < entities.length; o++) {
var r = entities[o];
r.nameID = o;
r.point = { color: Cesium.Color.BLUE }
}
viewer.flyTo(dataSource)
})
})
},
'polyline': () => {
commonUpload((fileData) => {
var promise = Cesium.GeoJsonDataSource.load(fileData);
promise.then(function (dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var o = 0; o < entities.length; o++) {
var r = entities[o];
r.nameID = o;
r.polyline.width = 5;
(r.polyline.material = new Cesium.PolylineGlowMaterialProperty({
glowPower: .1,
color: Cesium.Color.ORANGERED.withAlpha(.9)
}), 10)
}
viewer.flyTo(dataSource)
})
})
},
'polygon': () => {
commonUpload((fileData) => {
var promise = Cesium.GeoJsonDataSource.load(fileData);
promise.then(function (dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var o = 0; o < entities.length; o++) {
var r = entities[o];
r.nameID = o;
r.polygon.width = 10;
r.polygon.material = Cesium.Color.BLUE.withAlpha(.9)
}
viewer.flyTo(dataSource)
})
})
},
'model': () => {
commonUpload((fileData) => {
viewer.flyTo(d3kit.createModelGraphics({
position: Cesium.Cartesian3.fromDegrees(120.38105869, 31.10115627),
m_url: fileData
}))
})
},
'czml': () => {
commonUpload((fileData) => {
viewer.flyTo(viewer.dataSources.add(Cesium.CzmlDataSource.load(fileData)))
})
},
'3dtilset': () => {
commonUpload((fileData) => {
viewer.flyTo(viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: fileData
})))
})
}
}
geojson.add(geojsonParam, "point")
geojson.add(geojsonParam, "polyline")
geojson.add(geojsonParam, "polygon")
geojson.add(geojsonParam, "model")
geojson.add(geojsonParam, "czml")
geojson.add(geojsonParam, "3dtilset")
geojson.open()
}
},
/**
* 后处理面板
* @param {*} param
*/
showPostProcessStagesPanel(param) {
param = param || {}
let Options = function () {
this.blackAndWhiteShow = false
this.blackAndWhiteGradations = 5.0
this.brightnessShow = false
this.brightnessValue = 0.5
this.nightVisionShow = false
this.silhouette = false
}
let option = new Options();
let gui = new dat.GUI();
let viewer = this._viewer
let stages = viewer.scene.postProcessStages;
let silhouette = stages.add(Cesium.PostProcessStageLibrary.createSilhouetteStage());
let blackAndWhite = stages.add(Cesium.PostProcessStageLibrary.createBlackAndWhiteStage());
let brightness = stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage());
let nightVision = stages.add(Cesium.PostProcessStageLibrary.createNightVisionStage());
//config
silhouette.uniforms.color = param.silhouetteColor || Cesium.Color.YELLOW;
silhouette.enabled = false;
blackAndWhite.enabled = false;
blackAndWhite.uniforms.gradations = 5.0;
brightness.enabled = false;
brightness.uniforms.brightness = 0.5;
nightVision.enabled = false;
gui.add(option, 'blackAndWhiteShow').name("blackAndWhiteShow").onChange(function (value) {
blackAndWhite.enabled = value;
})
gui.add(option, 'blackAndWhiteGradations', 0, 10, 0.1).name("blackAndWhiteGradations").onChange(function (value) {
blackAndWhite.uniforms.gradations = value;
})
gui.add(option, 'brightnessShow').name("brightnessShow").onChange(function (value) {
brightness.enabled = value;
})
gui.add(option, 'brightnessValue', 0, 10, 0.1).name("brightnessValue").onChange(function (value) {
brightness.uniforms.brightness = value;
})
gui.add(option, 'nightVisionShow').name("nightVisionShow").onChange(function (value) {
nightVision.enabled = value;
})
gui.add(option, 'silhouette').name("silhouette").onChange(function (value) {
silhouette.enabled = value;
})
},
/**
* 环境控制
* @param {*}
*/
showSceneBloomPanel(param) {
let Options = function () {
this.contrast = 128;
this.brightness = -0.3;
this.delta = 1;
this.gamma = 3.5;
this.enabled = false;
this.highDynamicRange = false;
this.shadows = false;
this.glowOnly = false;
this.sigma = 1.0;
this.stepSize = 5.0;
}
let option = new Options();
let gui = new dat.GUI();
let viewer = this._viewer
gui.__closeButton.innerHTML = "收缩面板";
let bloom = viewer.scene.postProcessStages.bloom;
gui.add(option, 'enabled').name("bloom").onChange(function (value) {
bloom.enabled = value;
})
gui.add(option, 'glowOnly').name("发光").onChange(function (value) {
bloom.uniforms.glowOnly = value;
})
gui.add(option, 'enabled').name("启用模糊").onChange(function (value) {
bloom.enabled = value;
})
gui.add(option, 'contrast', -255.0, 255.0, 0.01).name("对比度").onChange(function (value) {
bloom.uniforms.contrast = value;
})
gui.add(option, 'brightness', -1.0, 1.0, 0.01).name("光泽亮度").onChange(function (value) {
bloom.uniforms.brightness = value;
})
gui.add(option, 'delta', 1, 5, 0.01).name("因子").onChange(function (value) {
bloom.uniforms.delta = value;
})
gui.add(option, 'sigma', 1, 10, 0.01).name("sigma").onChange(function (value) {
bloom.uniforms.sigma = value;
})
gui.add(option, 'stepSize', 0.1, 10).name("stepSize").onChange(function (value) {
bloom.uniforms.stepSize = value;
})
gui.add(option, 'shadows').name("启用阴影").onChange(function (value) {
viewer.shadows = value;
})
gui.add(option, 'highDynamicRange').name("高动态范围").onChange(function (value) {
viewer.scene.highDynamicRange = value;
})
gui.add(option, 'gamma', 1, 10, 0.01).name("伽马亮度").onChange(function (value) {
viewer.scene.gamma = value;
})
},
/**
* 矩阵调整面板
* @param {*} primitives
*/
showPrimitiveMatrixPanel(primitives) {
let primitive = primitives._delegate || primitives, viewer = this._viewer;
function update3dtilesMaxtrix(params) {
//旋转
let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
let rotationY = Cesium.Matrix4.fromRotationTranslation(my);
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
//平移
let position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
let m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
let scale = Cesium.Matrix4.fromUniformScale(0.85);
// //缩放
Cesium.Matrix4.multiply(m, scale, m);
//旋转、平移矩阵相乘
Cesium.Matrix4.multiply(m, rotationX, m);
Cesium.Matrix4.multiply(m, rotationY, m);
Cesium.Matrix4.multiply(m, rotationZ, m);
//赋值给tileset
return m;
}
let gui = new dat.GUI();
//高度
let heightMatrix = {
height: 100
};
let height = gui.addFolder('离地高度');
height.add(heightMatrix, "height", 0, 1000, 1).onChange(function (value) {
var boundingSphere = primitives.boundingSphere;
var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, value);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
primitives.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
});
height.open()
//缩放矩阵
let scale = gui.addFolder('缩放大小');
let scaleParam = {
'm+Scale': () => {
primitive.readyPromise.then(data => {
let modelMatrix = data.root.transform
Cesium.Matrix4.multiplyByUniformScale(modelMatrix, 1.2, modelMatrix);
data.root.transform = modelMatrix
});
},
'm-Scale': () => {
primitive.readyPromise.then(data => {
let modelMatrix = data.root.transform
Cesium.Matrix4.multiplyByUniformScale(modelMatrix, 0.8, modelMatrix);
data.root.transform = modelMatrix
});
}
}
scale.add(scaleParam, "m+Scale")
scale.add(scaleParam, "m-Scale")
scale.open()
let translationMatrix = {
x: 0,
y: 0,
z: 0
}
//平移矩阵
let translationParam = {
'x+Axis': () => {
translationMatrix.x += 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(20, 0, 0))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
},
'x-Axis': () => {
translationMatrix.x -= 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(-20, 0, 0))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
},
'y+Axis': () => {
translationMatrix.y += 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 20, 0))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
},
'y-Axis': () => {
translationMatrix.y -= 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, -20, 0))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
},
'z+Axis': () => {
translationMatrix.z += 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 0, 20))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
},
'z-Axis': () => {
translationMatrix.z -= 1
const translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 0, -20))
Cesium.Matrix4.multiply(primitive.modelMatrix, translation, primitive.modelMatrix)
}
};
let translation = gui.addFolder('矩阵平移');
translation.add(translationParam, "x+Axis")
translation.add(translationParam, "x-Axis")
translation.add(translationParam, "y+Axis")
translation.add(translationParam, "y-Axis")
translation.add(translationParam, "z+Axis")
translation.add(translationParam, "z-Axis")
translation.open()
//旋转矩阵
let rotationMatrix = {
x: 0,
y: 0,
z: 0
};
let rotationParam = {
'x+Axis': () => {
rotationMatrix.x += 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotationMatrix.x))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
// const rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotationMatrix.x)))
// const rotationY = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotationMatrix.y)))
// const rotationZ = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotationMatrix.z)))
// Cesium.Matrix4.multiply(m, rotationX, m);
// Cesium.Matrix4.multiply(m, rotationY, m);
// Cesium.Matrix4.multiply(m, rotationZ, m);
data._root.transform = m
})
},
'x-Axis': () => {
rotationMatrix.x -= 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotationMatrix.x))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
data._root.transform = m
})
},
'y+Axis': () => {
rotationMatrix.y += 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotationMatrix.y))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
data._root.transform = m
})
},
'y-Axis': () => {
rotationMatrix.y -= 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotationMatrix.y))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
data._root.transform = m
})
},
'z+Axis': () => {
rotationMatrix.z += 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotationMatrix.z))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
data._root.transform = m
})
},
'z-Axis': () => {
rotationMatrix.z -= 15
primitive.readyPromise.then(data => {
const angel = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotationMatrix.z))
const rotation = Cesium.Matrix4.fromRotationTranslation(angel)
const m = Cesium.Transforms.eastNorthUpToFixedFrame(data.boundingSphere.center);
Cesium.Matrix4.multiply(m, rotation, m)
data._root.transform = m
})
}
}
let rotation = gui.addFolder('旋转矩阵');
rotation.add(rotationParam, "x+Axis")
rotation.add(rotationParam, "x-Axis")
rotation.add(rotationParam, "y+Axis")
rotation.add(rotationParam, "y-Axis")
rotation.add(rotationParam, "z+Axis")
rotation.add(rotationParam, "z-Axis")
rotation.open()
gui.__closeButton.innerHTML = "收缩面板";
},
/**
* 图层参数调整
* @param {*} options
*/
showLayerParamPanel: function (layer) {
if (layer) {
var gui = new dat.GUI()
var layerObj = new function () {
this.alpha = layer.alpha
this.brightness = layer.brightness
this.contrast = layer.contrast
this.gamma = layer.gamma
this.hue = layer.hue
this.dayAlpha = layer.dayAlpha
this.nightAlpha = layer.nightAlpha
this.saturation = layer.saturation
};
var layerParam = gui.addFolder('图层调整')
layerParam.add(layerObj, 'alpha', 0, 1, 0.05).name('透明度').onChange(function (value) {
layer.alpha = value
});
layerParam.add(layerObj, 'brightness', 0, 5, 0.05).name('亮度').onChange(function (value) {
layer.brightness = value
});
layerParam.add(layerObj, 'contrast', 0, 5, 0.05).name('对比').onChange(function (value) {
layer.contrast = value
});
layerParam.add(layerObj, 'gamma', 0, 5, 0.05).name('伽马').onChange(function (value) {
layer.gamma = value
});
layerParam.add(layerObj, 'hue', 0, 5, 0.05).name('色调').onChange(function (value) {
layer.hue = value
});
layerParam.add(layerObj, 'dayAlpha', 0, 1, 0.05).name('白天透明').onChange(function (value) {
layer.dayAlpha = value
});
layerParam.add(layerObj, 'nightAlpha', 0, 1, 0.05).name('夜晚透明').onChange(function (value) {
layer.nightAlpha = value
});
layerParam.add(layerObj, 'saturation', 0, 5, 0.05).name('饱和').onChange(function (value) {
layer.saturation = value
});
layerParam.open()
}
},
/**
* 图层切换
* @param {*} options
*/
showLayerSwitchPanel: function (layers) {
if (layers && layers.length) {
var gui = new dat.GUI()
var layerObj = new function () {
for (let i in layers) {
this[layers[i].id] = layers[i].show
}
};
var layerSwitch = gui.addFolder('图层切换')
for (let i in layers) {
layerSwitch.add(layerObj, layers[i].id).name(layers[i].name).onChange(function (value) {
layers[i].show = value
});
}
var layerAlphaObj = new function () {
for (let i in layers) {
this[layers[i].id] = layers[i].alpha
}
};
var layerAlpha = gui.addFolder('透明度')
for (let i in layers) {
layerAlpha.add(layerAlphaObj, layers[i].id, 0, 1, 0.05).name(layers[i].name).onChange(function (value) {
layers[i].alpha = value
});
}
layerSwitch.open()
layerAlpha.open()
}
},
/**
* 场景效果调整面板
* @param {*} opt
*/
showSceneEffectEditPanel: function (options) {
options = options || {}
if (dat.GUI && this._viewer.scene.colorCorrection) {
var gui = new dat.GUI(), viewer = this._viewer;
/**
* 初始化场景
*/
//设置环境光
viewer.scene.lightSource.ambientLightColor = options.ambientLightColor || new Cesium.Color(0.3, 0.3, 0.3, 1);
//开启颜色校正
viewer.scene.colorCorrection.show = options.colorCorrection || false;
viewer.scene.colorCorrection.saturation = options.saturation || 3.1;
viewer.scene.colorCorrection.brightness = options.brightness || 1.8;
viewer.scene.colorCorrection.contrast = options.contrast || 1.2;
viewer.scene.colorCorrection.hue = options.hue || 0;
//开启泛光和HDR
viewer.scene.bloomEffect.show = options.bloomEffect || false;
viewer.scene.hdrEnabled = options.hdrEnabled || true;
viewer.scene.bloomEffect.threshold = options.threshold || 1;
viewer.scene.bloomEffect.bloomIntensity = options.bloomIntensity || 2;
/**
* 初始化dat
*/
var sceneObj = new function () {
//泛光开关
this.bloomEffectShow = options.bloomEffect || false
//泛光阈值
this.bloomThreshold = options.threshold || 1
//泛光强度
this.bloomIntensity = options.bloomIntensity || 2
//环境光
this.ambientLightColor = options.ambientLightColor || 0.3
//HDR开关
this.hdrEnabled = options.hdrEnabled || true
//颜色校正
this.colorCorrectionShow = false
//饱和度
this.colorCorrectionSaturation = options.saturation || 3.1
//亮度
this.colorCorrectionBrightness = options.brightness || 1.8
//对比度
this.colorCorrectionContrast = options.contrast || 1.2
//色调
this.colorCorrectionHue = options.hue || 0
};
var sceneEffect = gui.addFolder('场景效果')
sceneEffect.add(sceneObj, 'bloomEffectShow').name('泛光开关').onChange(function (value) {
viewer.scene.bloomEffect.show = value;
viewer.scene.bloomEffect.threshold = sceneObj.bloomThreshold;
viewer.scene.bloomEffect.bloomIntensity = sceneObj.bloomIntensity;
});
sceneEffect.add(sceneObj, 'bloomThreshold', 0, 1, 0.1).name('泛光阈值').onChange(function (value) {
viewer.scene.bloomEffect.threshold = value;
});
sceneEffect.add(sceneObj, 'bloomIntensity', 0, 10, 0.1).name('泛光强度').onChange(function (value) {
viewer.scene.bloomEffect.bloomIntensity = value;
});
sceneEffect.add(sceneObj, 'hdrEnabled').name('HDR开关').onChange(function (value) {
viewer.scene.hdrEnabled = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionShow').name('颜色校正').onChange(function (value) {
viewer.scene.colorCorrection.show = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionSaturation', 0, 5, 0.1).name('饱和度').onChange(function (value) {
viewer.scene.colorCorrection.saturation = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionBrightness', 0, 5, 0.1).name('亮度').onChange(function (value) {
viewer.scene.colorCorrection.brightness = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionContrast', 0, 5, 0.1).name('对比度').onChange(function (value) {
viewer.scene.colorCorrection.contrast = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionHue', 0, 5, 0.1).name('色调').onChange(function (value) {
viewer.scene.hdrEnabled = value;
});
sceneEffect.add(sceneObj, 'colorCorrectionHue', 0, 1, 0.1).name('环境光').onChange(function (value) {
viewer.scene.lightSource.ambientLightColor = new Cesium.Color(value, value, value, 1);
});
sceneEffect.open()
}
},
/**
* 位置姿态编辑面板啊
* @param {*} Entity
*/
showEntityOrientationEditPanel: function (Entity) {
if (Entity) {
var gui = new dat.GUI()
var OrientationObj = new function () {
this.heading = 360
this.pitch = 1
this.roll = 1
};
var Orientation = gui.addFolder('实体姿态调整'), $this = this;
Orientation.add(OrientationObj, 'heading', 0, 360, 1).name('角度').onChange(function (value) {
OrientationObj.heading = value
Entity.orientation =
Cesium.Transforms.headingPitchRollQuaternion(
Entity.position.getValue($this._viewer.clock.currentTime),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(OrientationObj.heading),
Cesium.Math.toRadians(OrientationObj.pitch),
Cesium.Math.toRadians(OrientationObj.roll)
))
});
Orientation.add(OrientationObj, 'pitch', 0, 360, 1).name('航向').onChange(function (value) {
OrientationObj.pitch = value
Entity.orientation =
Cesium.Transforms.headingPitchRollQuaternion(
Entity.position.getValue($this._viewer.clock.currentTime),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(OrientationObj.heading),
Cesium.Math.toRadians(OrientationObj.pitch),
Cesium.Math.toRadians(OrientationObj.roll)
))
});
Orientation.add(OrientationObj, 'roll', 0, 360, 1).name('翻转').onChange(function (value) {
OrientationObj.roll = value
Entity.orientation =
Cesium.Transforms.headingPitchRollQuaternion(
Entity.position.getValue($this._viewer.clock.currentTime),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(OrientationObj.heading),
Cesium.Math.toRadians(OrientationObj.pitch),
Cesium.Math.toRadians(OrientationObj.roll)
))
});
Orientation.open()
}
}
}
/**
* 基于three的融合
*
* cesium 需要关闭自带的循环渲染
* useDefaultRenderLoop: false
* @param {*} viewer
*/
function ThreeJs(viewer) {
if (viewer) {
this._initContainer()
this._initThree()
}
}
ThreeJs.prototype = {
/**
* 初始化容器
*/
_initContainer: function () {
this.cesiumContainer = undefined
this.threeContainer = undefined
this.cesiumContainer = document.getElementById('cesiumContainer')
this.threeContainer = document.getElementById('threeContainer')
//元素都已经创建默认集成
if (this.cesiumContainer && this.threeContainer) {
return false
}
if (!this.cesiumContainer) {
alert('未获取到 cesiumContainer 容器!')
return false
} else {
//是否符合
if (this.cesiumContainer.style.position !== 'absolute') {
// 重写样式
this.cesiumContainer.style.position = 'absolute'
this.cesiumContainer.style.top = 0
this.cesiumContainer.style.left = 0
this.cesiumContainer.style.height = '100%'
this.cesiumContainer.style.width = '100%'
this.cesiumContainer.style.margin = 0
this.cesiumContainer.style.overflow = 'hidden'
this.cesiumContainer.style.padding = 0
this.cesiumContainer.style.fontFamily = 'sans-serif'
}
}
//no create
if (!this.threeContainer) {
var body = document.getElementsByTagName('body')[0];
if (body) {
this.threeContainer = document.createElement('div')
this.threeContainer.id = 'threeContainer'
this.threeContainer.style.position = 'absolute'
this.threeContainer.style.top = 0
this.threeContainer.style.left = 0
this.threeContainer.style.height = '100%'
this.threeContainer.style.width = '100%'
this.threeContainer.style.margin = 0
this.threeContainer.style.overflow = 'hidden'
this.threeContainer.style.padding = 0
this.threeContainer.style.fontFamily = 'sans-serif'
this.threeContainer.style.pointerEvents = 'none'
body.appendChild(this.threeContainer)
}
}
},
/**
* 初始化three
*/
_initThree: function () {
var fov = 45,
width = window.innerWidth,
height = window.innerHeight,
aspect = width / height,
near = 1,
far = 10 * 1000 * 1000;
this._three = {
renderer: null,
camera: null,
scene: null
}
this._three.scene = new THREE.Scene();
this._three.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
this._three.renderer = new THREE.WebGLRenderer({ alpha: true });
if (this.threeContainer) {
this.threeContainer.appendChild(this._three.renderer.domElement);
}
},
/**
* threeObjects 对象
*
* 用于实例化到cesium球上
*/
createThreeObject: function () {
function _3DObject() {
this.threeMesh = null;
this.minWGS84 = null;
this.maxWGS84 = null;
}
return new _3DObject()
},
/**
* 添加three obj对象
*/
addThreeObjects: function (objects) {
if (objects && objects.length > 0) {
this._3Dobjects = objects;
//注册
this._renderCesium()
this._renderThreeObj()
this._loop()
}
},
/**
* 开始渲染cesium和three
*/
_loop: function () {
window.loop = function () {
//循环渲染
requestAnimationFrame(loop)
//渲染cesium
renderCesium()
//渲染three
renderThreeObj()
}
loop()
},
/**
* 渲染cesium
*/
_renderCesium: function () {
var $this = this
window.renderCesium = function () {
$this._viewer && $this._viewer.render()
}
},
/**
* 渲染three
*/
_renderThreeObj: function () {
var $this = this
window.renderThreeObj = function () {
var cartToVec = function (cart) {
return new THREE.Vector3(cart.x, cart.y, cart.z);
};
if ($this._three && $this._viewer && $this._3Dobjects) {
//同步相机事件
$this._three.camera.fov = Cesium.Math.toDegrees($this._viewer.camera.frustum.fovy)
$this._three.camera.updateProjectionMatrix();
// 同步位置 Configure Three.js meshes to stand against globe center position up direction
for (var id in $this._3Dobjects) {
var minWGS84 = $this._3Dobjects[id].minWGS84,
maxWGS84 = $this._3Dobjects[id].maxWGS84,
// convert lat/long center position to Cartesian3
center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2),
// get forward direction for orienting model
centerHigh = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2, 1);
// use direction from bottom left to top left as up-vector
var bottomLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], minWGS84[1]));
var topLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], maxWGS84[1]));
var latDir = new THREE.Vector3().subVectors(bottomLeft, topLeft).normalize();
// configure entity position and orientation
$this._3Dobjects[id].threeMesh.position.copy(center);
$this._3Dobjects[id].threeMesh.lookAt(centerHigh);
$this._3Dobjects[id].threeMesh.up.copy(latDir);
}
// Clone Cesium Camera projection position so the
// Three.js Object will appear to be at the same place as above the Cesium Globe
$this._three.camera.matrixAutoUpdate = false;
var cvm = $this._viewer.camera.viewMatrix,
civm = $this._viewer.camera.inverseViewMatrix;
$this._three.camera.matrixWorld.set(
civm[0], civm[4], civm[8], civm[12],
civm[1], civm[5], civm[9], civm[13],
civm[2], civm[6], civm[10], civm[14],
civm[3], civm[7], civm[11], civm[15]
);
$this._three.camera.matrixWorldInverse.set(
cvm[0], cvm[4], cvm[8], cvm[12],
cvm[1], cvm[5], cvm[9], cvm[13],
cvm[2], cvm[6], cvm[10], cvm[14],
cvm[3], cvm[7], cvm[11], cvm[15]
);
$this._three.camera.lookAt(new THREE.Vector3(0, 0, 0));
var width = $this.threeContainer.clientWidth,
height = $this.threeContainer.clientHeight,
aspect = width / height;
$this._three.camera.aspect = aspect;
$this._three.camera.updateProjectionMatrix();
$this._three.renderer.setSize(width, height);
$this._three.renderer.render($this._three.scene, $this._three.camera);
}
}
}
}
/**
* @description D3Kit 拓展包
*
* 分析模块
* @param {*} viewer
*/
function Analysis(viewer) {
if (viewer) {
this._analysisLayer = new Cesium.CustomDataSource('analysisLayer')
viewer && viewer.dataSources.add(this._analysisLayer)
}
}
Analysis.prototype = {
/**
* 创建通视分析
* @param {*} options
*/
createVisibilityAnalysis: function (options) {
options = options || {}
var $this = this
$this.drawLineGraphics({
type: 'straightLine',
clampToGround: false,
callback: function (line, lineObj) {
var _visibilityAnalysis = new VisibilityAnalysis({ positions: line, that: $this })
if ($this._graphicsLayer) $this._graphicsLayer.entities.remove(lineObj)
if (typeof options.callback === 'function') {
options.callback(_visibilityAnalysis)
}
}
})
},
/**
* 创建环视分析
* @param {*} options
*/
createLookAroundAnalysis: function (options) {
options = options || {}
if (this._viewer && options) {
var $this = this;
$this.drawCircleGraphics({
callback: function (result, obj) {
$this._drawLayer.entities.remove(obj)
let _lookAroundAnalysis = new LookAroundAnalysis({ that: $this, radius: result.radius, center: result.center })
if (typeof options.callback === 'function') {
options.callback(_lookAroundAnalysis);
}
}
})
}
},
/**
* 创建可视域分析
* @param {*} options
*/
createVisualFieldAnalysis: function (options) {
options = options || {}
if (this._viewer && options) {
var $this = this, _shadowPrimitive = null;
$this.bindHandelEvent(
function click(event, _handlers) {
var position = $this._viewer.scene.pickPosition(event.position);
if (!position) return false
if (!Cesium.defined(_shadowPrimitive)) {
// 创建shadowPrimitve
_shadowPrimitive = new Cesium.ShadowPrimitive({
scene: $this._viewer.scene,
viewerPosition: position
});
$this._analysisLayer._primitives.add(_shadowPrimitive);
} else {
_handlers.destroy()
_handlers = null
}
},
function move(event) {
var position = $this._viewer.scene.pickPosition(event.endPosition);
if (!position) return false
if (_shadowPrimitive) _shadowPrimitive.setPoseByTargetPoint(position);
})
}
},
/**
* 地形开挖分析
* @param {*} options
*/
createClipPlanAnalysis: function (options) {
options = options || {}
if (this._viewer && options) {
var $this = this;
var _height = options.height || 30,
_splitNum = options.splitNum || 50,
_wallImg = options.wallImg || "data/images/excavate_side_min.jpg",
_bottomImg = options.bottomImg || "data/images/excavate_bottom_min.jpg";
$this.drawPolygonGraphics({
callback: function (polygon, polygonObj) {
$this._drawLayer.entities.remove(polygonObj)
let terrainClipPlan = new Cesium.TerrainClipPlan($this._viewer, {
height: _height,
splitNum: _splitNum,
wallImg: _wallImg,
bottomImg: _bottomImg
})
terrainClipPlan.updateData($this.transformWGS84ArrayToCartesianArray(polygon))
if (typeof options.callback === 'function') {
options.callback(terrainClipPlan);
}
}
})
}
},
/**
* 创建淹没分析
* @param {*} options
*/
createSubmergedAnalysis: function (options) {
options = options || {}
if (this._viewer && options) {
var $this = this,
_maxH = options.maxH || 15,
_speed = options.speed || 1,
_interval = options.interval || 10;
$this.drawPolygonGraphics({
height: 1,
callback: function (polygon, polygonObj) {
if (!$this._viewer.scene.globe.depthTestAgainstTerrain) {
alert('请开启深度检测')
return false;
}
if (polygonObj) {
setTimeout(() => {
polygonObj.polygon.heightReference = "CLAMP_TO_GROUND";
polygonObj.polygon.material = "data/images/water.png";
var h = 0.0;
polygonObj.polygon.extrudedHeight = h;
var st = setInterval(function () {
h = h + _speed;
if (h >= _maxH) {
h = _maxH;
clearTimeout(st);
}
polygonObj.polygon.extrudedHeight = h;
}, _interval);
}, 2000);
}
}
})
}
},
/**
* 创建坡度分析
* @param {*} options
*/
createSlopeAnalysis: function (options) {
options = options || {}
if (!echarts) {
alert('需要引入echarts库')
return false;
}
if (this._viewer && options) {
$this.drawLineGraphics({
type: 'straightLine',
clampToGround: false,
callback: function (line, lineObj) {
var _slopeAnalysis = new SlopeAnalysis({ positions: line, that: $this })
if ($this._graphicsLayer) $this._graphicsLayer.entities.remove(lineObj)
if (typeof options.callback === 'function') {
options.callback(_slopeAnalysis)
}
}
})
}
},
/**
* 方量分析
* @param {*} options
*/
createCutVolumeAnalysis: function (options) {
options = options || {}
if (this._viewer && options) {
var $this = this;
$this.drawWallGraphics({
callback: function (wall, wallobj) {
var _cutVolumeAnalysis = new CutVolumeAnalysis({
positions: $this.transformWGS84ArrayToCartesianArray(wall, 100),
that: $this
})
if (typeof options.callback === 'function') {
options.callback(_cutVolumeAnalysis)
}
}
})
}
}
}
/**
* 通视分析
* @param {*} params
*/
function VisibilityAnalysis(params) {
if (params && params.positions) {
var positions = params.positions, that = params.that, points = [], lines = [], pickedObjs = [],
position1 = that.transformWGS84ToCartesian(positions[0]), position2 = that.transformWGS84ToCartesian(positions[1]);
points = that.createPointsGraphics({
point: true,
positions: [position1, position2]
})
var results = that.getIntersectObj(position1, position2, points, true); //碰撞检测
if (results.length === 0) {
alert("没有取到相交点 , 请检查是否开启深度检测。")
return false
}
//显示相交对象 高亮
function showIntersections() {
for (let i = 0; i < results.length; ++i) {
var object = results[i].object;
if (object) {
if (object instanceof Cesium.Cesium3DTileFeature) {
pickedObjs.push(object);
object.oldColor = object.color.clone();
object.color = Cesium.Color.fromAlpha(Cesium.Color.YELLOW, object.color.alpha);
} else if (object.id instanceof Cesium.Entity) {
var entity = object.id;
pickedObjs.push(entity);
var color = entity.polygon.material.color.getValue();
entity.polygon.oldColor = color.clone();
entity.polygon.material = Cesium.Color.fromAlpha(Cesium.Color.YELLOW, color.alpha);
}
}
//相交点
points.push(that._analysisLayer.entities.add({
position: results[i].position,
ellipsoid: {
radii: new Cesium.Cartesian3(0.8, 0.8, 0.8),
material: Cesium.Color.RED
}
}));
}
}
// 计算分析结果
function computesResult() {
//分析一下是否都有position
for (let index = results.length - 1; index >= 0; index--) {
const element = results[index];
if (!Cesium.defined(element.position)) {
results.splice(index, 1);
}
}
if (!Cesium.defined(results[0].position)) {
throw new Cesium.DeveloperError("position is undefined");
}
var pickPos1 = results[0].position;
var dis = Cesium.Cartesian3.distance(pickPos1, position2);
var bVisibility = dis < 5 ? true : false; //
var arrowPositions = [position1, results[0].position];
//通视线
var greenLine = that._analysisLayer.entities.add({
polyline: {
positions: arrowPositions,
width: 10,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.GREEN)
}
});
lines.push(greenLine);
//不通视
if (!bVisibility) {
var unArrowPositions = [results[0].position, position2];
var redLine = that._analysisLayer.entities.add({
polyline: {
positions: unArrowPositions,
width: 10,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)
}
});
lines.push(redLine);
}
showIntersections()
var rad1 = Cesium.Cartographic.fromCartesian(position1);
var rad2 = Cesium.Cartographic.fromCartesian(position2);
var degree1 = { longitude: rad1.longitude / Math.PI * 180, latitude: rad1.latitude / Math.PI * 180, height: rad1.height };
var degree2 = { longitude: rad2.longitude / Math.PI * 180, latitude: rad2.latitude / Math.PI * 180, height: rad2.height };
var length_ping = Math.sqrt(Math.pow(position1.x - position2.x, 2) + Math.pow(position1.y - position2.y, 2) + Math.pow(position1.z - position2.z, 2));
var length_h = Math.abs(degree2.height - degree1.height);
var length = Math.sqrt(Math.pow(length_ping, 2) + Math.pow(length_h, 2));
var visTxt = bVisibility ? '是' : '否';
var text =
'起点坐标: ' + (' (' + degree1.longitude.toFixed(6)) + '\u00B0' + ',' + (degree1.latitude.toFixed(6)) + '\u00B0' + ',' + degree1.height.toFixed(2) + ')' +
'\n终点坐标: ' + (' (' + degree2.longitude.toFixed(6)) + '\u00B0' + ',' + (degree2.latitude.toFixed(6)) + '\u00B0' + ',' + degree2.height.toFixed(2) + ')' +
'\n垂直距离: ' + ' ' + length_h.toFixed(2) + 'm' +
'\n水平距离: ' + ' ' + length_ping.toFixed(2) + 'm' +
'\n空间距离: ' + ' ' + length.toFixed(2) + 'm' +
'\n是否可视: ' + ' ' + visTxt;
if (points && points[0]) {
points[0].label = {
text: text,
showBackground: true,
font: '14px monospace',
fillColor: Cesium.Color.YELLOW,
pixelOffset: { x: 0, y: -20 },
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT
}
}
}
computesResult() // 计算相交结果
}
VisibilityAnalysis.prototype.remove = function () { }
}
/**
* 环视分析
* @param {*} params
*/
function LookAroundAnalysis(params) {
if (!params && !params.center && !params.radius && params.that) {
alert('没有获取到分析参数')
return false;
}
var that = params.that, $this = this;
if (!that._viewer.scene.globe.depthTestAgainstTerrain) {
alert('请开启深度检测')
return false;
}
var viewHeight = params.viewHeight || 10
var cartographicCenter = Cesium.Cartographic.fromCartesian(params.center);
// 分析
try {
var ab = params.radius;
var eopt = {};
eopt.semiMinorAxis = ab;
eopt.semiMajorAxis = ab;
eopt.rotation = 0;
eopt.center = params.center;
eopt.granularity = Math.PI / 45.0;//间隔
let ellipse = that.computeEllipseEdgePositions(eopt); //范围当前椭圆位置的数组
for (let i = 0; i < ellipse.outerPositions.length; i += 3) {
//逐条计算可视域
let cartesian = new Cesium.Cartesian3(ellipse.outerPositions[i], ellipse.outerPositions[i + 1], ellipse.outerPositions[i + 2]);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
let deltaRadian = 0.00005 * Math.PI / 180.0; //Cesium.Math.RADIANS_PER_DEGREE
let cartographicArr = that.computeInterpolateLineCartographic(cartographicCenter, cartographic, deltaRadian);
that.computeCartographicPointsTerrainData(cartographicArr,
function (terrainData) {
if (terrainData.length > 0) {
let preVisible = true;
let cartesiansLine = [];
let colors = [];
for (let j = 1; j < terrainData.length; j++) {
//逐点计算可见性
let visible = true;//该点可见性
if (j > 1) {
let cartographicCenterHV = new Cesium.Cartographic(terrainData[0].longitude, terrainData[0].latitude, terrainData[0].height + viewHeight);
if (preVisible) {
//
let curPoint = that.computeInterpolateIndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
if (curPoint.height >= terrainData[j - 1].height) {
preVisible = true;
visible = true;
} else {
preVisible = false;
visible = false;
}
} else {
//插值到当前
let curPointArr = that.computeInterpolateIndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
for (let k = 0; k < curPointArr.length; k++) {
if (curPointArr[k].height >= terrainData[k].height) {
preVisible = true;
visible = true;
} else {
preVisible = false;
visible = false;
break;
}
}
}
}
let cartesianTemp = Cesium.Cartesian3.fromRadians(terrainData[j].longitude, terrainData[j].latitude, terrainData[j].height + 1);
cartesiansLine.push(cartesianTemp);
//绘制点
if (visible) {
colors.push(0);
colors.push(0);
colors.push(1);
colors.push(1);
} else {
colors.push(1);
colors.push(0);
colors.push(0);
colors.push(1);
}
}
//绘制结果
$this._pointsKSYResult = new Cesium.PointsPrimitive({ 'viewer': that._viewer, 'Cartesians': cartesiansLine, 'Colors': colors });
} else { alert("高程异常!"); }
});
}
} catch (error) {
console.log(error);
}
LookAroundAnalysis.prototype.remove = function () { }
}
/**
* 坡度分析
* @param {*} params
*/
function SlopeAnalysis(params) {
if (params && params.positions) {
var positions = params.positions, that = params.that, points = [],
position1 = that.transformWGS84ToCartesian(positions[0]), position2 = that.transformWGS84ToCartesian(positions[1]);
points = that.createPointsGraphics({
point: true,
positions: [position1, position2]
})
//显示结果
function showResult(startPoint, endPoint) {
//起止点相关信息
var scartographic = Cesium.Cartographic.fromCartesian(startPoint);
var samplePoint = [scartographic];
var pointSum = 10; //取样点个数
var tempCartesians = new Cesium.Cartesian3();
var slopePercent = [0];
var disL = [0];
var angle = 0;
for (var i = 1; i <= pointSum; i++) {
Cesium.Cartesian3.lerp(startPoint, endPoint, i / pointSum, tempCartesians);
var tempCartographic = Cesium.Cartographic.fromCartesian(tempCartesians);
var surfaceHeight = $this._viewer.scene.globe.getHeight(tempCartographic);
tempCartographic.height = surfaceHeight;
samplePoint.push(tempCartographic);
var lastCarto = samplePoint[i - 1];
var dis = Cesium.Cartesian3.distance(Cesium.Cartographic.toCartesian(lastCarto), Cesium.Cartographic.toCartesian(tempCartographic));
disL.push(disL[i - 1] + dis);
angle = Math.asin((tempCartographic.height - lastCarto.height) / dis);
slopePercent.push(Math.tan(angle) * 100);
}
var echartContainer = document.createElement('div');
echartContainer.className = 'echart-viewer';
$this._viewer.container.appendChild(echartContainer, 'dark', {
renderer: 'canvas',
width: 640,
height: 480
});
echartContainer.style.position = "absolute";
echartContainer.style.right = '140px';
echartContainer.style.top = '100px';
echartContainer.style.height = '300px';
echartContainer.style.width = '640px';
echartContainer.style.overflow = "hidden";
echartContainer.style.zIndex = "9999";
echartContainer.style.opacity = 0.9;
var myChart = echarts.init(echartContainer);
var option = {
title: {
text: '剖面示意图',
left: 'center',
subtext: '',
textStyle: {
color: 'white',
fontSize: 15
}
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['']
},
//右上角工具条
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: 'category',
name: "长度(米)",
boundaryGap: false,
data: disL,
axisLabel: {
textStyle: {
color: 'white'
}
},
axisLine: {
lineStyle: {
color: "white"
}
}
}
],
yAxis: [
{
type: 'value',
name: "坡度(%)",
axisLabel: {
formatter: function (data) { return data.toFixed(2) + "%"; },
// formatter: '{value} 米',
textStyle: {
color: 'white'
}
},
axisLine: {
lineStyle: {
color: "white"
}
}
}
],
series: [
{
name: '坡度',
type: 'line',
areaStyle: {},
smooth: true,
data: slopePercent,
markPoint: {
data: [
{ type: 'max', name: '最大值' },
{ type: 'min', name: '最小值' }
]
},
markLine: {
data: [
{ type: 'average', name: '平均值' }
]
}
}
]
};
// 为echarts对象加载数据
myChart.setOption(option);
return myChart;
}
}
showResult(points[0], points[1])
}
/**
* 方量分析
* @param {*} params
*/
function CutVolumeAnalysis(params) {
if (params && params.positions && params.that) {
var that = params.that, positions = params.positions
, _debugShowSubTriangles = true, $this = this;
computeCutVolume()
}
/**
* 计算多边形的重心点
* @param {*} positions
*/
function computeCentroidOfPolygon(positions) {
var x = [];
var y = [];
for (var i = 0; i < positions.length; i++) {
var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
x.push(cartographic.longitude);
y.push(cartographic.latitude);
}
var x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0;
var signedArea = 0.0;
var a = 0.0;
var centroidx = 0.0, centroidy = 0.0;
for (i = 0; i < positions.length; i++) {
x0 = x[i];
y0 = y[i];
if (i == positions.length - 1) {
x1 = x[0];
y1 = y[0];
} else {
x1 = x[i + 1];
y1 = y[i + 1];
}
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidx += (x0 + x1) * a;
centroidy += (y0 + y1) * a;
}
signedArea *= 0.5;
centroidx /= (6.0 * signedArea);
centroidy /= (6.0 * signedArea);
return new Cesium.Cartographic(centroidx, centroidy);
}
/**
* 计算三角形的面积
* @param {*} pos1
* @param {*} pos2
* @param {*} pos3
*/
function computeAreaOfTriangle(pos1, pos2, pos3) {
var a = Cesium.Cartesian3.distance(pos1, pos2);
var b = Cesium.Cartesian3.distance(pos2, pos3);
var c = Cesium.Cartesian3.distance(pos3, pos1);
var S = (a + b + c) / 2;
return Math.sqrt(S * (S - a) * (S - b) * (S - c));
}
/**
* 计算方量
*/
function computeCutVolume() {
var tileAvailability = that._viewer.terrainProvider.availability;
if (!tileAvailability) {
alert("未获取到地形")
return false;
}
var maxLevel = 0;
var minHeight = 15000;
// 计算差值点
for (var i = 0; i < positions.length; i++) {
var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
var height = that._viewer.scene.globe.getHeight(cartographic);
if (minHeight > height)
minHeight = height;
var level = tileAvailability.computeMaximumLevelAtPosition(cartographic);
if (maxLevel < level)
maxLevel = level;
}
var granularity = Math.PI / Math.pow(2, 11);
granularity = granularity / (64);
var polygonGeometry = new Cesium.PolygonGeometry.fromPositions(
{
positions: positions,
vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
granularity: granularity
}
);
//polygon subdivision
var geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);
var totalCutVolume = 0;
var maxHeight = 0;
var i0, i1, i2;
var height1, height2, height3;
var p1, p2, p3;
var bottomP1, bottomP2, bottomP3;
var scratchCartesian = new Cesium.Cartesian3();
var cartographic;
var bottomArea;
var subTrianglePositions;
for (i = 0; i < geom.indices.length; i += 3) {
i0 = geom.indices[i];
i1 = geom.indices[i + 1];
i2 = geom.indices[i + 2];
subTrianglePositions = geom.attributes.position.values;
scratchCartesian.x = subTrianglePositions[i0 * 3];
scratchCartesian.y = subTrianglePositions[i0 * 3 + 1];
scratchCartesian.z = subTrianglePositions[i0 * 3 + 2];
cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);
height1 = that._viewer.scene.globe.getHeight(cartographic);
p1 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height1);
bottomP1 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
if (maxHeight < height1)
maxHeight = height1;
scratchCartesian.x = subTrianglePositions[i1 * 3];
scratchCartesian.y = subTrianglePositions[i1 * 3 + 1];
scratchCartesian.z = subTrianglePositions[i1 * 3 + 2];
cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);
height2 = that._viewer.scene.globe.getHeight(cartographic);
p2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height2);
bottomP2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
if (maxHeight < height2)
maxHeight = height2;
scratchCartesian.x = subTrianglePositions[i2 * 3];
scratchCartesian.y = subTrianglePositions[i2 * 3 + 1];
scratchCartesian.z = subTrianglePositions[i2 * 3 + 2];
cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);
height3 = that._viewer.scene.globe.getHeight(cartographic);
p3 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height3);
bottomP3 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
if (maxHeight < height3)
maxHeight = height3;
bottomArea = computeAreaOfTriangle(bottomP1, bottomP2, bottomP3);
totalCutVolume = totalCutVolume + bottomArea * (height1 - minHeight + height2 - minHeight + height3 - minHeight) / 3;
if (_debugShowSubTriangles) {
var positionsarr = [];
positionsarr.push(p1);
positionsarr.push(p2);
positionsarr.push(p3);
var drawingPolygon = {
polygon: {
hierarchy: {
positions: positionsarr
},
extrudedHeight: 0,
perPositionHeight: true,
material: Cesium.Color.fromRandom().withAlpha(0.5),
outline: true,
closeTop: true,
closeBottom: true,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2
}
};
that._analysisLayer.entities.add(drawingPolygon);
}
}
var centroid = computeCentroidOfPolygon(positions);
$this._volumeLabel = that._analysisLayer.entities.add({
position: Cesium.Cartesian3.fromRadians(centroid.longitude, centroid.latitude, maxHeight + 1000),
label: {
text: 'Cut Volume ' + totalCutVolume.toString() + 'm3'
}
});
return maxHeight;
};
}
/**
* mapv 插件
*/
function MapvLayer(viewer) { this._mapvLayer = null }
MapvLayer.prototype = {
createMapvLayer(option) {
if (this._viewer && option) {
this._mapvLayer = new mapv.cesiumMapLayer(
this._viewer,
new mapv.DataSet([]),
option || {}
)
this._viewer.scene.canvas.setAttribute('tabIndex', 0)
return this._mapvLayer
}
},
setMapvData(dataSet, option) {
if (dataSet && option) {
this._mapvLayer &&
this._mapvLayer.update({ data: dataSet, option: option })
}
},
removeMapvLayer() { }
}
/**
* chart 插件
*/
function ChartLayer(viewer) { this._chartLayer = null }
ChartLayer.prototype = {
createChartLayer() {
this._chartLayer = new Cesium.ChartLayer()
return this._chartLayer.install({
csmContainer: this._csmContainer,
canvas: this._viewer.scene.canvas,
viewer: this._viewer
})
},
setChartData(options) {
if (options) {
this._chartLayer &&
this._chartLayer.setOption(options)
}
},
removeChartLayer() { }
}
/**
* 自定义插件
* @param {*} viewer
*/
function CustomCesiumPlugin(viewer) {
if (viewer) {
this._customPluginLayer = new Cesium.CustomDataSource('_customPluginLayer')
viewer && viewer.dataSources.add(this._customPluginLayer)
}
}
CustomCesiumPlugin.prototype = {
createRectangularSensorGraphics: function (options) {
if (this._customPluginLayer && options) {
let r = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(options.heading || 90),
Cesium.Math.toRadians(options.pitch || 0),
Cesium.Math.toRadians(options.roll || 0));
let l = options.position;
return this._customPluginLayer.entities.add({
position: l,
orientation: Cesium.Transforms.headingPitchRollQuaternion(l, r),
rectangularSensor: new Cesium.RectangularSensorGraphics({
radius: options.radius || 100000,
xHalfAngle: Cesium.Math.toRadians(options.xHalfAngle || 45),
yHalfAngle: Cesium.Math.toRadians(options.yHalfAngle || 45),
material: options.material || new Cesium.Color(1.0, 0.0, 1.0, 0.4),
lineColor: options.lineColor || new Cesium.Color(1.0, 0.0, 1.0, 1.0),
showScanPlane: options.showScanPlane || true,
scanPlaneColor: options.scanPlaneColor || new Cesium.Color(1.0, 0.0, 1.0, 1.0),
scanPlaneMode: options.scanPlaneMode || "vertical",
scanPlaneRate: options.scanPlaneRate || 3,
showThroughEllipsoid: options.showThroughEllipsoid || !1
})
})
}
},
createSatelliteCoverageSimulationGraphics: function (options) {
if (options) {
return new Cesium.SatelliteCoverageSimulation(this._viewer, {
position: options.position,
angle1: options.angle1 || 30,
angle2: options.angle2 || 45,
areaType: options.areaType || 2,
rotation: {
heading: Cesium.Math.toRadians(options.heading || 0),
pitch: Cesium.Math.toRadians(options.pitch || 0),
roll: Cesium.Math.toRadians(options.roll || 0)
},
color: options.color || { red: 0.43137254901960786, green: 0.9607843137254902, blue: 0, alpha: 0.8 }
})
}
},
createRadarPrimitive: function (options) {
if (options) {
return new Cesium.RadarPrimitive(this._viewer, {
position: options.position,
angle: options.angle || 90 - 10,
radius: options.radius || 700000,
rotation: {
heading: Cesium.Math.toRadians(options.heading || 0),
pitch: Cesium.Math.toRadians(options.pitch || 40),
roll: Cesium.Math.toRadians(options.roll || 0)
},
color: options.color || { red: 1, green: 0, blue: 0, alpha: 0.4 },
lineColor: options.lineColor || { red: 1, green: 1, blue: 1, alpha: 0.9 }
})
}
}
}
/**
* 初始化入口
* 三维地图工具拓展
* @param {*} viewer
* @param {*} options
*/
function _(viewer, options) {
this._viewer = viewer
options = options || {}
if (this._viewer && Cesium) {
/**
* 基础模块
*/
this._install([Base, Shaders, Graphics, Primitive, Draw, Math3d, Math2d, Material, Plugin, PassEffect, SuperMap, DomUtil])
/**
* 拓展分析模块
*/
if (Analysis instanceof Object) {
this._install([Analysis])
}
/**
* 外部自定义插件
*/
if (options.loadCustomCesiumPlugin && typeof _installCustomCesiumPlugin !== 'undefined') {
this._install([CustomCesiumPlugin])
}
/**
* threeJS相关模块
*/
if (options && options.three && THREE && ThreeJs instanceof Object) {
this._install([ThreeJs])
}
/**
* GUI控件模块
*/
if (typeof dat !== 'undefined' && Control instanceof Object) {
this._install([Control])
}
/**
* Mapv 组件
*/
if (typeof mapv !== 'undefined' && MapvLayer instanceof Object) {
this._install([MapvLayer])
}
/**
* chart 组件
*/
if (typeof echarts !== 'undefined' && ChartLayer instanceof Object
&& Cesium.ChartLayer instanceof Object) {
Cesium.getUUID = this.getuuid
Cesium.createDom = this.createDom
this._install([ChartLayer])
options.container = options.container || 'viewer-container'
}
/**
* 创建信用容器
*/
if (options && options.container !== '' &&
document.getElementById(options.container)) {
this._csmContainer = this.createDom(
'div',
'cesium-container',
document.getElementById(options.container)
)
}
} else {
alert("请检查 Cesium 是否初始化 !!")
}
}
_.prototype = {
// 安装组件
_install: function (objects) {
// 拷贝
for (var i in objects) {
this._mixin(objects[i])
}
},
// 深拷贝
_mixin: function (obj) {
if (obj instanceof Object) {
//拷贝方法
var keys = Object.keys(obj.prototype);
var i, len;
for (var i = 0, len = keys.length; i < len; i++) {
_.prototype[keys[i]] = obj.prototype[keys[i]];
}
//拷贝属性
obj.call(this, this._viewer)
}
},
/**
* 获取id
* @returns {*|string|!Array.<T>}
*/
getuuid: function () {
let [s, hexDigits] = [[], '0123456789abcdef']
for (let i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = '4'
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
s[8] = s[13] = s[18] = s[23] = '-'
return (s.join(''))
},
/**
* 添加标识
* @param obj
* @returns {*}
*/
stamp: function (obj) {
let key = '_event_id_'
obj[key] = obj[key] || (this.getuuid())
return obj[key]
},
/**
* 去除字符串前后空格
* @param str
* @returns {*}
*/
trim: function (str) {
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '')
},
/**
* 将类名截取成数组
* @param str
* @returns {Array|*}
*/
splitWords: function (str) {
return this.trim(str).split(/\s+/)
},
/**
* 判断是否为对象
* @param value
* @returns {boolean}
*/
isObject: function (value) {
const type = typeof value
return value !== null && (type === 'object' || type === 'function')
},
/**
* merge
* 合并对象
* @param a
* @param b
* @returns {*}
*/
merge: function (a, b) {
for (const key in b) {
if (this.isObject(b[key]) && this.isObject(a[key])) {
this.merge(a[key], b[key])
} else {
a[key] = b[key]
}
}
return a
},
/**
* 取消默认行为
* @param {*} e
*/
preventDefault: function (e) {
e = e || window.event
if (e.preventDefault) {
e.preventDefault()
} else {
e.returnValue = false
}
},
/**
* 函数绑定到某个对象
* @param {*} fns
* @param {*} context
*/
bindAll: function (fns, context) {
fns.forEach((fn) => {
if (!context[fn]) { return }
context[fn] = context[fn].bind(context)
})
},
/**
* 对数据分组
* @param {*} array 数据集
*/
groupBy: function (array, call) {
const groups = {};
array.forEach(function (a) {
const group = JSON.stringify(call(a));
groups[group] = groups[group] || [];
groups[group].push(a);
});
return Object.keys(groups).map(function (group) {
return groups[group];
});
}
}
return _
})();
// export default {};