7685 lines
354 KiB
JavaScript
7685 lines
354 KiB
JavaScript
; if (typeof Cesium !== 'undefined')
|
||
/**
|
||
* 重构工具包 剥离功能模块 解耦合以及模块权限 可以自动安装不同模块使用
|
||
* @author zhangti
|
||
* @param viewer {object} 三维对象
|
||
* @param options {object} 初始化容器参数
|
||
* @constructor
|
||
*/
|
||
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 || ''
|
||
/**
|
||
* 全局参数
|
||
*/
|
||
var CONST_PARAM = {
|
||
LoadFunctionAttribute: '', // 加载方式
|
||
BasePath: '' // 路径
|
||
}
|
||
/**
|
||
* @description 基础模块,封装常用的配置,转换,场景加载等方法。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param viewer {object} 三维对象
|
||
*
|
||
* @returns {[*,*]}
|
||
*/
|
||
var Base = function (viewer) {
|
||
|
||
if (viewer) {
|
||
|
||
this._installBaiduImageryProvider()
|
||
|
||
this._installGooGleImageryProvider()
|
||
|
||
this._installAmapImageryProvider()
|
||
|
||
this._installTencentImageryProvider()
|
||
|
||
this._installTdtImageryProvider()
|
||
}
|
||
}
|
||
Base.prototype = {
|
||
/**
|
||
* 天空盒 1
|
||
*
|
||
* @returns {string|*} SkyBox 星空盒子1
|
||
*/
|
||
setOneSkyBox: function () {
|
||
return new Cesium.SkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/00h+00.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/12h+00.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/06h+00.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/18h+00.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/06h+90.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/06h-90.jpg'
|
||
}
|
||
})
|
||
},
|
||
/**
|
||
* 天空盒 1
|
||
*
|
||
* @return {Object} SkyBox 星空盒子2
|
||
*/
|
||
setTwoSkyBox: function () {
|
||
return new Cesium.SkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_px.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_mx.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_py.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_my.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_pz.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/Version2_dark_mz.jpg'
|
||
}
|
||
})
|
||
},
|
||
/**
|
||
* 天空盒 1
|
||
*
|
||
* @return {Object} SkyBox 星空盒子3
|
||
*/
|
||
setThreeSkyBox: function () {
|
||
return new Cesium.SkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_pxs.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_mxs.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_pys.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_mys.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_pzs.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/tycho2t3_80_mzs.jpg'
|
||
}
|
||
})
|
||
},
|
||
/**
|
||
* 天空盒 1
|
||
* @param {Number} 1-5
|
||
* @return {Object} SkyBox 星空盒子 多选
|
||
*/
|
||
setSelectSkyBox: function (page) {
|
||
page = page || 1
|
||
return new Cesium.SkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_px.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_mx.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_py.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_my.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_pz.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/' + page + '/tycho2t3_80_mz.jpg'
|
||
}
|
||
})
|
||
},
|
||
/**
|
||
* 近景天空盒 1
|
||
*
|
||
* @return {Object} GroundSkyBox 近景天空盒1
|
||
*/
|
||
setOneGroundSkyBox: function () {
|
||
return new Cesium.GroundSkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/rightav9.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/leftav9.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/frontav9.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/backav9.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/topav9.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/bottomav9.jpg'
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 近景天空盒 2
|
||
*
|
||
* @return {Object} GroundSkyBox 近景天空盒2
|
||
*/
|
||
setTwoGroundSkyBox: function () {
|
||
return new Cesium.GroundSkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetRight.png',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetLeft.png',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetFront.png',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetBack.png',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetUp.png',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/SunSetDown.png'
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 近景天空盒 3
|
||
*
|
||
* @return {Object} GroundSkyBox 近景天空盒3
|
||
*/
|
||
setThreeGroundSkyBox: function () {
|
||
return new Cesium.GroundSkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/Right.jpg',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/Left.jpg',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/Front.jpg',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/Back.jpg',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/Up.jpg',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/Down.jpg'
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 近景天空盒 4
|
||
*
|
||
* @return {Object} GroundSkyBox 近景天空盒4
|
||
*/
|
||
setFourGroundSkyBox: function () {
|
||
return new Cesium.GroundSkyBox({
|
||
sources: {
|
||
positiveX: CONST_PARAM.BasePath + 'datas/images/SkyBox/px.png',
|
||
negativeX: CONST_PARAM.BasePath + 'datas/images/SkyBox/nx.png',
|
||
positiveY: CONST_PARAM.BasePath + 'datas/images/SkyBox/py.png',
|
||
negativeY: CONST_PARAM.BasePath + 'datas/images/SkyBox/ny.png',
|
||
positiveZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/pz.png',
|
||
negativeZ: CONST_PARAM.BasePath + 'datas/images/SkyBox/nz.png'
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 叠加黑夜特效
|
||
*
|
||
* @param {Object} options.offset 偏移量
|
||
*
|
||
* @return {Object} postProcessStages 后期处理
|
||
*/
|
||
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);
|
||
}
|
||
}
|
||
}));
|
||
},
|
||
/**
|
||
* 叠加场景蓝光
|
||
*
|
||
* @param {Object} options.width 宽
|
||
* @param {Object} options.height 高
|
||
*
|
||
* @return {Object} postProcessStages 后期处理
|
||
*/
|
||
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"
|
||
}
|
||
}));
|
||
}
|
||
},
|
||
/**
|
||
* 叠加雨天特效
|
||
*
|
||
* @return {Object} postProcessStages 后期处理
|
||
*/
|
||
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
|
||
}));
|
||
}
|
||
|
||
},
|
||
/**
|
||
* 叠加雨天特效
|
||
*
|
||
* @return {Object} postProcessStages 后期处理
|
||
*/
|
||
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
|
||
}));
|
||
}
|
||
},
|
||
/**
|
||
* 叠加雾天特效
|
||
*
|
||
* @return {Object} postProcessStages 后期处理
|
||
*/
|
||
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, 1000, 1.0),
|
||
fogColor: Cesium.Color.BLACK,
|
||
},
|
||
})
|
||
);
|
||
}
|
||
},
|
||
/**
|
||
* 默认场景配置
|
||
*
|
||
* @param {Object} options.scene 场景中的一些配置,一般默认不用填
|
||
* @return {null}
|
||
*/
|
||
setDefSceneConfig: function (options) {
|
||
options = options || {}
|
||
if (this._viewer && options) {
|
||
this._viewer.scene.sun.show = options.sun || false;
|
||
this._viewer.scene.moon.show = options.moon || false;
|
||
this._viewer.scene.fxaa = options.fxaa || true;
|
||
this._viewer.scene.globe.depthTestAgainstTerrain = options.depthTestAgainstTerrain || true;
|
||
this._viewer.scene.undergroundMode = options.undergroundMode || false;
|
||
this._viewer.scene.terrainProvider.isCreateSkirt = options.isCreateSkirt || false;
|
||
this._viewer.scene.skyAtmosphere.show = options.skyAtmosphere || false;
|
||
this._viewer.scene.globe.showGroundAtmosphere = options.showGroundAtmosphere || false
|
||
this._viewer.scene.globe.enableLighting = options.enableLighting || true
|
||
this._viewer.scene.fog.enabled = options.fog || false
|
||
this._viewer.cesiumWidget.creditContainer.style.display = "none";
|
||
}
|
||
},
|
||
/**
|
||
* 场景泛光
|
||
*
|
||
* @return {null}
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 相机定位
|
||
*
|
||
* @param {Object} options.position 三维位置坐标
|
||
* @param {Object} options.orientation 四元数
|
||
*
|
||
* @return {null}
|
||
*/
|
||
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)
|
||
},
|
||
});
|
||
}
|
||
},
|
||
/**
|
||
* 获取两个点的方向
|
||
* @param {Object} position 起点
|
||
* @param {Object} tagPosition 目标点
|
||
*
|
||
* @return {Cartesian3} Direction 三维方向
|
||
*/
|
||
getDirection: function (tagPosition, position) {
|
||
return Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(tagPosition, position, new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||
},
|
||
/**
|
||
* 相机飞行
|
||
*
|
||
* @param {Object} options.position 三维位置坐标
|
||
* @param {Object} options.orientation 四元数
|
||
* @param {Object} options.easingFunction 相机模式
|
||
* @param {Object} options.duration 用时
|
||
* @param {Object} options.callback 相机完成回调
|
||
* @param {Object} options.distance 距离
|
||
*
|
||
*/
|
||
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
|
||
*
|
||
* @param {Object} Cartesian3 三维位置坐标
|
||
*
|
||
* @return {Object} {lng,lat,alt} 地理坐标
|
||
*/
|
||
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
|
||
*
|
||
* @param {Array} WSG84Arr {lng,lat,alt} 地理坐标数组
|
||
* @param {Number} alt 拔高
|
||
* @return {Array} Cartesian3 三维位置坐标数组
|
||
*/
|
||
transformWGS84ArrayToCartesianArray: function (WSG84Arr, alt) {
|
||
if (this._viewer && WSG84Arr) {
|
||
var $this = this
|
||
return WSG84Arr
|
||
? WSG84Arr.map(function (item) { return $this.transformWGS84ToCartesian(item, alt) })
|
||
: []
|
||
}
|
||
},
|
||
/***
|
||
* 坐标转换 84转笛卡尔
|
||
*
|
||
* @param {Object} {lng,lat,alt} 地理坐标
|
||
*
|
||
* @return {Object} Cartesian3 三维位置坐标
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/***
|
||
* 坐标数组转换 笛卡尔转86
|
||
*
|
||
* @param {Array} cartesianArr 三维位置坐标数组
|
||
*
|
||
* @return {Array} {lng,lat,alt} 地理坐标数组
|
||
*/
|
||
transformCartesianArrayToWGS84Array: function (cartesianArr) {
|
||
if (this._viewer) {
|
||
var $this = this
|
||
return cartesianArr
|
||
? cartesianArr.map(function (item) { return $this.transformCartesianToWGS84(item) })
|
||
: []
|
||
}
|
||
},
|
||
/***
|
||
* 设置相机绕点旋转
|
||
*
|
||
* @param {Object} options.lng 相机的位置高度
|
||
* @param {Object} options.lat 相机的位置高度,
|
||
* @param {Object} options.height 相机的位置高度,
|
||
* @param {Object} options.speed 旋转速度,
|
||
* @param {Object} options.time 间隔
|
||
*
|
||
* @return {Object} interval window触发器对象
|
||
*/
|
||
setCameraEotateHeading: function (options) {
|
||
if (options) {
|
||
let viewer = this._viewer
|
||
let position = Cesium.Cartesian3.fromDegrees(options.lng, options.lat, options.height);
|
||
let pitch = Cesium.Math.toRadians(-30);
|
||
let angle = 360 / 30;
|
||
let distance = options.distance || 5000;
|
||
let initialHeading = viewer.camera.heading;
|
||
let delTime = 0
|
||
let speed = options.speed || 0.06
|
||
let time = options.time || 60
|
||
let interval = setInterval(() => {
|
||
delTime += speed
|
||
let heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
|
||
viewer.scene.camera.setView({
|
||
destination: position, // 点的坐标
|
||
orientation: {
|
||
heading: heading,
|
||
pitch: pitch,
|
||
}
|
||
});
|
||
viewer.scene.camera.moveBackward(distance);
|
||
}, time)
|
||
|
||
return interval
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 84坐标转弧度坐标
|
||
* @param {Object} position wgs84
|
||
* @return {Object} Cartographic 弧度坐标
|
||
*
|
||
*/
|
||
transformWGS84ToCartographic: function (position) {
|
||
return position
|
||
? Cesium.Cartographic.fromDegrees(
|
||
position.lng || position.lon,
|
||
position.lat,
|
||
position.alt
|
||
)
|
||
: Cesium.Cartographic.ZERO
|
||
},
|
||
/**
|
||
* 拾取位置点
|
||
*
|
||
* @param {Object} px 屏幕坐标
|
||
*
|
||
* @return {Object} Cartesian3 三维坐标
|
||
*/
|
||
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 && !this._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;
|
||
}
|
||
|
||
},
|
||
/**
|
||
* 获取相机位置
|
||
*
|
||
* @return {Object} {lon,lat,height,position...} 相机位置实体
|
||
*
|
||
*/
|
||
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, z: Math.ceil(height) },
|
||
direction: new Cesium.Cartesian3(x, y, z)
|
||
};
|
||
}
|
||
}
|
||
},
|
||
/**
|
||
* 修改相机状态
|
||
*
|
||
* @param {Boolean} flag
|
||
*/
|
||
updateCameraState: function (flag) {
|
||
if (this._viewer) {
|
||
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;
|
||
}
|
||
},
|
||
/**
|
||
* 鼠标事件注册
|
||
* @param {*} _mouseClickHandler 点击事件回调
|
||
* @param {*} _mouseMoveHandler 移动时间回调
|
||
* @param {*} _mouseDbClickHandler 双击事件回调
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 获取鼠标信息
|
||
* @param {Function} callback 回调方法cartesian, handler句柄
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 根据坐标, 方位角计算世界矩阵
|
||
* @param {Object} position 位置
|
||
* @param {Object} hpr 方向角
|
||
*
|
||
* @return {Object} 模型矩阵
|
||
*/
|
||
getObjectMatrix4: function (position, hpr) {
|
||
|
||
if (position instanceof Cesium.Cartesian3) {
|
||
let cartesian = Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.alt || 0)
|
||
let heading = Cesium.Math.toRadians(hpr.heading || 90);
|
||
let pitch = Cesium.Math.toRadians(hpr.pitch || 90);
|
||
let roll = Cesium.Math.toRadians(hpr.hearollding || 0);
|
||
let headingPitchRoll = new Cesium.HeadingPitchRoll(heading, pitch, roll);
|
||
|
||
let m = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian, headingPitchRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
|
||
return m;
|
||
}
|
||
},
|
||
/**
|
||
* 根据矩阵求方位角
|
||
*
|
||
* @param {Object} matrix4 模型矩阵
|
||
* @return {Object} hpr 方位角
|
||
*/
|
||
getObjectQuaternion: function (matrix4) {
|
||
if (matrix4 instanceof Cesium.Matrix4) {
|
||
// 计算中心处的变换矩阵
|
||
let m1 = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Matrix4.getTranslation(matrix4, new Cesium.Cartesian3()), Cesium.Ellipsoid.WGS84, new Cesium.Matrix4());
|
||
// 矩阵相除
|
||
let m3 = Cesium.Matrix4.multiply(Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()), matrix4, new Cesium.Matrix4());
|
||
// 得到旋转矩阵
|
||
let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3());
|
||
// 计算四元数
|
||
let q = Cesium.Quaternion.fromRotationMatrix(mat3);
|
||
// 计算旋转角(弧度)
|
||
let hpr = Cesium.HeadingPitchRoll.fromQuaternion(q);
|
||
// 得到角度
|
||
let heading = Cesium.Math.toDegrees(hpr.heading);
|
||
let pitch = Cesium.Math.toDegrees(hpr.pitch);
|
||
let roll = Cesium.Math.toDegrees(hpr.roll);
|
||
return {
|
||
heading: heading,
|
||
pitch: pitch,
|
||
roll: roll
|
||
}
|
||
}
|
||
},
|
||
/**
|
||
* 保存当前场景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();
|
||
}
|
||
},
|
||
/**
|
||
* AmapImageryProvider
|
||
*/
|
||
_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)
|
||
}
|
||
/**
|
||
* 拓展AmapImageryProvider
|
||
*/
|
||
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 () {
|
||
let IMG_URL =
|
||
'http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46'
|
||
|
||
let VEC_URL =
|
||
'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020'
|
||
|
||
let CUSTOM_URL =
|
||
'http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid={style}'
|
||
let $this = this;
|
||
function BaiduImageryProvider(options) {
|
||
|
||
CUSTOM_URL = options.temp_url || CUSTOM_URL
|
||
this._url =
|
||
options.style === 'img'
|
||
? IMG_URL
|
||
: options.style === 'vec'
|
||
? VEC_URL
|
||
: CUSTOM_URL
|
||
this._tileWidth = 256
|
||
this._tileHeight = 256
|
||
this._maximumLevel = 18
|
||
this._minimumLevel = 1
|
||
this._tilingScheme = options.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._token = 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
|
||
}
|
||
},
|
||
hasAlphaChannel: {
|
||
get: function () {
|
||
return true
|
||
}
|
||
}
|
||
});
|
||
|
||
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 pick1 = new Cesium.Cartesian2(x, y);
|
||
// var cartesian3 = $this._viewer.scene.globe.pick($this._viewer.camera.getPickRay(pick1), $this._viewer.scene);
|
||
// if (cartesian3) {
|
||
// var ellipsoid = $this._viewer.scene.globe.ellipsoid;
|
||
// var cartographic = ellipsoid.cartesianToCartographic(cartesian3);
|
||
// var lat = Cesium.Math.toDegrees(cartographic.latitude);
|
||
// var lng = Cesium.Math.toDegrees(cartographic.longitude);
|
||
// var alt = cartographic.height;
|
||
// if (lat && lng) {
|
||
// let position = $this.bd09togcj02(lng, lat)
|
||
// position = $this.gcj02towgs84(position[0], position[1])
|
||
// let xy = Cesium.SceneTransforms.wgs84ToWindowCoordinates($this._viewer.scene, Cesium.Cartesian3.fromDegrees(position[0], position[1]));
|
||
// if (xy && xy.x && xy.y) {
|
||
// x = xy.x, y = xy.y
|
||
// this._tilingScheme.positionToTileXY(x, y, level,this._rectangle)
|
||
// }
|
||
// }
|
||
// }
|
||
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
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @description Dom 工具 页面dom元素操作。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
*
|
||
* @param viewer {object} 三维对象
|
||
* @returns {[*,*]}
|
||
*/
|
||
var DomUtil = function (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
|
||
* @param {*} el
|
||
*/
|
||
removeDom: function (el) {
|
||
var parent = el.parentNode
|
||
if (parent) {
|
||
parent.removeChild(el)
|
||
}
|
||
},
|
||
/**
|
||
* 清空 element
|
||
* @param {*} el
|
||
*/
|
||
emptyDom: function (el) {
|
||
while (el.firstChild) {
|
||
el.removeChild(el.firstChild)
|
||
}
|
||
},
|
||
/**
|
||
* 添加 class
|
||
* @param {*} el
|
||
* @param {*} name
|
||
*/
|
||
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
|
||
* @param {*} el
|
||
* @param {*} name
|
||
*/
|
||
removeDomClass: function (el, name) {
|
||
if (el.classList !== undefined) {
|
||
el.classList.remove(name)
|
||
} else {
|
||
this.setClass(el, this.trim((' ' + this.getClass(el) + ' ').replace(' ' + name + ' ', ' ')))
|
||
}
|
||
},
|
||
/**
|
||
* 设置 class
|
||
* @param {*} el
|
||
* @param {*} name
|
||
*/
|
||
setDomClass: function (el, name) {
|
||
if (el.className.baseVal === undefined) {
|
||
el.className = name
|
||
} else {
|
||
// in case of SVG element
|
||
el.className.baseVal = name
|
||
}
|
||
},
|
||
/**
|
||
* 获取 el class
|
||
* @param {*} el
|
||
*/
|
||
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
|
||
* @param {*} width
|
||
* @param {*} height
|
||
* @param {*} path
|
||
* @param {*} container
|
||
*/
|
||
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
|
||
* @param {*} prefix
|
||
*/
|
||
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('')
|
||
}
|
||
}
|
||
/**
|
||
* @description 超图模块。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var SuperMap = function (viewer) {
|
||
if (viewer) {
|
||
|
||
this._superMapLayer = new Cesium.CustomDataSource('superMapLayer')
|
||
|
||
viewer && viewer.dataSources.add(this._superMapLayer)
|
||
}
|
||
}
|
||
SuperMap.prototype = {
|
||
/**
|
||
* 发光纹理纹理
|
||
* @param {*} layer
|
||
* @param {*} option
|
||
*/
|
||
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 || CONST_PARAM.BasePath + "/datas/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
|
||
}
|
||
}
|
||
},
|
||
/**
|
||
* 点光源
|
||
* @param {*} position
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 平行光
|
||
* @param {*} position
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 扫描圆
|
||
* @param {*} options
|
||
*/
|
||
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 || CONST_PARAM.BasePath + '/datas/images/cc2.jpg'
|
||
this._viewer.scene.scanEffect.mode = Cesium.ScanEffectMode.CIRCLE
|
||
setTimeout(() => {
|
||
this._viewer.scene.scanEffect.show = true
|
||
}, 5000)
|
||
}
|
||
},
|
||
/**
|
||
* 扫描线
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
|
||
},
|
||
/**
|
||
* 添加火焰粒子
|
||
* @param {*} options
|
||
*/
|
||
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;
|
||
}
|
||
},
|
||
/**
|
||
* 添加雨滴粒子
|
||
* @param {*} options
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 鼠标旋转
|
||
* @param {*} init
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 旋转聚光灯
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
|
||
}
|
||
})
|
||
|
||
}
|
||
},
|
||
}
|
||
/**
|
||
* 图形模块 。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Graphics = function (viewer) {
|
||
|
||
if (viewer) {
|
||
|
||
this._graphicsLayer = new Cesium.CustomDataSource('graphicsLayer')
|
||
|
||
viewer && viewer.dataSources.add(this._graphicsLayer)
|
||
}
|
||
|
||
}
|
||
Graphics.prototype = {
|
||
/**
|
||
* 创建一个实体图形
|
||
*/
|
||
createGraphics: function () {
|
||
|
||
return new Cesium.Entity()
|
||
},
|
||
/**
|
||
* 获取点图形
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
});
|
||
}
|
||
},
|
||
/**
|
||
* 获取线图形
|
||
* @param {*} options
|
||
*/
|
||
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,
|
||
});
|
||
}
|
||
},
|
||
/**
|
||
* 获取面图形
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取标签
|
||
* @param {*} options
|
||
*/
|
||
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,
|
||
outlineColor: options.l_outlineColor || undefined,
|
||
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
|
||
});
|
||
}
|
||
},
|
||
/**
|
||
* 获取广告牌
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取路径
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取模型
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取圆面
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取球体
|
||
* @param {*} options
|
||
*/
|
||
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,
|
||
});
|
||
}
|
||
},
|
||
/**
|
||
* 获取面板
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 获取锥体
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 创建信息点实体
|
||
* @param {*} options
|
||
*/
|
||
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;
|
||
}
|
||
},
|
||
/**
|
||
* 创建线段实体
|
||
* @param {*} options
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 创建多变形面实体
|
||
* @param {*} options
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 创建模型实体
|
||
* @param {*} options
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 创建地面指示实体
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建动态线实体
|
||
* @param {*} options
|
||
*/
|
||
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);
|
||
}
|
||
},
|
||
/**
|
||
* 创建动态椎体
|
||
* @param {*} options
|
||
*/
|
||
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;
|
||
}
|
||
},
|
||
/**
|
||
* 创建渐变锥体实体
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建旋转圆柱实体
|
||
* @param {*} options
|
||
*/
|
||
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: CONST_PARAM.BasePath + "datas/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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建闪烁圆实体
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建动态旋转圆实体
|
||
* @param {*} options
|
||
*/
|
||
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 || CONST_PARAM.BasePath + 'datas/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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建动态渐变墙实体
|
||
* @param {*} options
|
||
*/
|
||
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: CONST_PARAM.BasePath + "datas/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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建默认自定义标牌气泡框
|
||
* @param {*} options
|
||
*/
|
||
createCustomDefBillboardGraphics: function (options) {
|
||
|
||
if (options && options.position) {
|
||
|
||
var $this = this, img = document.createElement('img');
|
||
img.src = options.img || CONST_PARAM.BasePath + 'datas/images/file/div1.png'
|
||
// 绘制canvas
|
||
function drawCompanyTip(options) {
|
||
if (!options.image) return
|
||
var canvas = document.createElement("canvas");
|
||
canvas.width = options.width || 150;
|
||
canvas.height = options.height || 80;
|
||
var context = canvas.getContext('2d');
|
||
context.drawImage(options.image, 0, 0);
|
||
var dom = options.text;
|
||
context.font = '15px bold 宋体';
|
||
context.fillStyle = "#f4fff0";
|
||
context.fillText(dom, 55, 36);
|
||
return canvas;
|
||
}
|
||
img.onload = function () {
|
||
options.image = img;
|
||
var entity = $this._graphicsLayer.entities.add({
|
||
position: options.position,
|
||
billboard: {
|
||
image: drawCompanyTip(options),
|
||
scaleByDistance: new Cesium.NearFarScalar(1.5e2, 0.7, 1.5e7, 0.5),
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
pixelOffset: options.b_pixelOffset || new Cesium.Cartesian2(80, -35),
|
||
width: 140,
|
||
height: 100,
|
||
scale: options.b_scale || 1.5,
|
||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||
imageSubRegion: { x: 0, y: 0, width: 200, height: 150 }
|
||
},
|
||
})
|
||
if (typeof options.callback === 'function') {
|
||
|
||
options.callback(entity)
|
||
}
|
||
};
|
||
}
|
||
},
|
||
/**
|
||
* 创建旋转面实体
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 创建视频投放实体
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
}),
|
||
// classificationType: Cesium.ClassificationType.BOTH
|
||
}
|
||
return this._graphicsLayer.entities.add(entity)
|
||
}
|
||
},
|
||
/**
|
||
* 创建gif 图片投影实体
|
||
* @param {*} options
|
||
*/
|
||
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
|
||
}
|
||
})
|
||
}
|
||
},
|
||
/**
|
||
* 创建缓冲区图形实体
|
||
* @param {*} options
|
||
*/
|
||
createBufferGraphics: function (options) {
|
||
|
||
if (options && options.turfPositions && options.radius) {
|
||
|
||
function reduceDimension(arr) { // 连接
|
||
var reduced = [];
|
||
for (var i = 0; i < arr.length; i++) {
|
||
reduced = reduced.concat(arr[i]);
|
||
}
|
||
return reduced
|
||
}
|
||
let bufferEntity = this.createGraphics(), _positions = options.turfPositions, _radius = options.radius,
|
||
_hierarchy = new Cesium.PolygonHierarchy(), radius = 0.1;
|
||
|
||
bufferEntity.polygon = {
|
||
hierarchy: new Cesium.CallbackProperty(function (time, result) {
|
||
if (options.animation === undefined || options.animation) { // 动画
|
||
if (radius <= _radius) {
|
||
radius += 0.02
|
||
} else {
|
||
radius = 0.02
|
||
}
|
||
} else {
|
||
radius = _radius
|
||
}
|
||
let buffered = reduceDimension(
|
||
turf.buffer(_positions, radius, { units: 'kilometers' }).geometry
|
||
.coordinates[0]
|
||
)
|
||
_hierarchy.positions = Cesium.Cartesian3.fromDegreesArray(buffered, Cesium.Ellipsoid.WGS84, result)
|
||
return _hierarchy;
|
||
}, false),
|
||
material: options.material || Cesium.Color.SKYBLUE.withAlpha(0.5)
|
||
}
|
||
|
||
this._graphicsLayer.entities.add(bufferEntity)
|
||
}
|
||
},
|
||
/**
|
||
* 设置图形旋转
|
||
* @param {*} options
|
||
*/
|
||
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)
|
||
}
|
||
},
|
||
/**
|
||
* 设置图形浮动
|
||
* @param {*} options
|
||
*/
|
||
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 贴图实体
|
||
* @param {*} options
|
||
*/
|
||
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()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 着色器模块,默认隐藏 。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
Shaders = function (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\
|
||
}
|
||
},
|
||
// 带方向的墙体
|
||
_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\
|
||
";
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 后期效果模块 。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var PassEffect = function () { }
|
||
PassEffect.prototype = {
|
||
/**
|
||
* 圆形扩散效果 自定义
|
||
* @param {*} options
|
||
*/
|
||
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;
|
||
}
|
||
},
|
||
/**
|
||
* 雷达扫描 自定义
|
||
* @param {*} options
|
||
*/
|
||
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;
|
||
}
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 画笔模块 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Draw = function (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: CONST_PARAM.BasePath + 'datas/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);
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 二维模块 平面Math工具 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Math2d = function (viewer) { }
|
||
Math2d.prototype = {
|
||
/**
|
||
* 计算两个坐标之间的距离
|
||
* @param pnt1
|
||
* @param pnt2
|
||
* @returns {number}
|
||
*/
|
||
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 {[*,*]}
|
||
*/
|
||
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)
|
||
},
|
||
/**
|
||
* 绘制扇形
|
||
* 经度、纬度、半径、开始角度、夹角度
|
||
* computeCirclularFlight(center.x, center.y, 5000,40,120)
|
||
* @param {*} lon
|
||
* @param {*} lat
|
||
* @param {*} radius
|
||
* @param {*} fx
|
||
* @param {*} angle
|
||
*/
|
||
computeCirclularFlight: function (lon, lat, radius, fx, angle) {
|
||
let Ea = 6378137; // 赤道半径
|
||
let Eb = 6356725; // 极半径
|
||
let positionArr = [];
|
||
positionArr.push(lon);
|
||
positionArr.push(lat);
|
||
//需求正北是0° cesium正东是0°
|
||
for (let i = fx; i <= fx + angle; i++) {
|
||
let dx = radius * Math.sin(i * Math.PI / 180.0);
|
||
let dy = radius * Math.cos(i * Math.PI / 180.0);
|
||
|
||
let ec = Eb + (Ea - Eb) * (90.0 - lat) / 90.0;
|
||
let ed = ec * Math.cos(lat * Math.PI / 180);
|
||
|
||
let BJD = lon + (dx / ed) * 180.0 / Math.PI;
|
||
let BWD = lat + (dy / ec) * 180.0 / Math.PI;
|
||
|
||
positionArr.push(BJD);
|
||
positionArr.push(BWD);
|
||
}
|
||
return positionArr;
|
||
},
|
||
/**
|
||
* 获取交集的点
|
||
* @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) {
|
||
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
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 三维Math拓展工具,默认三维。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Math3d = function (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 && startPoint && endPoint && angularityFactor && numOfSingleLine) {
|
||
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;
|
||
},
|
||
/**
|
||
* 线段插值 经纬度坐标插值
|
||
* @param {*} start start.lon start.lat 单位:度
|
||
* @param {*} end
|
||
* @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;
|
||
},
|
||
/**
|
||
* 线段插值 经纬度坐标插值
|
||
* @param {*} start start.longitude start.latitude 单位:弧度
|
||
* @param {*} end
|
||
* @param {*} _Delta
|
||
* @returns [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;
|
||
},
|
||
/**
|
||
* 线段插值 经纬度高程插值
|
||
* @param {*} start
|
||
* @param {*} end
|
||
*/
|
||
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,...]
|
||
* @param {*} start
|
||
* @param {*} end
|
||
* @param {*} num
|
||
* @param {*} curIndex
|
||
*/
|
||
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
|
||
* @param {*} start
|
||
* @param {*} end
|
||
* @param {*} num
|
||
* @param {*} index
|
||
*/
|
||
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;
|
||
}
|
||
}
|
||
/**
|
||
* 材质模块 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Material = function (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 = CONST_PARAM.BasePath + 'datas/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 = CONST_PARAM.BasePath + "datas/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
|
||
}
|
||
})
|
||
}
|
||
}
|
||
/**
|
||
* 外部插件模块 。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Plugin = function (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
|
||
},
|
||
/**
|
||
* 灯光扫描插件
|
||
* @param {*} data
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 路径漫游 支持第一时间,匀速和自定义时间
|
||
* @param {*} options
|
||
*/
|
||
buildPathRoaming: function (options) {
|
||
|
||
if (this._viewer && options && options.paths) {
|
||
|
||
var _paths = options.paths, _positionProperty = new Cesium.SampledPositionProperty(),
|
||
_rEntity = this.createGraphics(), _directionProperty = new Cesium.SampledPositionProperty(),
|
||
_startTime = new Cesium.JulianDate(), _direction = null, _stopTime = null, _increment = null,
|
||
_time = null;
|
||
|
||
if (options.times) {
|
||
// 漫游时间
|
||
let _times = options.times - options.times % (_paths.length - 1)
|
||
_stopTime = Cesium.JulianDate.addSeconds(_startTime, _times, new Cesium.JulianDate()),
|
||
_increment = _times / (_paths.length - 1)
|
||
} else {
|
||
// 自定义
|
||
_stopTime = Cesium.JulianDate.addSeconds(
|
||
_startTime,
|
||
(_paths.length - 1) * (options.step || 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
|
||
);
|
||
|
||
if (options.times) {
|
||
// 漫游时间
|
||
_time = Cesium.JulianDate.addSeconds(startTime, i * _increment, new Cesium.JulianDate())
|
||
} else {
|
||
// 自定义
|
||
_time = Cesium.JulianDate.addSeconds(
|
||
startTime,
|
||
_paths[i].time,
|
||
new Cesium.JulianDate()
|
||
);
|
||
}
|
||
_positionProperty.addSample(_time, cartesian); // 添加位置,和时间对应
|
||
|
||
// --------------
|
||
let directionCartesian = null
|
||
// let hpr = this.getObjectQuaternion(this.getObjectMatrix4(cartesian)) // 添加四元数插值
|
||
if (i === _paths.length - 1) {
|
||
_directionProperty.addSample(_time, _direction)
|
||
continue;
|
||
} else {
|
||
directionCartesian = Cesium.Cartesian3.fromDegrees(
|
||
_paths[i + 1].lon,
|
||
_paths[i + 1].lat,
|
||
_paths[i + 1].alt
|
||
);
|
||
}
|
||
_direction = this.getDirection(directionCartesian, cartesian)
|
||
|
||
_directionProperty.addSample(_time, _direction)
|
||
}
|
||
_rEntity.name = options.name || "路径漫游";
|
||
_rEntity.availability = new Cesium.TimeIntervalCollection([
|
||
|
||
new Cesium.TimeInterval({ start: startTime, stop: stopTime })
|
||
]); // 和时间轴关联
|
||
|
||
_rEntity.position = _positionProperty;
|
||
|
||
_rEntity.orientation = new Cesium.VelocityOrientationProperty(_positionProperty); // 基于位置移动自动计算方向
|
||
|
||
_rEntity.direction = _directionProperty
|
||
// 添加图形
|
||
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)
|
||
}
|
||
|
||
// 视角跟踪
|
||
if (options.firstView) {
|
||
|
||
this._viewer.scene.postUpdate.addEventListener(() => {
|
||
let position = _rEntity.position.getValue(this._viewer.clock.currentTime)
|
||
let direction = _rEntity.direction.getValue(this._viewer.clock.currentTime)
|
||
this._viewer.scene.camera.setView({
|
||
destination: position, // 点的坐标
|
||
orientation: {
|
||
direction: direction,
|
||
up: new Cesium.Cartesian3(0, 0, 0),
|
||
}
|
||
});
|
||
this._viewer.scene.camera.lookUp(options.up || 200)
|
||
this._viewer.scene.camera.lookDown(options.down || 150)
|
||
this._viewer.scene.camera.moveBackward(options.backward || 1200)
|
||
})
|
||
}
|
||
return this._pluginLayer.entities.add(_rEntity)
|
||
}
|
||
},
|
||
/**
|
||
* 拓展css3的动画 html元素
|
||
*/
|
||
_installCss3Renderer: function () {
|
||
|
||
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: CONST_PARAM.BasePath + "datas/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: CONST_PARAM.BasePath + "datas/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
|
||
}
|
||
})
|
||
}
|
||
}
|
||
/**
|
||
* 添加css3 html元素
|
||
* @param app
|
||
* @param elements
|
||
* @param isBackHide
|
||
*/
|
||
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
|
||
}
|
||
}
|
||
/**
|
||
* 控件模块 。 目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var Control = function (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()
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Mapv 插件 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var MapvLayer = function (viewer) { this._mapvLayer = null }
|
||
MapvLayer.prototype = {
|
||
/**
|
||
* 创建mapv图层 需要导入mapv.js
|
||
* @param {*} option
|
||
*/
|
||
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
|
||
}
|
||
},
|
||
/**
|
||
* 设置图层数据
|
||
* @param {*} dataSet
|
||
* @param {*} option
|
||
*/
|
||
setMapvData(dataSet, option) {
|
||
if (dataSet && option) {
|
||
this._mapvLayer &&
|
||
this._mapvLayer.update({ data: dataSet, option: option })
|
||
}
|
||
},
|
||
/**
|
||
* 删除图层
|
||
*/
|
||
removeMapvLayer() { }
|
||
}
|
||
/**
|
||
* chart 插件 需要导入echart.js 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
*/
|
||
var ChartLayer = function (viewer) { this._chartLayer = null }
|
||
ChartLayer.prototype = {
|
||
/**
|
||
* 创建echart图层
|
||
*/
|
||
createChartLayer() {
|
||
this._chartLayer = new Cesium.ChartLayer()
|
||
return this._chartLayer.install({
|
||
csmContainer: this._csmContainer,
|
||
canvas: this._viewer.scene.canvas,
|
||
viewer: this._viewer
|
||
})
|
||
},
|
||
/**
|
||
* 设置图层数据
|
||
* @param {*} options
|
||
*/
|
||
setChartData(options) {
|
||
if (options) {
|
||
this._chartLayer &&
|
||
this._chartLayer.setOption(options)
|
||
}
|
||
},
|
||
/**
|
||
* 删除图层
|
||
*/
|
||
removeChartLayer() { }
|
||
}
|
||
|
||
/**
|
||
* 初始化入口 三维地图工具拓展 。目前该对象对外隐藏,所有属性及方法追加到d3kit上
|
||
* @constructor
|
||
* @param {*} viewer
|
||
* @param {*} options
|
||
*/
|
||
function _(viewer, options) {
|
||
|
||
this._viewer = viewer
|
||
|
||
options = options || {}
|
||
|
||
if (this._viewer && Cesium) {
|
||
/**
|
||
* config
|
||
* 局部参数配置
|
||
*/
|
||
// 加载方式
|
||
CONST_PARAM.LoadFunctionAttribute = options.loadFunctionAttribute || ''
|
||
CONST_PARAM.BasePath = options.basePath || '/gis-manager/WEBGISv1.5/'
|
||
/**
|
||
* 基础模块
|
||
*/
|
||
this._install([Base, Shaders, Graphics, Draw, Math3d, Math2d, Material, Plugin, PassEffect, DomUtil])
|
||
|
||
/**
|
||
* 超图拓展
|
||
*/
|
||
if (options && options.loadSuperMapPlugin && SuperMap instanceof Object) {
|
||
this._install([SuperMap])
|
||
}
|
||
/**
|
||
* GUI控件模块
|
||
*/
|
||
if (options && options.loadGuiPlugin && typeof dat !== 'undefined' && Control instanceof Object) {
|
||
|
||
this._install([Control])
|
||
}
|
||
/**
|
||
* Mapv 组件
|
||
*/
|
||
if (options && options.loadMapVPlugin && typeof mapv !== 'undefined' && MapvLayer instanceof Object) {
|
||
this._install([MapvLayer])
|
||
}
|
||
/**
|
||
* chart 组件
|
||
*/
|
||
if (options && options.loadEchartPlugin && typeof echarts !== 'undefined' && ChartLayer instanceof Object
|
||
&& Cesium.ChartLayer instanceof Object) {
|
||
|
||
Cesium.getUUID = this.getuuid
|
||
Cesium.createDom = this.createDom
|
||
this._install([ChartLayer])
|
||
options.mapContainer = options.mapContainer || 'viewer-container'
|
||
}
|
||
/**
|
||
* 创建信用容器
|
||
*/
|
||
if (options && options.mapContainer !== '' &&
|
||
document.getElementById(options.mapContainer)) {
|
||
this._csmContainer = this.createDom(
|
||
'div',
|
||
'cesium-container',
|
||
document.getElementById(options.mapContainer)
|
||
)
|
||
}
|
||
/**
|
||
* 是否手动执行函数对象属性
|
||
*/
|
||
if (CONST_PARAM.LoadFunctionAttribute == 'loadAttribute') this._loadFunctionAttribute(options)
|
||
} else {
|
||
|
||
alert("请检查 Cesium 是否初始化 !!")
|
||
return false
|
||
}
|
||
}
|
||
_.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]];
|
||
}
|
||
//拷贝属性
|
||
if (CONST_PARAM.LoadFunctionAttribute === 'loadAttribute') return;
|
||
obj.call(this, this._viewer)
|
||
}
|
||
|
||
},
|
||
/**
|
||
* 手动加载执行函数(对象属性)
|
||
*/
|
||
_loadFunctionAttribute: function (options) {
|
||
if (CONST_PARAM.LoadFunctionAttribute === 'loadAttribute') {
|
||
// addSources
|
||
this._graphicsLayer = new Cesium.CustomDataSource('graphicsLayer')
|
||
viewer && viewer.dataSources.add(this._graphicsLayer)
|
||
this._drawLayer = new Cesium.CustomDataSource('drawLayer')
|
||
viewer && viewer.dataSources.add(this._drawLayer)
|
||
this._pluginLayer = new Cesium.CustomDataSource('pluginLayer')
|
||
viewer && viewer.dataSources.add(this._pluginLayer)
|
||
// install
|
||
this._installBaiduImageryProvider()
|
||
this._installGooGleImageryProvider()
|
||
this._installAmapImageryProvider()
|
||
this._installTencentImageryProvider()
|
||
this._installTdtImageryProvider()
|
||
this._installMaterial()
|
||
this._installPlugin()
|
||
this._installPrimitives()
|
||
}
|
||
},
|
||
/**
|
||
* 获取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") {
|
||
// window.D3Kit = D3Kit
|
||
// // Cesium.D3Kit = D3Kit;
|
||
// }
|
||
|
||
console.clear()
|
||
console.log(
|
||
`%c \n D3-KIT \n %c \n 基于Cesium三维拓展包 %c \n
|
||
版本:${version}
|
||
作者:${author}
|
||
主页: http://www.ztwow.top
|
||
github: ${github}
|
||
示例地址: ${examplesAddr}
|
||
Cesium版本:${CesiumVersion}
|
||
版权声明:
|
||
1.代码包基于Cesium拓展,部分模块开源已上传github。
|
||
2.后续会继续更新拓展,目前该代码包不开源,如需使用:
|
||
1)代码包的完整引用
|
||
2)此版权信息在控制台输出
|
||
我方保留对此版权信息的最终解释权。`,
|
||
'font-size:20px;padding-left:70px;color:#EEB422',
|
||
'font-size:14px;padding-left:50px;color:#EEB422;font-style:oblique',
|
||
'font-size:14px;color:#0865ba'
|
||
)
|
||
|
||
return _
|
||
})();
|
||
|
||
// export default {};
|