cesium 坐标简述
1、常用坐标转换API
API | 说明 |
---|---|
Cesium.Cartographic.fromCartesian(cartesian, ellipsoid, result) | 笛卡尔转弧度 |
Cesium.Cartographic.fromDegrees(longitude, latitude, height, result) | 经纬度转弧度(度单位) |
Cesium.CesiumMath.toDegrees(radians) | 弧度转度 |
Cesium.CesiumMath.toRadians(degrees) | 度转弧度 |
Cesium.Cartographic.fromRadians(longitude, latitude, height, result) | 经纬度转弧度(弧度单位) |
Cesium.Cartographic.toCartesian(cartographic, ellipsoid, result) | 弧度转笛卡尔 |
var pick1= scene.globe.pick(viewer.camera.getPickRay(pt1), scene) //其中pt1为一个二维屏幕坐标 | 平面坐标转三维坐标(其实都是笛卡尔坐标) |
var geoPt1= scene.globe.ellipsoid.cartesianToCartographic(pick1) //其中pick1是一个Cesium.Cartesian3对象 | 笛卡尔三维坐标转地理坐标 |
var point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180]; //其中geoPt1是一个地理坐标 | 地理坐标转经纬度 |
var cartographic = Cesium.Cartographic.fromDegree(point) //point是经纬度值 | 经纬度转地理坐标(弧度) |
var coord_wgs84 = Cesium.Cartographic.fromDegrees(lng, lat, alt);//单位:度,度,米 | 经纬度转地理坐标 |
var cartesian = Cesium.Cartesian3.fromDegree(point) | 经纬度转笛卡尔坐标 |
2、笛卡尔坐标系api
API | 说明 |
---|---|
Cesium.Cartesian3.abs(cartesian, result) | 计算绝对值 |
Cesium.Cartesian3.add(left, right, result) | 计算两个笛卡尔的分量和 |
Cesium.Cartesian3.angleBetween(left, right) | 计算角度(弧度制) |
Cesium.Cartesian3.cross(left, right, result) | 计算叉积 |
Cesium.Cartesian3.distance(left, right) | 计算两点距离 |
Cesium.Cartesian3.distanceSquared(left, right) | 计算两点平方距离 |
Cesium.Cartesian3.divideByScalar(cartesian, scalar, result) | 计算标量除法 |
Cesium.Cartesian3.divideComponents(left, right, result) | 计算两点除法 |
Cesium.Cartesian3.dot(left, right) 计算点乘 | |
Cesium.Cartesian3.equals(left, right) | 比较两点是否相等 |
Cesium.Cartesian3.fromArray(array, startingIndex, result) | 从数组中提取3个数构建笛卡尔坐标 |
Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result) | 将将纬度转换为笛卡尔坐标(单位是度°) |
Cesium.Cartesian3.fromDegreesArray(coordinates, ellipsoid, result) | 返回给定经度和纬度值数组(以度为单位)的笛卡尔位置数组。 |
Cesium.Cartesian3.fromDegreesArrayHeights(coordinates, ellipsoid, result) | 返回给定经度,纬度和高度的笛卡尔位置数组 |
Cesium.Cartesian3.fromElements(x, y, z, result) | 创建一个新的笛卡尔坐标 |
Cesium.Cartesian3.fromRadians(longitude, latitude, height, ellipsoid, result) | 返回笛卡尔坐标以弧度制的经纬度 |
Cesium.Cartesian3.fromRadiansArray(coordinates, ellipsoid, result) | 返回笛卡尔坐标以弧度制的经纬度数组 |
Cesium.Cartesian3.fromRadiansArrayHeights(coordinates, ellipsoid, result) | 返回笛卡尔坐标以弧度制的经纬度高度数组 |
Cesium.Cartesian3.fromSpherical(spherical, result) | 将提供的球面转换为笛卡尔系 |
Cesium.Cartesian3.lerp(start, end, t, result) | 使用提供的笛卡尔数来计算t处的线性插值或外推。 |
Cesium.Cartesian3.magnitude(cartesian) | 计算笛卡尔长度 |
Cesium.Cartesian3.magnitudeSquared(cartesian) | 计算提供的笛卡尔平方量级 |
Cesium.Cartesian3.maximumByComponent(first, second, result) | 比较两个笛卡尔并计算包含所提供笛卡尔最大成分的笛卡尔。 |
Cesium.Cartesian3.maximumComponent(cartesian) | 计算所提供笛卡尔坐标系的最大分量的值 |
Cesium.Cartesian3.midpoint(left, right, result) | 计算右笛卡尔和左笛卡尔之间的中点 |
Cesium.Cartesian3.minimumByComponent(first, second, result) | 比较两个笛卡尔并计算包含所提供笛卡尔的最小分量的笛卡尔 |
Cesium.Cartesian3.minimumComponent(cartesian) | 计算所提供笛卡尔坐标系的最小分量的值 |
Cesium.Cartesian3.mostOrthogonalAxis(cartesian, result) | 返回与提供的笛卡尔坐标最正交的轴 |
Cesium.Cartesian3.multiplyByScalar(cartesian, scalar, result) | 将提供的笛卡尔分量乘以提供的标量 |
Cesium.Cartesian3.multiplyComponents(left, right, result) | 计算两个笛卡尔的分量积 |
Cesium.Cartesian3.normalize(cartesian, result) | 计算所提供笛卡尔的规范化形式 |
Cesium.Cartesian3.pack(value, array, startingIndex) | 将提供的实例存储到提供的数组中 |
Cesium.Cartesian3.projectVector(a, b, result) | 将向量a投影到向量b上 |
Cesium.Cartesian3.subtract(left, right, result) | 计算两个笛卡尔分量差 |
Cesium.Cartesian3.unpack(array, startingIndex, result) | 从压缩的数组中检索实例 |
Cesium.Cartesian3.unpackArray(array, result) | 将笛卡尔分量数组解包为笛卡尔数组 |
cesium 代码应用
1、获取三位场景下的相机位置
getMapCameraInfo(cesiumScene) {
//相机姿态
var d = cesiumScene.camera;
var heading = Cesium.Math.toDegrees(d.heading);
var pitch = Cesium.Math.toDegrees(d.pitch);
var roll = Cesium.Math.toDegrees(d.roll);
let i = cesiumScene.camera.positionCartographic;
let lat = Cesium.Math.toDegrees(i.latitude);
let lng = Cesium.Math.toDegrees(i.longitude);
console.log({
heading: heading,
pitch: pitch,
roll: roll,
lng: lng,
lat: lat,
height: i.height
});
},
2、地图左键点击事件
mapFunction.leftClick = new Cesium.ScreenSpaceEventHandler(
cesiumView.scene.canvas
)
mapFunction.leftClick.setInputAction((click) => {
var pick = cesiumView.scene.pick(click.position)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
//=======================================
// 地图事件
mapEvent (cesiumView, config) {
mapEvent = new Cesium.ScreenSpaceEventHandler(cesiumView.scene.canvas);
mapEvent.setInputAction((click) => {
// let pos = getScale(click.endPosition);
// var pick = cesiumView.scene.pick(new Cesium.Cartesian2(pos.x, pos.y));
var pick = cesiumView.scene.pick(click.endPosition);
if (pick && pick.id && pick.id.id) {
document.body.style = "cursor: pointer;";
} else {
document.body.style = "cursor: default;";
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
mapEvent.setInputAction((click) => {
// let pos = getScale(click.position);
// var pick = cesiumView.scene.pick(new Cesium.Cartesian2(pos.x, pos.y));
var pick = cesiumView.scene.pick(click.position);
if (pick && pick.id && pick.id.extendedData && pick.id.id) {
console.log(pick.id.extendedData)
let extendedData = pick.id.extendedData;
this.clickChangePointIcon(pick.id);
// 展示数据框
// $('#mapInfoBox').show()
// this.setInfoPosition(cesiumView, extendedData.lng, extendedData.lat)
// this.setHtmlDataText(extendedData, config)
// this.clickState = true
} else {
console.log("none")
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
1.移除鼠标事件
//方式一
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除事件
//方式二
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
2.事件类型
Cesium.ScreenSpaceEventType.LEFT_CLICK //鼠标左击事件
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK //鼠标左键双击事件
Cesium.ScreenSpaceEventType.LEFT_DOWN //左键鼠标按下事件
Cesium.ScreenSpaceEventType.LEFT_UP //左键鼠标抬起事件
Cesium.ScreenSpaceEventType.MIDDLE_CLICK //中键单机
Cesium.ScreenSpaceEventType.MIDDLE_DOWN //中键按下
Cesium.ScreenSpaceEventType.MIDDLE_UP //中键抬起
Cesium.ScreenSpaceEventType.MOUSE_MOVE //鼠标移动
Cesium.ScreenSpaceEventType.PINCH_END //表示两指事件在触摸面上的结束。
Cesium.ScreenSpaceEventType.PINCH_MOVE //两指移动
Cesium.ScreenSpaceEventType.PINCH_START //表示在触摸面上发生两指事件的开始。
Cesium.ScreenSpaceEventType.RIGHT_CLICK //鼠标右击事件
Cesium.ScreenSpaceEventType.RIGHT_DOWN //鼠标右键按下
Cesium.ScreenSpaceEventType.RIGHT_UP //鼠标右键抬起s
3、设置地图视角
mapFlyTo (style) {
let initialPosition = Cesium.Cartesian3.fromDegrees(
style.lng,
style.lat,
style.height
)
let initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(
style.heading,
style.pitch,
style.roll
) //初始化相机对准方向1:左右摆动角度;2:上下俯仰角度;3:相机翻滚角度
cesiumScene.camera.setView({
destination: initialPosition,
orientation: initialOrientation,
endTransform: Cesium.Matrix4.IDENTITY,
})
},
4、创建线的材质样式
// 构建管线贴片
loadGXStyle (url, color, Speed) {
function PolylineTrailLinkMaterialProperty(color, duration) {
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._colorSubscription = undefined
this.color = color
this.duration = duration
this._time = new Date().getTime()
}
Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
isConstant: {
get: function () {
return false
},
},
definitionChanged: {
get: function () {
return this._definitionChanged
},
},
color: Cesium.createPropertyDescriptor('color'),
})
PolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
return 'PolylineTrailLink'
}
PolylineTrailLinkMaterialProperty.prototype.getValue = function (
time,
result
) {
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
)
result.image = Cesium.Material.PolylineTrailLinkImage
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration
return result
}
PolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof PolylineTrailLinkMaterialProperty &&
Property.equals(this._color, other._color))
)
}
Cesium.PolylineTrailLinkMaterialProperty = PolylineTrailLinkMaterialProperty
Cesium.Material.PolylineTrailLinkType = 'PolylineTrailLink'
Cesium.Material.PolylineTrailLinkImage = url
Cesium.Material.PolylineTrailLinkSource =
'czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));\n\
material.alpha = colorImage.a * color.a;\n\
material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\
return material;\n\
}'
Cesium.Material._materialCache.addMaterial(
Cesium.Material.PolylineTrailLinkType, {
fabric: {
type: Cesium.Material.PolylineTrailLinkType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
image: Cesium.Material.PolylineTrailLinkImage,
time: 0,
},
source: Cesium.Material.PolylineTrailLinkSource,
},
translucent: function (material) {
return true
},
}
)
var material = new Cesium.PolylineTrailLinkMaterialProperty(
color,
Speed || 10000
)
return new Promise((resolve, reject) => {
resolve(material)
})
},
5、实线和虚线
//正常线
var scene = viewer.scene;
var primitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray([120.0,40.0,100.0,30.0]),
width:3.0,
vertexFormat:Cesium.PolylineColorAppearance.VERTEX_FORMAT
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
}
}),
appearance: new Cesium.PolylineColorAppearance({
translucent: false, //是否透明
})
});
scene.primitives.add(primitive);
//虚线
var primitive1 = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray([110.0,50.0,120.0,60.0]),
width:3.0,
vertexFormat:Cesium.PolylineColorAppearance.VERTEX_FORMAT
})
}),
appearance: new Cesium.PolylineMaterialAppearance({
material: Cesium.Material.fromType(Cesium.Material.PolylineDashType, {
color: Cesium.Color.CYAN, //线条颜色
gapColor:Cesium.Color.TRANSPARENT, //间隔颜色
dashLength:20 //短划线长度
})
})
});
scene.primitives.add(primitive1);
6、cesium画贴地线
1. Entity 实现方式
Polyline对象的clampToGround属性设置为true。
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(line),
width: 10,
clampToGround: true,//开启贴地
material: Cesium.Color.RED
}
});
2. Primitive 实现方式
需要使用GroundPolylinePrimitive和GroundPolylineGeometry来创建Primitive与Geometry对象,而不是使用Primitive和PolylineGeometry创建Primitive与Geometry对象。
viewer.scene.primitives.add(new Cesium.GroundPolylinePrimitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.GroundPolylineGeometry({
positions : Cesium.Cartesian3.fromDegreesArray(positions[i]),
width : 15.0,//线宽
vertexFormat : Cesium.PolylineColorAppearance.VERTEX_FORMAT
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(
new Cesium.Color.fromCssColorString("#0096ff")),
}
}),
appearance : new Cesium.PolylineColorAppearance({
translucent : false
})
}));
7、圆形区域闪烁
function twinkleCircle() {
var x = 1;
var flog = true;
dataSourse.entities.add({
name: "圆形区域闪烁",
position: Cesium.Cartesian3.fromDegrees(pointItem[0], pointItem[1], 0),
ellipse: {
semiMinorAxis: 5000.0,
semiMajorAxis: 5000.0,
height: 350,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(function() {
if (flog) {
x = x - 0.05;
if (x <= 0) {
flog = false;
}
} else {
x = x + 0.05;
if (x >= 1) {
flog = true;
}
}
return Cesium.Color.RED.withAlpha(x);
}, false))
}
});
}
twinkleCircle()
8、半圆报警扫描
注意地形遮挡问题:
cesiumView.scene.globe.depthTestAgainstTerrain = true; //控制视角,能被地形遮挡
// 构建报警贴图
// 报警
AddCircleScanPostStage: function (
viewer,
cartographicCenter,
maxRadius,
scanColor,
duration
) {
var ScanSegmentShader =
"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" +
"vec4 toEye(in vec2 uv, in float depth)\n" +
" {\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" +
"vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)\n" +
"{\n" +
"vec3 v01 = point -planeOrigin;\n" +
"float d = dot(planeNormal, v01) ;\n" +
"return (point - planeNormal * d);\n" +
"}\n" +
"float getDepth(in vec4 depth)\n" +
"{\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" +
"void main()\n" +
"{\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" +
"{\n" +
"float f = 1.0 -abs(u_radius - dis) / u_radius;\n" +
"f = pow(f, 4.0);\n" +
"gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n" +
"}\n" +
"}\n";
var _Cartesian3Center = Cesium.Cartographic.toCartesian(
cartographicCenter
);
var _Cartesian4Center = new Cesium.Cartesian4(
_Cartesian3Center.x,
_Cartesian3Center.y,
_Cartesian3Center.z,
1
);
var _CartographicCenter1 = new Cesium.Cartographic(
cartographicCenter.longitude,
cartographicCenter.latitude,
cartographicCenter.height + 500
);
var _Cartesian3Center1 = Cesium.Cartographic.toCartesian(
_CartographicCenter1
);
var _Cartesian4Center1 = new Cesium.Cartesian4(
_Cartesian3Center1.x,
_Cartesian3Center1.y,
_Cartesian3Center1.z,
1
);
var _time = new Date().getTime();
var _scratchCartesian4Center = new Cesium.Cartesian4();
var _scratchCartesian4Center1 = new Cesium.Cartesian4();
var _scratchCartesian3Normal = new Cesium.Cartesian3();
let pScanPostStage = new Cesium.PostProcessStage({
fragmentShader: ScanSegmentShader,
uniforms: {
u_scanCenterEC: function () {
return Cesium.Matrix4.multiplyByVector(
viewer.camera._viewMatrix,
_Cartesian4Center,
_scratchCartesian4Center
);
},
u_scanPlaneNormalEC: function () {
var temp = Cesium.Matrix4.multiplyByVector(
viewer.camera._viewMatrix,
_Cartesian4Center,
_scratchCartesian4Center
);
var temp1 = Cesium.Matrix4.multiplyByVector(
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_radius: function () {
return (
(maxRadius * ((new Date().getTime() - _time) % duration)) /
duration
);
},
u_scanColor: scanColor,
},
});
viewer.scene.postProcessStages.add(pScanPostStage);
return pScanPostStage;
},
9、获取点击地图后的经纬度信息
方法1
// 获取点击的POI点位
// 点击的坐标
// var pick = scene.pick(movement.position)
let location = this.viewer.scene.pickPosition(movement.position)
//如果定义了对象,则返回true,否则返回false。
var pickedEntity = Cesium.defined(pick) ? pick.id : undefined //pick.id即为entity
var cartographic = new Cesium.Cartographic.fromCartesian(
location,
this.viewer.scene.globe.ellipsoid
)
var lat = Cesium.Math.toDegrees(cartographic.latitude)
var lng = Cesium.Math.toDegrees(cartographic.longitude)
// console.log(pickedEntity)
// console.log(pick)
console.log('经度:' + lng + ',' + '纬度:' + lat)
//获取点击的POI点位END
方法2
/*************************右键点击返回经纬度**********************/
var handler = new Cesium.ScreenSpaceEventHandler(cesiumView.scene.canvas);
handler.setInputAction(function(event) {
var earthPosition = cesiumView.camera.pickEllipsoid(event.position, cesiumView.scene.globe.ellipsoid);
var cartographic = Cesium.Cartographic.fromCartesian(earthPosition, cesiumView.scene.globe.ellipsoid, new Cesium.Cartographic());
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lng = Cesium.Math.toDegrees(cartographic.longitude);
var height = cartographic.height;
console.log(lng + "," + lat);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
10、地图视角飞入,调整地图视角
// 视角参数
let configMapSceneStyle = {
lng: 108.52866036065753,
lat: 30.293739782135887,
height: 403217.96718934656,
heading: 0.6311843412704754,
pitch: -40.852126070429755,
roll: 359.9998440596327,
brightness: 0.2,
saturation: 0.2,
}
// 地图视角fly
function mapFlyTo(style) {
let initialPosition = Cesium.Cartesian3.fromDegrees(
style.lng,
style.lat,
style.height
);
let initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(
style.heading,
style.pitch,
style.roll
); //初始化相机对准方向1:左右摆动角度;2:上下俯仰角度;3:相机翻滚角度
cesiumScene.camera.setView({
destination: initialPosition,
orientation: initialOrientation,
endTransform: Cesium.Matrix4.IDENTITY,
});
},
11、地图的鼠标移动事件
mapMoveEvent() {
mapFunction.move = new Cesium.ScreenSpaceEventHandler(cesiumView.scene.canvas);
mapFunction.move.setInputAction((click) => {
var pick = cesiumView.scene.pick(click.endPosition);
if (pick && pick.id.id) {
document.body.style = "cursor: pointer;";
} else {
document.body.style = "cursor: default;";
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
12、设置地图泛光效果
/*************************开始-设置屏幕泛光【周浩20200923增加】**********************/
var stages = cesiumScene.postProcessStages;
cesiumScene.brightness = cesiumScene.brightness || stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage());
cesiumScene.brightness.enabled = true;
cesiumScene.brightness.uniforms.brightness = Number(2);
var viewModel = {
contrast: 110, //128
brightness: -0.3, //-0.3
delta: 1, //设置泛光度 1.0
sigma: 3.78, //3.78
stepSize: 5.0, //5.0
}
var bloom = cesiumScene.postProcessStages.bloom
bloom.enabled = true
bloom.uniforms.glowOnly = false
bloom.uniforms.contrast = Number(viewModel.contrast)
bloom.uniforms.brightness = Number(viewModel.brightness)
bloom.uniforms.delta = Number(viewModel.delta)
bloom.uniforms.sigma = Number(viewModel.sigma)
bloom.uniforms.stepSize = Number(viewModel.stepSize)
/*************************结束-设置屏幕泛光**********************/
13、cesium的地图初始化
const pTileProvider = new Cesium.ArcGisMapServerImageryProvider({
//影像瓦片驱动
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer',
// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer',
})
// terrainProvider = new Cesium.CesiumTerrainProvider({ //地形瓦片驱动
// url: terrainProviderUrl
// });
cesiumView = new Cesium.Viewer("mapBox", {
animation: false, //是否显示动画控件
shouldAnimate: true,
homeButton: false, //是否显示Home按钮
fullscreenButton: false, //是否显示全屏按钮
baseLayerPicker: false, //是否显示图层选择控件
geocoder: false, //是否显示地名查找控件
timeline: false, //是否显示时间线控件
sceneModePicker: true, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
infoBox: false, //是否显示点击要素之后显示的信息
// infoBox: true, //是否显示点击要素之后显示的信息
// requestRenderMode: true, //启用请求渲染模式
requestRenderMode: false, //启用请求渲染模式
scene3DOnly: true, //每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
// fullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处
selectionIndicator: false,
// terrainProvider: terrainProvider,
imageryProvider: pTileProvider,
skyAtmosphere: false,
});
this.measure = new Cesium.Measure(cesiumView); // 测量面板 见cesium的插件引用
cesiumScene = cesiumView.scene;
cesiumView.scene.globe.depthTestAgainstTerrain = false; //控制视角,能被地形遮挡
cesiumEllipsoid = cesiumScene.globe.ellipsoid;
cesiumView._cesiumWidget._creditContainer.style.display = "none";
14、设置墙向上的流动效果
// 生成场站范围区域动效,从下往上
loadAreaStyle: function() {
function PolylineTrailLinkMaterialProperty(color, duration) {
this._definitionChanged = new Cesium.Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = color;
this.duration = duration;
this._time = new Date().getTime();
}
Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
isConstant: {
get: function() {
return false;
},
},
definitionChanged: {
get: function() {
return this._definitionChanged;
},
},
color: Cesium.createPropertyDescriptor("color"),
});
PolylineTrailLinkMaterialProperty.prototype.getType = function(time) {
return "PolylineTrailLink";
};
PolylineTrailLinkMaterialProperty.prototype.getValue = function(time, result) {
if (!Cesium.defined(result)) {
result = {};
}
result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
result.image = Cesium.Material.PolylineTrailLinkImage;
result.time = ((new Date().getTime() - this._time) % this.duration) / this.duration;
return result;
};
PolylineTrailLinkMaterialProperty.prototype.equals = function(other) {
return (this === other || (other instanceof PolylineTrailLinkMaterialProperty && Property.equals(this._color, other._color)));
};
Cesium.PolylineTrailLinkMaterialProperty = PolylineTrailLinkMaterialProperty;
Cesium.Material.PolylineTrailLinkType = "PolylineTrailLink";
//---------------------------------------------设置图片url ---------------------------------------------
Cesium.Material.PolylineTrailLinkImage = wallpng;
//---------------------------------------------设置流动方式 ---------------------------------------------
// 着色器代码
Cesium.Material.PolylineTrailLinkSource = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = materialInput.st;\n\
vec4 colorImage = texture2D(image, vec2(fract(st.t - time), st.t));\n\
material.alpha = colorImage.a * color.a;\n\
material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\
return material;\n\
}";
Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineTrailLinkType, {
fabric: {
type: Cesium.Material.PolylineTrailLinkType,
uniforms: {
color: new Cesium.Color(0.0, 0.0, 0.0, 1),
image: Cesium.Material.PolylineTrailLinkImage,
time: 0,
},
source: Cesium.Material.PolylineTrailLinkSource,
},
translucent: function(material) {
return true;
},
});
/*-------------------------调用示例颜色 时间(速度) ----------------------------*/
// 材质
this.p_material = new Cesium.PolylineTrailLinkMaterialProperty(Cesium.Color.FUCHSIA.withAlpha(1), 500);
},
15、添加点图层
1、Entity 添加点图层
// 创建point Entity数据集
const pointLayer = new Cesium.CustomDataSource("pointLayer");
// 向地图里面添加数据集
viewer.dataSources.add(pointLayer);
loadchangzhan(pointData, pointLayer) {
pointData.forEach((item) => {
let type = "场站";
let entityObj = {
name: "点点点",
id: item.id + "&" + type,
position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 10),
show: true,
billboard: {
image: icon,
scale: 0.5,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 135000),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
label: {
text: "加点",
font: 14 + "px sans-serif",
pixelOffset: new Cesium.Cartesian2(0.0, -55),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 80000),
fillColor: Cesium.Color.AQUA,
showBackground: true,
backgroundColor: new Cesium.Color(0, 0, 0, 0.5),
},
};
entityObj.addProperty("extendedData");
entityObj.extendedData = properties;
entityObj.extendedData['lng'] = pointDataArray[0].toFixed(6);
entityObj.extendedData['lat'] = pointDataArray[1].toFixed(6);
this.pointLayer.entities.add(entityObj);
pointLayer.entities.add(entityObj);
});
}
2、Primitives 添加点图层
billboardParams: {
name: '图标参数设置',
type: 'group',
children: {
imgUrl: {
name: '图标URL',
type: 'input',
def: 'http://localhost:8089/icon/point.png'
},
imgWidth: {
name: '图标宽',
type: 'input',
def: '20'
},
imgHeight: {
name: '图标高',
type: 'input',
def: '20'
},
imgScale: {
name: '图标缩放比',
type: 'input',
def: '1'
},
billboardsHeight: {
name: '图标基于地面的高度',
type: 'input',
def: '20'
},
}
},
labelParams: {
name: '标签参数设置',
type: 'group',
children: {
labelFont: {
name: '标签字体和大小',
type: 'input',
def: '14px sans-serif'
},
labelColor: {
name: '标签颜色(RGBA)',
type: 'input',
def: '233,34,234,0.9'
},
labelBackgroundColor: {
name: '背景颜色(RGBA)',
type: 'input',
def: '233,255,255,0.9'
},
labelBackgroundShow: {
name: '背景显隐',
type: 'input',
def: 'true'
},
labelScale: {
name: '字体缩放比',
type: 'input',
def: '1'
},
labelPixelOffset: {
name: '标签偏移',
type: 'input',
def: '0,-10'
},
}
}
// 3、添加点注记
addPointInstance (cesiumScene, features, options) {
function addPoint (cesiumScene) {
// 创建广告牌的primitive
this.billboards = cesiumScene.primitives.add(
new Cesium.BillboardCollection()
);
// 创建标注的primitive
this.labels = cesiumScene.primitives.add(new Cesium.LabelCollection());
// 创建集合
this.pointDataCollection = new Cesium.PrimitiveCollection();
this.billboardParams = options.billboardParams;
this.labelParams = options.labelParams
}
addPoint.prototype.getPointDataFeatures = function () {
return features;
};
addPoint.prototype.addPointCollection = function () {
// 添加集合
this.pointDataCollection.add(this.billboards, 0);
this.pointDataCollection.add(this.labels, 1);
};
addPoint.prototype.addLabelBillboards = function () {
let labelColor = this.labelParams.labelColor.split(',').map(Number)
let labelBackgroundColor = this.labelParams.labelBackgroundColor.split(',').map(Number)
let labelPixelOffset = this.labelParams.labelPixelOffset.split(',').map(Number)
for (let i = 0; i < features.length; i++) {
const pointDataArray = features[i].geometry.coordinates;
const properties = features[i].properties;
// add Label
this.labels.add({
show: true,
position: Cesium.Cartesian3.fromDegrees(
pointDataArray[0],
pointDataArray[1]
),
id: properties.id,
text: properties.name,
font: this.labelParams.labelFont,
fillColor: new Cesium.Color(labelColor[0] / 255, labelColor[1] / 255, labelColor[2] / 255, labelColor[3]),
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
showBackground: eval(this.labelParams.labelBackgroundShow),
backgroundColor: new Cesium.Color(labelBackgroundColor[0] / 255, labelBackgroundColor[1] / 255, labelBackgroundColor[2] / 255, labelBackgroundColor[3]),
backgroundPadding: new Cesium.Cartesian2(7, 5),
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(labelPixelOffset[0], labelPixelOffset[1]),
// eyeOffset: Cesium.Cartesian3.ZERO,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
scale: eval(this.labelParams.labelScale)
// translucencyByDistance: undefined,
// pixelOffsetScaleByDistance: undefined,
// heightReference: HeightReference.NONE // 基础的高度参考
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 50000) // 该条件指定将在距摄像机的距离显示此广告牌。
});
// add BillBoards
this.billboards.add({
show: true,
position: Cesium.Cartesian3.fromDegrees(
pointDataArray[0],
pointDataArray[1],
eval(this.billboardParams.billboardsHeight)
),
// pixelOffset: Cesium.Cartesian2.ZERO,
// eyeOffset: Cesium.Cartesian3.ZERO,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, //RELATIVE===CLAMP_TO_GROUND===NONE,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
scale: eval(this.billboardParams.imgScale),
image: this.billboardParams.imgUrl,
// imageSubRegion: undefined,
color: Cesium.Color.WHITE,
id: properties.id,
rotation: 0.0, // 获取或设置弧度的旋转角度。
width: eval(this.billboardParams.imgWidth),
height: eval(this.billboardParams.imgHeight),
// scaleByDistance: undefined,
// translucencyByDistance: undefined,
// pixelOffsetScaleByDistance: undefined,
sizeInMeters: false // 设置广告牌大小是否以米或像素为单位。 true 以米为单位确定广告牌的大小;否则,大小以像素为单位。
// distanceDisplayCondition: undefined
});
}
};
addPoint.prototype.showPoint = function (show) {
const billboards = this.pointDataCollection.get(0)._billboards;
const labels = this.pointDataCollection.get(1)._labels;
billboards.forEach(billboard => {
billboard.show = show;
});
labels.forEach(label => {
label.show = show;
});
};
Object.defineProperties(addPoint.prototype, {});
return new addPoint(cesiumScene);
}
16、Entity 添加线图层
// 创建polyline Entity数据集
const polylineLayer = new Cesium.CustomDataSource("polylineLayer");
viewer.dataSources.add(polylineLayer);
// 向地图里面添加数据集
initMainGuanXian(polylineData, polylineLayer) {
let lineColor = lineColor = new Cesium.Color(220 / 255, 20 / 255, 60 / 255, 1)
let type = "管线";
polylineData.forEach((item) = > {
let lineDataCoor = item.coordinateList || item.data;
layerType.entities.add({
name: "管线",
id: item.id + "&" + type
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(item.arr),
width: 3,
material: lineColor,
// material: guanxianStyle.success,
clampToGround: true,
},
});
}
17、cesium信息框动态显示并跟随移动(高度会影响定位精度)
export function htmlFixed(viewer, domId) {
const htmlOverlay = document.getElementById(domId);
const domHeight = htmlOverlay.offsetHeight; // DOM的高度
const domWidth = htmlOverlay.offsetWidth; // DOM的宽度
const heightOffset = 20; // Y轴偏移量
const widthOffset = -9; // X轴偏移量
const scratch = new Cesium.Cartesian2();
cesiumView.scene.preRender.addEventListener(function () {
let position = Cesium.Cartesian3.fromDegrees(lnglat[0], lnglat[1], 2);
let canvasPosition = cesiumView.scene.cartesianToCanvasCoordinates(position, scratch);
if (Cesium.defined(canvasPosition)) {
htmlOverlay.style.top = canvasPosition.y - domHeight - heightOffset + 'px';
htmlOverlay.style.left = canvasPosition.x - domWidth / 2 - widthOffset + 'px';
}
});
}
// DOM绑定数据
// <div v-infoBoxPosition="(that)"
// class="info-box-position"
// v-for="(item,index) in infoBoxPosition"
// :key=index
// :data-position=item.lnglat>
// 自定义组件
directives: {
infoBoxPosition (el, binding) {
let height = cesiumScene.camera.positionCartographic.height;
// 当相机的高度大于700000,信息框就隐藏
if (height > 700000) {
binding.value.infoBoxPositionShow = false
} else {
binding.value.infoBoxPositionShow = true
}
const dispradius = el.dataset.position.split(",")
const scratch = new Cesium.Cartesian2();
cesiumView.scene.preRender.addEventListener(() => {
let position = Cesium.Cartesian3.fromDegrees(dispradius[0], dispradius[1], 100);
let canvasPosition = cesiumView.scene.cartesianToCanvasCoordinates(position, scratch);
if (Cesium.defined(canvasPosition)) {
el.style.top = canvasPosition.y + 'px';
el.style.left = canvasPosition.x + 'px';
}
});
}
}
18、相机监听、获取中心点坐标、高度、当前可视区域范围
/* 三维球转动添加监听事件 */
viewer.camera.changed.addEventListener(function (percentage) {
getCenterPosition();
getCurrentExtent();
// 打印中心点坐标、高度、当前范围坐标
console.log(getCenterPosition());
console.log("bounds",getCurrentExtent());
});
/* 获取camera高度 */
function getHeight() {
if (viewer) {
var scene = viewer.scene;
var ellipsoid = scene.globe.ellipsoid;
var height = ellipsoid.cartesianToCartographic(viewer.camera.position).height;
return height;
}
}
/* 获取camera中心点坐标 */
function getCenterPosition() {
var result = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas
.clientHeight / 2));
var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
var lon = curPosition.longitude * 180 / Math.PI;
var lat = curPosition.latitude * 180 / Math.PI;
var height = getHeight();
return {
lon: lon,
lat: lat,
height: height
};
}
function getCurrentExtent() {
// 范围对象
var extent = {};
// 得到当前三维场景
var scene = viewer.scene;
// 得到当前三维场景的椭球体
var ellipsoid = scene.globe.ellipsoid;
var canvas = scene.canvas;
// canvas左上角
var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);
// canvas右下角
var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);
// 当canvas左上角和右下角全部在椭球体上
if (car3_lt && car3_rb) {
var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
}
// 当canvas左上角不在但右下角在椭球体上
else if (!car3_lt && car3_rb) {
var car3_lt2 = null;
var yIndex = 0;
do {
// 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
yIndex <= canvas.height ? yIndex += 10 : canvas.height;
car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);
} while (!car3_lt2);
var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
}
// 获取高度
extent.height = Math.ceil(viewer.camera.positionCartographic.height);
return extent;
}
19、地图放大缩小、经纬度显示
// 放大缩小
document.getElementById('zoomIn').onclick = function () {
// 获取当前镜头位置的笛卡尔坐标
let cameraPos = viewer.camera.position;
// 获取当前坐标系标准
let ellipsoid = viewer.scene.globe.ellipsoid;
// 根据坐标系标准,将笛卡尔坐标转换为地理坐标
let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
// 获取镜头的高度
let height = cartographic.height;
// if (height < 40) {
// return
// }
// 镜头拉近
viewer.camera.zoomIn(height / 3);
};
document.getElementById('zoomOut').onclick = function () {
// 获取当前镜头位置的笛卡尔坐标
let cameraPos = viewer.camera.position;
// 获取当前坐标系标准
let ellipsoid = viewer.scene.globe.ellipsoid;
// 根据坐标系标准,将笛卡尔坐标转换为地理坐标
let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
// 获取镜头的高度
let height = cartographic.height;
// if (height < 40) {
// return
// }
// 镜头拉近
viewer.camera.zoomOut(height * 1.2);
};
//经纬度显示
viewer.screenSpaceEventHandler.setInputAction(function (event) {
var earthPosition = viewer.camera.pickEllipsoid(
event.position,
viewer.scene.globe.ellipsoid
);
var cartographic = Cesium.Cartographic.fromCartesian(
earthPosition,
viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lng = Cesium.Math.toDegrees(cartographic.longitude);
var height = viewer.camera.positionCartographic.height;
document.getElementById('infobox').innerHTML =
'<span>经度:' +
lng.toFixed(3) +
'</span>' +
'<span> 纬度:' +
lat.toFixed(3) +
'</span>' +
'<span> 相机高度:' +
height +
'</span>';
console.log(lat, lng, height);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
20、RGBA 方法
String.prototype.colorHex = function () {
// RGB颜色值的正则
var reg = /^(rgb|RGB)/;
var color = this;
if (reg.test(color)) {
var strHex = "#";
// 把RGB的3个数值变成数组
var colorArr = color.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
// 转成16进制
for (var i = 0; i < colorArr.length; i++) {
var hex = Number(colorArr[i]).toString(16);
if (hex === "0") {
hex += hex;
}
strHex += hex;
}
return strHex;
} else {
return String(color);
}
};
String.prototype.colorRgb = function () {
// 16进制颜色值的正则
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
// 把颜色值变成小写
var color = this.toLowerCase();
if (reg.test(color)) {
// 如果只有三位的值,需变成六位,如:#fff => #ffffff
if (color.length === 4) {
var colorNew = "#";
for (var i = 1; i < 4; i += 1) {
colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
}
color = colorNew;
}
// 处理六位的颜色值,转为RGB
var colorChange = [];
for (var i = 1; i < 7; i += 2) {
colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
}
return "RGB(" + colorChange.join(",") + ")";
} else {
return color;
}
};
21、CESIUM 模型加载
var hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(45), 0, 0);
var position = Cesium.Cartesian3.fromDegrees(
featureItem[0] || featureItem.lon,
featureItem[1] || featureItem.lat,
2
);
let entityObj = new Cesium.Entity({
name: String(index),
id: featureItem[1],
position: position,
orientation: Cesium.Transforms.headingPitchRollQuaternion(position, hpr) // 方向
}
方法一:
function createModel(url, height) {
viewer.entities.removeAll();
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
name : url,
position : position,
orientation : orientation,
model : {
uri : url,
minimumPixelSize : 128,
maximumScale : 20000
}
});
viewer.trackedEntity = entity;
}
方法二:
function createModel(url, height, heading, pitch, roll) {
height = Cesium.defaultValue(height, 0.0);
heading = Cesium.defaultValue(heading, 0.0);
pitch = Cesium.defaultValue(pitch, 0.0);
roll = Cesium.defaultValue(roll, 0.0);
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, hpr);
scene.primitives.removeAll(); // Remove previous model
model = scene.primitives.add(Cesium.Model.fromGltf({
url : url,
modelMatrix : modelMatrix,
minimumPixelSize : 128
}));
model.readyPromise.then(function(model) {
model.color = Cesium.Color.fromAlpha(getColor(viewModel.color), Number(viewModel.alpha));
model.colorBlendMode = getColorBlendMode(viewModel.colorBlendMode);
model.colorBlendAmount = viewModel.colorBlendAmount;
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
speedup : 0.5,
loop : Cesium.ModelAnimationLoop.REPEAT
});
var camera = viewer.camera;
// Zoom to model
var controller = scene.screenSpaceCameraController;
var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;
var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3());
var heading = Cesium.Math.toRadians(230.0);
var pitch = Cesium.Math.toRadians(-20.0);
camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0));
}).otherwise(function(error){
window.alert(error);
});
}
22、cesiumJI加载水(多面环形)
var x=1;
x++;
loadWaterPrimitives();
loadRoad();
loadPark();
load3DTile();
/************************************开始-加载【3DTile】实体*************************************/
function load3DTile() {
var tj = scene.primitives.add(new Cesium.Cesium3DTileset({
url: './resource/3dTiles/tileset.json'
}));
}
/************************************结束-加载【3DTile】实体*************************************/
/************************************开始-加载【水系】实体*************************************/
//返回水面材质:s速度的倍数
function getWaterAppearance(r,g,b,s){
return new Cesium.EllipsoidSurfaceAppearance({
material: new Cesium.Material({
fabric: {
type: 'Water',
uniforms: {
baseWaterColor:new Cesium.Color(r, g, b, 0.9),//rgba颜色的对象基本颜色的水。0.0, 0.4, 0.9, 0.7
// blendColor: new Cesium.Color(0.0, 0.4, 0.9, 0.2),//rgba颜色对象,用于混合从水到非水的地区。
//specularMap: 'gray.jpg',//单通道纹理,用来表示水域。
normalMap: './resource/img/waterNormals.jpg',//正态图:水正常扰动的正态图。
frequency: 1000.0,//频率:控制波数的数字。
animationSpeed: 0.01*s,//动画速度:控制水的动画速度的数字。
amplitude: 5.0,//振幅:控制水波振幅的数字。
specularIntensity:1 //反射强度:控制镜面反射强度的数字。
}
}
}),
fragmentShaderSource: 'varying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec2 v_st;\nvoid main()\n{\nczm_materialInput materialInput;\nvec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nmaterialInput.s = v_st.s;\nmaterialInput.st = v_st;\nmaterialInput.str = vec3(v_st, 0.0);\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\nvec3 positionToEyeEC = -v_positionEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\
gl_FragColor.a=0.5;\n#endif\n}\n' //重写shader,修改水面的透明度
})
}
var riversPrimitive=[];//所有河流的Primitive
function loadWaterPrimitives() {
let pWaters;
$.getJSON('/resource/json/徐汇水系.json', function (data) {
pWaters=data.features;
for (var i = 0; i < pWaters.length; i++) {
var pPolygonHierarchy;
var range = pWaters[i].geometry.coordinates;
var river_code=pWaters[i].properties.river_code;
if (range.length == 1) //多边形无内洞
{
pPolygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(setFormat(range[0])));
} else //多边形有内洞
{
var holeHierarchys = [];
for (var j = 1; j < range.length; j++) {
holeHierarchys.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(setFormat(range[j]))));
}
pPolygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(setFormat(range[0])), holeHierarchys);
}
var waterPrimitive = new Cesium.Primitive({
show: true, // 默认隐藏
allowPicking: false,
releaseGeometryInstances:false,
asynchronous:false,
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: pPolygonHierarchy,
height:0.1
// extrudedHeight: 50, //注释掉此属性可以只显示水面
// perPositionHeight: true //注释掉此属性水面就贴地了
})
}),
// 可以设置内置的水面shader
appearance: getWaterAppearance(0,165/255, 1,2)
// appearance: getWaterAppearance(Color[0][0]/255, Color[0][1]/255, Color[0][2]/255,2)
});
scene.primitives.add(waterPrimitive);
riversPrimitive.push(waterPrimitive);
}
});
}
function setFormat(waterlist) {
var list = [];
for (var i = 0; i < waterlist.length; i++) {
list.push(waterlist[i][0]);
list.push(waterlist[i][1]);
}
return list;
}
/************************************结束-加载【水系】实体*************************************/
/************************************开始-加载【道路】实体*************************************/
function loadRoad() {
Cesium.GeoJsonDataSource.load("./resource/json/徐汇道路.json", {
clampToGround: !0
}).then(function (e) {
viewer.dataSources.add(e);
let l = e.entities.values;
for (let o = 0; o < l.length; o++) {
let i = l[o];
i.polyline.material = new Cesium.PolylineGlowMaterialProperty({
glowPower: 1,
color: Cesium.Color.ORANGERED.withAlpha(.5)
}),
i.polyline.width = 3;
}
}).otherwise(function (e) {
console.log(e)
})
}
/************************************结束-加载【道路】实体*************************************/
/************************************开始-加载【绿地】实体*************************************/
function loadPark() {
Cesium.GeoJsonDataSource.load("./resource/json/徐汇绿地.json", {
clampToGround: !0
}).then(function (e) {
viewer.dataSources.add(e);
let l = e.entities.values;
for (let o = 0; o < l.length; o++) {
let i = l[o];
i.polygon.material = Cesium.Color.LIGHTGREEN;
i.polygon.height=0.1;
// i.polygon.heightReference=Cesium.HeightReference.CLAMP_TO_GROUND;
}
}).otherwise(function (e) {
console.log(e)
})
};
/************************************结束-加载【绿地】实体*************************************/
23、经纬度<=>瓦片编号
// 经纬度转瓦片编号
function lon2tile(lon,zoom) {
return (Math.floor((lon+180)/360*Math.pow(2,zoom)));
}
function lat2tile(lat,zoom) {
return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom)));
}
// 瓦片编号转经纬度
function tile2long(x,z) {
return (x/Math.pow(2,z)*360-180);
}
function tile2lat(y,z) {
var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
}
24、cesium限制最大最小zoom等级高度
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1200;
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 2500;
/**
* 设置后当相机高度达到设置的最大和最小高度时将不再放大和缩小
*/
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 250000;//相机的高度的最小值
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 22000000; //相机高度的最大值
viewer.scene.screenSpaceCameraController._minimumZoomRate = 30000; // 设置相机缩小时的速率
viewer.scene.screenSpaceCameraController._maximumZoomRate=5906376272000 //设置相机放大时的速率
cesium 插件使用
1、地图控件添加(比列尺、指北针等)
1、安装 npm install cesium-navigation-es6
// 引入相关的模块
import CesiumNavigation from "cesium-navigation-es6";
let options = {};
// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
options.defaultResetView = Rectangle.fromDegrees(80, 22, 130, 50)
// 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。
options.enableCompass = true;
// 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件将不会添加到地图中。
options.enableZoomControls = false;
// 用于启用或禁用距离图例。true是启用,false是禁用。默认值为true。如果将选项设置为false,距离图例将不会添加到地图中。
options.enableDistanceLegend = true;
// 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
options.enableCompassOuterRing = true;
CesiumNavigation(cesiumView, options);
2、cesium 的测量面板插件(测距、测面、)
import "./mapShare/cesium-measure.js";
this.measure = new Cesium.Measure(cesiumView);
// 示例如下
measureMap(num) {
switch (num) {
case 0:
// 线的测量
this.measure.drawLineMeasureGraphics({
clampToGround: true,
callback: () => {},
});
break;
case 1:
// 面的测量
this.measure.drawAreaMeasureGraphics({
clampToGround: true,
callback: () => {},
});
break;
case 2:
// 清除测量的相关图层
this.measure._drawLayer.entities.removeAll();
break;
}
}