cesium-d3kit/examples/libs/cesium-d3kit.js

9857 lines
450 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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];
});
}
}
// install to Cesium
// if (typeof Cesium !== "undefined") {
// Cesium.D3Kit = D3Kit;
// }
console.clear()
console.log(
`%c \n D3-KIT \n %c \n 基于Cesium三维拓展包 %c \n
版本:${version}
作者:${author}
主页: http://www.ztwow.top
github: ${github}
示例地址: ${examplesAddr}
Cesium版本:${CesiumVersion}
版权声明:
1.代码包基于Cesium拓展,部分模块开源已上传github。
2.后续会继续更新拓展,目前该代码包不开源,如需使用:
1)代码包的完整引用
2)此版权信息在控制台输出
我方保留对此版权信息的最终解释权。`,
'font-size:20px;padding-left:70px;color:#EEB422',
'font-size:14px;padding-left:50px;color:#EEB422;font-style:oblique',
'font-size:14px;color:#0865ba'
)
return _
})();
// export default {};