cesium-city3d/cesium-d3kit.js

7685 lines
354 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

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