2021-12-30 16:02:03 +08:00
"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.5 e2 , 0.7 , 1.5 e7 , 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 ) {
/ * *
* 基础模块
* /
2022-01-07 09:11:06 +08:00
this . _install ( [ Base , Shaders , Graphics , Primitive , Draw , Math3d , Math2d , Material , Plugin , PassEffect , SuperMap , DomUtil ] )
2021-12-30 16:02:03 +08:00
/ * *
* 拓展分析模块
* /
if ( Analysis instanceof Object ) {
this . _install ( [ Analysis ] )
}
/ * *
* 外部自定义插件
* /
if ( options . loadCustomCesiumPlugin && typeof _installCustomCesiumPlugin !== 'undefined' ) {
this . _install ( [ CustomCesiumPlugin ] )
}
/ * *
* threeJS相关模块
* /
if ( options && options . three && THREE && ThreeJs instanceof Object ) {
this . _install ( [ ThreeJs ] )
}
/ * *
* GUI控件模块
* /
if ( typeof dat !== 'undefined' && Control instanceof Object ) {
this . _install ( [ Control ] )
}
/ * *
* Mapv 组件
* /
if ( typeof mapv !== 'undefined' && MapvLayer instanceof Object ) {
this . _install ( [ MapvLayer ] )
}
/ * *
* chart 组件
* /
if ( typeof echarts !== 'undefined' && ChartLayer instanceof Object
&& Cesium . ChartLayer instanceof Object ) {
Cesium . getUUID = this . getuuid
Cesium . createDom = this . createDom
this . _install ( [ ChartLayer ] )
options . container = options . container || 'viewer-container'
}
/ * *
* 创建信用容器
* /
if ( options && options . container !== '' &&
document . getElementById ( options . container ) ) {
this . _csmContainer = this . createDom (
'div' ,
'cesium-container' ,
document . getElementById ( options . container )
)
}
} else {
alert ( "请检查 Cesium 是否初始化 !!" )
}
}
_ . prototype = {
// 安装组件
_install : function ( objects ) {
// 拷贝
for ( var i in objects ) {
this . _mixin ( objects [ i ] )
}
} ,
// 深拷贝
_mixin : function ( obj ) {
if ( obj instanceof Object ) {
//拷贝方法
var keys = Object . keys ( obj . prototype ) ;
var i , len ;
for ( var i = 0 , len = keys . length ; i < len ; i ++ ) {
_ . prototype [ keys [ i ] ] = obj . prototype [ keys [ i ] ] ;
}
//拷贝属性
obj . call ( this , this . _viewer )
}
} ,
/ * *
* 获取id
* @ returns { * | string | ! Array . < T > }
* /
getuuid : function ( ) {
let [ s , hexDigits ] = [ [ ] , '0123456789abcdef' ]
for ( let i = 0 ; i < 36 ; i ++ ) {
s [ i ] = hexDigits . substr ( Math . floor ( Math . random ( ) * 0x10 ) , 1 )
}
s [ 14 ] = '4'
s [ 19 ] = hexDigits . substr ( ( s [ 19 ] & 0x3 ) | 0x8 , 1 )
s [ 8 ] = s [ 13 ] = s [ 18 ] = s [ 23 ] = '-'
return ( s . join ( '' ) )
} ,
/ * *
* 添加标识
* @ param obj
* @ returns { * }
* /
stamp : function ( obj ) {
let key = '_event_id_'
obj [ key ] = obj [ key ] || ( this . getuuid ( ) )
return obj [ key ]
} ,
/ * *
* 去除字符串前后空格
* @ param str
* @ returns { * }
* /
trim : function ( str ) {
return str . trim ? str . trim ( ) : str . replace ( /^\s+|\s+$/g , '' )
} ,
/ * *
* 将类名截取成数组
* @ param str
* @ returns { Array | * }
* /
splitWords : function ( str ) {
return this . trim ( str ) . split ( /\s+/ )
} ,
/ * *
* 判断是否为对象
* @ param value
* @ returns { boolean }
* /
isObject : function ( value ) {
const type = typeof value
return value !== null && ( type === 'object' || type === 'function' )
} ,
/ * *
* merge
* 合并对象
* @ param a
* @ param b
* @ returns { * }
* /
merge : function ( a , b ) {
for ( const key in b ) {
if ( this . isObject ( b [ key ] ) && this . isObject ( a [ key ] ) ) {
this . merge ( a [ key ] , b [ key ] )
} else {
a [ key ] = b [ key ]
}
}
return a
} ,
/ * *
* 取消默认行为
* @ param { * } e
* /
preventDefault : function ( e ) {
e = e || window . event
if ( e . preventDefault ) {
e . preventDefault ( )
} else {
e . returnValue = false
}
} ,
/ * *
* 函数绑定到某个对象
* @ param { * } fns
* @ param { * } context
* /
bindAll : function ( fns , context ) {
fns . forEach ( ( fn ) => {
if ( ! context [ fn ] ) { return }
context [ fn ] = context [ fn ] . bind ( context )
} )
} ,
/ * *
* 对数据分组
* @ param { * } array 数据集
* /
groupBy : function ( array , call ) {
const groups = { } ;
array . forEach ( function ( a ) {
const group = JSON . stringify ( call ( a ) ) ;
groups [ group ] = groups [ group ] || [ ] ;
groups [ group ] . push ( a ) ;
} ) ;
return Object . keys ( groups ) . map ( function ( group ) {
return groups [ group ] ;
} ) ;
}
}
// install to Cesium
// if (typeof Cesium !== "undefined") {
// Cesium.D3Kit = D3Kit;
// }
console . clear ( )
console . log (
` %c \n D3-KIT \n %c \n 基于Cesium三维拓展包 %c \n
版本 : $ { version }
作者 : $ { author }
主页 : http : //www.ztwow.top
github : $ { github }
示例地址 : $ { examplesAddr }
Cesium版本 : $ { CesiumVersion }
版权声明 :
1. 代码包基于Cesium拓展 , 部分模块开源已上传github 。
2. 后续会继续更新拓展 , 目前该代码包不开源 , 如需使用 :
1 ) 代码包的完整引用
2 ) 此版权信息在控制台输出
我方保留对此版权信息的最终解释权 。 ` ,
'font-size:20px;padding-left:70px;color:#EEB422' ,
'font-size:14px;padding-left:50px;color:#EEB422;font-style:oblique' ,
'font-size:14px;color:#0865ba'
)
return _
} ) ( ) ;
2022-01-07 09:11:06 +08:00
// export default {};