cesium-city3d/cesium-d3kit.js

7685 lines
354 KiB
JavaScript
Raw Normal View History

; 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 {};