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