2025-08-07 18:42:39 +08:00
|
|
|
|
const { Cesium } = window;
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 11:28:32 +08:00
|
|
|
|
|
|
|
|
|
|
export default class LayerMgr {
|
2025-08-07 18:42:39 +08:00
|
|
|
|
constructor() {
|
|
|
|
|
|
// this.viewer = viewer
|
2025-08-07 11:28:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//加载模型
|
2025-08-07 18:42:39 +08:00
|
|
|
|
getGltf(viewer) {
|
|
|
|
|
|
viewer.entities.add({
|
2025-09-10 16:12:55 +08:00
|
|
|
|
position: Cesium.Cartesian3.fromDegrees(114.97, 31.47,250),
|
2025-08-07 18:42:39 +08:00
|
|
|
|
model: {
|
|
|
|
|
|
uri: `${process.env.PUBLIC_URL}/models/dam/scene.gltf` ,
|
2025-09-10 16:12:55 +08:00
|
|
|
|
scale: 10,
|
2025-08-07 18:42:39 +08:00
|
|
|
|
runAnimations: false
|
|
|
|
|
|
},
|
2025-08-07 11:28:32 +08:00
|
|
|
|
});
|
2025-08-07 18:42:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
getWater(viewer) {
|
2025-09-10 16:12:55 +08:00
|
|
|
|
const positions = [
|
|
|
|
|
|
114.96554141845703, 31.487516479492188,
|
|
|
|
|
|
114.993221862792957, 31.487516479492188,
|
|
|
|
|
|
114.993221862792957, 31.4622646484375,
|
|
|
|
|
|
114.96554141845703, 31.4622646484375,
|
|
|
|
|
|
]
|
|
|
|
|
|
let initialHeight = 120
|
|
|
|
|
|
const geometry = new Cesium.PolygonGeometry({
|
|
|
|
|
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
|
|
|
|
|
Cesium.Cartesian3.fromDegreesArray(positions)
|
|
|
|
|
|
),
|
|
|
|
|
|
extrudedHeight: initialHeight,
|
|
|
|
|
|
perPositionHeight:false,
|
|
|
|
|
|
});
|
|
|
|
|
|
const waterPrimitive = new Cesium.Primitive({
|
|
|
|
|
|
geometryInstances: new Cesium.GeometryInstance({ geometry }),
|
|
|
|
|
|
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
|
|
|
|
|
aboveGround: true,
|
|
|
|
|
|
material: new Cesium.Material({
|
|
|
|
|
|
fabric: {
|
|
|
|
|
|
type: 'Water',
|
|
|
|
|
|
uniforms: {
|
|
|
|
|
|
normalMap: Cesium.buildModuleUrl(
|
|
|
|
|
|
`${process.env.PUBLIC_URL}/models/waternormals.jpg`
|
|
|
|
|
|
),
|
|
|
|
|
|
frequency: 1000.0,
|
|
|
|
|
|
animationSpeed: 0.01,
|
|
|
|
|
|
amplitude: 10,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}),
|
|
|
|
|
|
}),
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
// releaseGeometryInstances: false
|
|
|
|
|
|
});
|
|
|
|
|
|
viewer.scene.primitives.add(waterPrimitive);
|
|
|
|
|
|
// 自动抬升
|
|
|
|
|
|
let height = 0;
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
|
|
if (height < 0.4) {
|
|
|
|
|
|
height += 0.001;
|
|
|
|
|
|
// height += 0.02;
|
|
|
|
|
|
// waterPrimitive.extrudedHeight = height; // 触发setter
|
|
|
|
|
|
var currentModelMatrix = Cesium.Matrix4.clone(waterPrimitive.modelMatrix);
|
|
|
|
|
|
// 定义平移向量(例如,沿x轴平移100单位)
|
|
|
|
|
|
var translation = new Cesium.Cartesian3(-height*0.7, height, height*0.8);
|
|
|
|
|
|
// 创建一个平移矩阵
|
|
|
|
|
|
var translationMatrix = Cesium.Matrix4.fromTranslation(translation);
|
|
|
|
|
|
// 计算新的modelMatrix(将平移矩阵应用到当前模型矩阵上)
|
|
|
|
|
|
var newModelMatrix = Cesium.Matrix4.multiply(translationMatrix, currentModelMatrix, new Cesium.Matrix4());
|
|
|
|
|
|
waterPrimitive.modelMatrix = newModelMatrix;
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getWater2(viewer) {
|
|
|
|
|
|
// const waterSurface = viewer.entities.add({
|
|
|
|
|
|
// rectangle: {
|
|
|
|
|
|
// coordinates: Cesium.Rectangle.fromDegrees(114.9, 31.4, 115.9, 32.4),
|
|
|
|
|
|
// material: new Cesium.WaterMaterial({
|
|
|
|
|
|
// normalMapUrl: `${process.env.PUBLIC_URL}/models/waternormals.jpg`, // 水波纹法线贴图
|
|
|
|
|
|
// frequency: 1000.0, // 波纹密度
|
|
|
|
|
|
// animationSpeed: 0.05, // 波动速度
|
|
|
|
|
|
// amplitude: 5.0 // 波高
|
2025-08-07 18:42:39 +08:00
|
|
|
|
// }),
|
2025-09-10 16:12:55 +08:00
|
|
|
|
// height: 130.0 // 水面高度(可动态调整)
|
2025-08-07 18:42:39 +08:00
|
|
|
|
// }
|
2025-09-10 16:12:55 +08:00
|
|
|
|
// });
|
|
|
|
|
|
|
2025-08-07 11:28:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 18:42:39 +08:00
|
|
|
|
async getQxsy(viewer) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
let tileset = await Cesium.Cesium3DTileset.fromUrl(
|
2025-08-07 11:28:32 +08:00
|
|
|
|
'http://res3d.oss-cn-shenzhen.aliyuncs.com/macheng/xiaoyutan/Scene/3DTILE.json',
|
2025-08-07 18:42:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
maximumScreenSpaceError: 1, //精细程度越小越精细
|
|
|
|
|
|
maximumMemoryUsage: 1000, //不可设置太高,目标机子空闲内存值以内,防止浏览器过于卡
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
viewer.scene.primitives.add(tileset);
|
2025-09-10 16:12:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const offsetHeight = 15
|
|
|
|
|
|
const boundingSphere = tileset.boundingSphere
|
|
|
|
|
|
const cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
|
|
|
|
|
|
const surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0)
|
|
|
|
|
|
const offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, offsetHeight)
|
|
|
|
|
|
const translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3())
|
|
|
|
|
|
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
|
|
|
|
|
|
viewer.flyTo(tileset)
|
2025-08-07 18:42:39 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`Error creating tileset: ${error}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 11:28:32 +08:00
|
|
|
|
// fetch(`${process.env.PUBLIC_URL}/data/geojson/macheng/boua.geojson`)
|
|
|
|
|
|
// .then(resp => resp.json())
|
|
|
|
|
|
// .then(data => {
|
|
|
|
|
|
// let features = data.features;
|
|
|
|
|
|
// let positionArray = [];
|
|
|
|
|
|
// // 获取区域的经纬度坐标
|
|
|
|
|
|
// for (let i = 0; i < features[0].geometry.coordinates[0].length; i++) {
|
|
|
|
|
|
// let coor = features[0].geometry.coordinates[0][i];
|
|
|
|
|
|
// positionArray.push(coor[0]);
|
|
|
|
|
|
// positionArray.push(coor[1]);
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// // 遮罩
|
|
|
|
|
|
// let polygonEntity = new Cesium.Entity({
|
|
|
|
|
|
// polygon: {
|
|
|
|
|
|
// hierarchy: {
|
|
|
|
|
|
// // 添加外部区域为1/4半圆,设置为180会报错 [0, 0, 0, 90, 179, 90, 179, 0]
|
|
|
|
|
|
// positions: Cesium.Cartesian3.fromDegreesArray([100, 0, 100, 89, 150, 89, 150, 0]),
|
|
|
|
|
|
// // 中心挖空的“洞”
|
|
|
|
|
|
// holes: [{
|
|
|
|
|
|
// positions: Cesium.Cartesian3.fromDegreesArray(positionArray)
|
|
|
|
|
|
// }]
|
|
|
|
|
|
// },
|
|
|
|
|
|
// material: Cesium.Color.BLACK.withAlpha(0.7) //new Cesium.Color(236,242,249, 1)
|
|
|
|
|
|
// }
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// // 边界线
|
|
|
|
|
|
// let lineEntity = new Cesium.Entity({
|
|
|
|
|
|
// polyline: {
|
|
|
|
|
|
// positions: Cesium.Cartesian3.fromDegreesArray(positionArray),
|
|
|
|
|
|
// width: 7,
|
|
|
|
|
|
// material: Cesium.Color.fromCssColorString('#7AE3C8'),//边界线颜色//Cesium.Color.YELLOW //new Cesium.Color(122,227,200, 1)
|
|
|
|
|
|
// clampToGround: true,
|
|
|
|
|
|
// zIndex: 10
|
|
|
|
|
|
// }
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// viewer.entities.add(polygonEntity);
|
|
|
|
|
|
// viewer.entities.add(lineEntity);
|
|
|
|
|
|
// //viewer.flyTo(lineEntity);
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 18:42:39 +08:00
|
|
|
|
// tileset.readyPromise.then(function () {
|
|
|
|
|
|
// viewer.zoomTo(
|
|
|
|
|
|
// tileset,
|
|
|
|
|
|
// new Cesium.HeadingPitchRange(
|
|
|
|
|
|
// 0,
|
|
|
|
|
|
// -0.7,
|
|
|
|
|
|
// 2500
|
|
|
|
|
|
// // tileset.boundingSphere.radius * 10
|
|
|
|
|
|
// )
|
|
|
|
|
|
// );
|
|
|
|
|
|
// });
|
2025-08-07 11:28:32 +08:00
|
|
|
|
|
|
|
|
|
|
//设置倾斜摄影Z轴高度
|
2025-08-07 18:42:39 +08:00
|
|
|
|
// tileset.readyPromise.then(function (tileset) {
|
|
|
|
|
|
// const offsetHeight = 15
|
|
|
|
|
|
// const boundingSphere = tileset.boundingSphere
|
|
|
|
|
|
// const cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
|
|
|
|
|
|
// const surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0)
|
|
|
|
|
|
// const offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, offsetHeight)
|
|
|
|
|
|
// const translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3())
|
|
|
|
|
|
// tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
|
|
|
|
|
|
// // viewer.flyTo(tileset)
|
|
|
|
|
|
// })
|
2025-08-07 11:28:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-10 16:12:55 +08:00
|
|
|
|
async getDem(viewer) {
|
|
|
|
|
|
const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(
|
|
|
|
|
|
// "/shzh/mapres/terrain",
|
2025-09-12 11:22:45 +08:00
|
|
|
|
// `${process.env.PUBLIC_URL}/terrain`,
|
2025-09-10 16:12:55 +08:00
|
|
|
|
// "http://192.168.66.51:42225/distribution/terrain/5vjnbauc3frn",
|
2025-09-12 11:22:45 +08:00
|
|
|
|
"https://map1.oss-cn-shenzhen.aliyuncs.com/tsg/terrain2",
|
2025-09-10 16:12:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
requestVertexNormals: true
|
|
|
|
|
|
})
|
|
|
|
|
|
viewer.terrainProvider = terrainProvider
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getWxyx(viewer) {
|
|
|
|
|
|
const tiandiKey = "efc861f25f96dc6e5f884f0403ebfefd"; //天地图key,官网申请
|
|
|
|
|
|
const baseUrl = "https://{s}.tianditu.gov.cn";//'https://t{0-7}.tianditu.gov.cn';
|
|
|
|
|
|
|
|
|
|
|
|
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
|
|
|
|
|
|
//url: `http://res3dstatic{s}.cloudowr.cn/${localStorage.getItem('address')}/dom2/{z}/{x}/{y}.png`,
|
|
|
|
|
|
url: baseUrl + '/DataServer?T=img_w&x={x}&y={y}&l={z}&tk='+tiandiKey,
|
|
|
|
|
|
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
|
|
|
|
|
|
//minimumLevel:10,
|
|
|
|
|
|
maximumLevel: 17,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
viewer.imageryLayers.addImageryProvider(imageryProvider);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getRlt(viewer) {
|
|
|
|
|
|
function getColorRamp() {
|
|
|
|
|
|
const ramp = document.createElement("canvas");
|
|
|
|
|
|
ramp.width = 100;
|
|
|
|
|
|
ramp.height = 1;
|
|
|
|
|
|
const ctx = ramp.getContext("2d");
|
|
|
|
|
|
|
|
|
|
|
|
let values;
|
|
|
|
|
|
values = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0];
|
|
|
|
|
|
|
|
|
|
|
|
const grd = ctx.createLinearGradient(0, 0, 100, 0);
|
|
|
|
|
|
grd.addColorStop(values[0], "#000000"); //black
|
|
|
|
|
|
grd.addColorStop(values[1], "#2747E0"); //blue
|
|
|
|
|
|
grd.addColorStop(values[2], "#D33B7D"); //pink
|
|
|
|
|
|
grd.addColorStop(values[3], "#D33038"); //red
|
|
|
|
|
|
grd.addColorStop(values[4], "#FF9742"); //orange
|
|
|
|
|
|
grd.addColorStop(values[5], "#ffd700"); //yellow
|
|
|
|
|
|
grd.addColorStop(values[6], "#ffffff"); //white
|
|
|
|
|
|
|
|
|
|
|
|
ctx.fillStyle = grd;
|
|
|
|
|
|
ctx.fillRect(0, 0, 100, 1);
|
|
|
|
|
|
|
|
|
|
|
|
return ramp;
|
|
|
|
|
|
}
|
|
|
|
|
|
const minHeight = -414.0; // approximate dead sea elevation
|
|
|
|
|
|
const maxHeight = 8777.0; // approximate everest elevation
|
|
|
|
|
|
let shadingUniforms = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateMaterial() {
|
|
|
|
|
|
// const globe = viewer.scene.globe;
|
|
|
|
|
|
// let material;
|
|
|
|
|
|
// material = Cesium.Material.fromType("ElevationRamp");
|
|
|
|
|
|
// shadingUniforms = material.uniforms;
|
|
|
|
|
|
// shadingUniforms.minimumHeight = minHeight;
|
|
|
|
|
|
// shadingUniforms.maximumHeight = maxHeight;
|
|
|
|
|
|
// shadingUniforms.image = getColorRamp();
|
|
|
|
|
|
// globe.material = material;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const material = Cesium.Material.fromType("ElevationRamp")
|
|
|
|
|
|
material.uniforms.image = getColorRamp()
|
|
|
|
|
|
viewer.scene.globe.material = material
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
updateMaterial();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getRlt2(viewer) {
|
|
|
|
|
|
const gridData = {
|
|
|
|
|
|
minLon: 110.0, // 最小经度
|
|
|
|
|
|
minLat: 30.0, // 最小纬度
|
|
|
|
|
|
deltaLon: 0.1, // 经度间隔
|
|
|
|
|
|
deltaLat: 0.1, // 纬度间隔
|
|
|
|
|
|
rows: 10, // 行数(纬度方向)
|
|
|
|
|
|
cols: 10, // 列数(经度方向)
|
|
|
|
|
|
heights: [ // 高度值数组(行优先存储)
|
|
|
|
|
|
/* 10x10 网格高度值 */
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
100, 120, 140, 140,135,130,120,110,100,90,
|
|
|
|
|
|
// ... 共 100 个值
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
// 2. 创建颜色映射函数(根据高度返回颜色)
|
|
|
|
|
|
function heightToColor(height) {
|
|
|
|
|
|
// 示例:根据高度值返回渐变色
|
|
|
|
|
|
const minH = 100, maxH = 500;
|
|
|
|
|
|
const ratio = Math.min(1, Math.max(0, (height - minH) / (maxH - minH)));
|
|
|
|
|
|
|
|
|
|
|
|
// 蓝 -> 绿 -> 红 渐变
|
|
|
|
|
|
const r = Math.floor(255 * ratio);
|
|
|
|
|
|
const g = Math.floor(255 * (1 - ratio));
|
|
|
|
|
|
const b = 128;
|
|
|
|
|
|
|
|
|
|
|
|
return new Cesium.Color(r / 255, g / 255, b / 255, 1.0);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 3. 生成网格几何数据
|
|
|
|
|
|
function createGridGeometry(grid) {
|
|
|
|
|
|
const positions = [];
|
|
|
|
|
|
const colors = [];
|
|
|
|
|
|
const indices = [];
|
|
|
|
|
|
let vertexIndex = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (let row = 0; row < grid.rows; row++) {
|
|
|
|
|
|
for (let col = 0; col < grid.cols; col++) {
|
|
|
|
|
|
// 计算当前网格点经纬度
|
|
|
|
|
|
const lon = grid.minLon + col * grid.deltaLon;
|
|
|
|
|
|
const lat = grid.minLat + row * grid.deltaLat;
|
|
|
|
|
|
const height = grid.heights[row * grid.cols + col];
|
|
|
|
|
|
|
|
|
|
|
|
// 将经纬度转换为笛卡尔坐标
|
|
|
|
|
|
const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
|
|
|
|
|
|
positions.push(position);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算颜色
|
|
|
|
|
|
const color = heightToColor(height);
|
|
|
|
|
|
colors.push(color.red, color.green, color.blue, color.alpha);
|
|
|
|
|
|
|
|
|
|
|
|
// 生成三角形索引(跳过边界)
|
|
|
|
|
|
if (row < grid.rows - 1 && col < grid.cols - 1) {
|
|
|
|
|
|
const topLeft = vertexIndex;
|
|
|
|
|
|
const topRight = topLeft + 1;
|
|
|
|
|
|
const bottomLeft = topLeft + grid.cols;
|
|
|
|
|
|
const bottomRight = bottomLeft + 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 两个三角形组成一个网格单元
|
|
|
|
|
|
indices.push(topLeft, bottomLeft, topRight);
|
|
|
|
|
|
indices.push(topRight, bottomLeft, bottomRight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vertexIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return { positions, colors, indices };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 创建Primitive并添加到场景
|
|
|
|
|
|
function createGridPrimitive(geometry) {
|
|
|
|
|
|
const appearance = new Cesium.PerInstanceColorAppearance({
|
|
|
|
|
|
flat: true, // 平面着色
|
|
|
|
|
|
renderState: {
|
|
|
|
|
|
depthTest: { enabled: true } // 启用深度测试
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const primitive = new Cesium.Primitive({
|
|
|
|
|
|
geometryInstances: new Cesium.GeometryInstance({
|
|
|
|
|
|
geometry: new Cesium.PolygonGeometry({
|
|
|
|
|
|
polygonHierarchy: new Cesium.PolygonHierarchy(geometry.positions),
|
|
|
|
|
|
vertexFormat: appearance.vertexFormat
|
|
|
|
|
|
}),
|
|
|
|
|
|
attributes: {
|
|
|
|
|
|
color: new Cesium.ColorGeometryInstanceAttribute.fromColor(
|
|
|
|
|
|
new Cesium.Color(1.0, 1.0, 1.0, 1.0)
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
appearance: appearance
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
viewer.scene.primitives.add(primitive);
|
|
|
|
|
|
return primitive;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const geometryData = createGridGeometry(gridData);
|
|
|
|
|
|
|
|
|
|
|
|
const gridPrimitive = createGridPrimitive(geometryData);
|
|
|
|
|
|
}
|
|
|
|
|
|
async getRlt3(viewer) {
|
|
|
|
|
|
// const gridData = {
|
|
|
|
|
|
// minLon: 110.0, // 最小经度
|
|
|
|
|
|
// minLat: 30.0, // 最小纬度
|
|
|
|
|
|
// deltaLon: 0.1, // 经度间隔
|
|
|
|
|
|
// deltaLat: 0.1, // 纬度间隔
|
|
|
|
|
|
|
|
|
|
|
|
// maxLon: 110.0 + 10 * 0.1, // minLon + cols * deltaLon
|
|
|
|
|
|
// maxLat: 30.0 + 10 * 0.1, // minLat + rows * deltaLat
|
|
|
|
|
|
|
|
|
|
|
|
// rows: 10, // 行数(纬度方向)
|
|
|
|
|
|
// cols: 10, // 列数(经度方向)
|
|
|
|
|
|
// // heights: [ // 高度值数组(行优先存储)
|
|
|
|
|
|
// // /* 10x10 网格高度值 */
|
|
|
|
|
|
// // 100, 120, 140, ...,
|
|
|
|
|
|
// // 110, 130, 150, ...,
|
|
|
|
|
|
// // // ... 共 100 个值
|
|
|
|
|
|
// // ]
|
|
|
|
|
|
// };
|
|
|
|
|
|
// // 2. 创建颜色映射函数(根据高度返回颜色)
|
|
|
|
|
|
// function heightToColor(height) {
|
|
|
|
|
|
// // 示例:根据高度值返回渐变色
|
|
|
|
|
|
// const minH = 1, maxH = 300;
|
|
|
|
|
|
// const ratio = Math.min(1, Math.max(0, (height - minH) / (maxH - minH)));
|
|
|
|
|
|
// // 蓝 -> 绿 -> 红 渐变
|
|
|
|
|
|
// const r = Math.floor(255 * ratio);
|
|
|
|
|
|
// const g = Math.floor(255 * (1 - ratio));
|
|
|
|
|
|
// const b = 128;
|
|
|
|
|
|
// // return new Cesium.Color(r / 255, g / 255, b / 255, 1.0);
|
|
|
|
|
|
// return [r,g,b,100]
|
|
|
|
|
|
// }
|
|
|
|
|
|
const gridData = {
|
|
|
|
|
|
minLon: 110.0, // 最小经度
|
|
|
|
|
|
minLat: 30.0, // 最小纬度
|
|
|
|
|
|
deltaLon: 0.01, // 经度间隔
|
|
|
|
|
|
deltaLat: 0.01, // 纬度间隔
|
|
|
|
|
|
maxLon: 110.0 + 100 * 0.01, // minLon + cols * deltaLon
|
|
|
|
|
|
maxLat: 30.0 + 100 * 0.01, // minLat + rows * deltaLat
|
|
|
|
|
|
rows: 100, // 行数(纬度方向)
|
|
|
|
|
|
cols: 100, // 列数(经度方向)
|
|
|
|
|
|
cccc:[
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,200,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
[10,10,10,10,10,10,10,10,10,10],
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
// 2. 创建颜色映射函数(根据高度返回颜色)
|
|
|
|
|
|
function heightToColor(height) {
|
|
|
|
|
|
// 示例:根据高度值返回渐变色
|
|
|
|
|
|
const minH = 1, maxH = 300;
|
|
|
|
|
|
const ratio = Math.min(1, Math.max(0, (height - minH) / (maxH - minH)));
|
|
|
|
|
|
// 蓝 -> 绿 -> 红 渐变
|
|
|
|
|
|
const r = Math.floor(255 * ratio);
|
|
|
|
|
|
const g = Math.floor(255 * (1 - ratio));
|
|
|
|
|
|
const b = 128;
|
|
|
|
|
|
// return new Cesium.Color(r / 255, g / 255, b / 255, 1.0);
|
|
|
|
|
|
return [r,g,b,100]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (let index = 0; index<10; index++){
|
|
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
|
canvas.width = gridData.cols; // 每个网格一个像素
|
|
|
|
|
|
canvas.height = gridData.rows;
|
|
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
|
|
for (let row = 0; row < gridData.rows; row++) {
|
|
|
|
|
|
for (let col = 0; col < gridData.cols; col++) {
|
|
|
|
|
|
const color = heightToColor(col*index*0.5);
|
|
|
|
|
|
// const color = heightToColor(gridData.cccc[row][col]);
|
|
|
|
|
|
const style = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${50})`;
|
|
|
|
|
|
context.fillStyle = style;
|
|
|
|
|
|
context.fillRect(col, row, 1, 1); // 每个像素一个网格点
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
const imageUrl = canvas.toDataURL('image/png');
|
|
|
|
|
|
// 5. 创建矩形范围(覆盖整个网格)
|
|
|
|
|
|
const rectangle = Cesium.Rectangle.fromDegrees(
|
|
|
|
|
|
gridData.minLon, gridData.minLat,
|
|
|
|
|
|
gridData.maxLon, gridData.maxLat
|
|
|
|
|
|
);
|
|
|
|
|
|
// 6. 创建SingleTileImageryProvider
|
|
|
|
|
|
const imageryProvider = new Cesium.SingleTileImageryProvider({
|
|
|
|
|
|
url: imageUrl,
|
|
|
|
|
|
rectangle: rectangle
|
|
|
|
|
|
});
|
|
|
|
|
|
// 7. 添加到影像层集合
|
|
|
|
|
|
viewer.imageryLayers.addImageryProvider(imageryProvider);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.sleep(1000)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async sleep(time) {
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, time));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getCzmlData(){
|
|
|
|
|
|
const gridData = {
|
|
|
|
|
|
minLon: 110.0, // 最小经度
|
|
|
|
|
|
minLat: 30.0, // 最小纬度
|
|
|
|
|
|
deltaLon: 0.1, // 经度间隔
|
|
|
|
|
|
deltaLat: 0.1, // 纬度间隔
|
|
|
|
|
|
rows: 10, // 行数(纬度方向)
|
|
|
|
|
|
cols: 10, // 列数(经度方向)
|
|
|
|
|
|
// heights: [ // 高度值数组(行优先存储)
|
|
|
|
|
|
// /* 10x10 网格高度值 */
|
|
|
|
|
|
// 100, 120, 140, ...,
|
|
|
|
|
|
// 110, 130, 150, ...,
|
|
|
|
|
|
// // ... 共 100 个值
|
|
|
|
|
|
// ]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 创建颜色映射函数(根据高度返回颜色)
|
|
|
|
|
|
function heightToColor(height) {
|
|
|
|
|
|
// 示例:根据高度值返回渐变色
|
|
|
|
|
|
const minH = 1, maxH = 300;
|
|
|
|
|
|
const ratio = Math.min(1, Math.max(0, (height - minH) / (maxH - minH)));
|
|
|
|
|
|
// 蓝 -> 绿 -> 红 渐变
|
|
|
|
|
|
const r = Math.floor(255 * ratio);
|
|
|
|
|
|
const g = Math.floor(255 * (1 - ratio));
|
|
|
|
|
|
const b = 128;
|
|
|
|
|
|
// return new Cesium.Color(r / 255, g / 255, b / 255, 1.0);
|
|
|
|
|
|
return [r,g,b,100]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 生成网格几何数据1帧
|
|
|
|
|
|
function createGridGeometry(grid,ccc) {
|
|
|
|
|
|
const positions = [];
|
|
|
|
|
|
const colors = [];
|
|
|
|
|
|
const indices = [];
|
|
|
|
|
|
let vertexIndex = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (let row = 0; row < grid.rows; row++) {
|
|
|
|
|
|
for (let col = 0; col < grid.cols; col++) {
|
|
|
|
|
|
// 计算当前网格点经纬度
|
|
|
|
|
|
const lon = grid.minLon + col * grid.deltaLon;
|
|
|
|
|
|
const lat = grid.minLat + row * grid.deltaLat;
|
|
|
|
|
|
const height = row+col+2;
|
|
|
|
|
|
const color = heightToColor(height*ccc*2);
|
|
|
|
|
|
// const color = heightToColor(height*ccc*0.1);
|
|
|
|
|
|
positions.push([
|
|
|
|
|
|
[lon-grid.deltaLon/2,lat,ccc===row?4000:3000],//左上
|
|
|
|
|
|
[lon+grid.deltaLon/2,lat,ccc===row?4000:3000],//右上
|
|
|
|
|
|
[lon,lat+grid.deltaLat,(ccc===(row+1))?4000:3000],//左下
|
|
|
|
|
|
color,//颜色
|
|
|
|
|
|
])
|
|
|
|
|
|
positions.push([
|
|
|
|
|
|
[lon+grid.deltaLon,lat+grid.deltaLat,(ccc===(row+1))?4000:3000],//左下
|
|
|
|
|
|
[lon,lat+grid.deltaLat,(ccc===(row+1))?4000:3000],//右下
|
|
|
|
|
|
[lon+grid.deltaLon/2,lat,ccc===row?4000:3000],//右上
|
|
|
|
|
|
color,//颜色
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将经纬度转换为笛卡尔坐标
|
|
|
|
|
|
// const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算颜色
|
|
|
|
|
|
// const color = heightToColor(height);
|
|
|
|
|
|
colors.push(color.red, color.green, color.blue, color.alpha);
|
|
|
|
|
|
// positions.push([lon,lat,height,[color.red,color.green,color.blue,color.alpha]]);
|
|
|
|
|
|
|
|
|
|
|
|
// 生成三角形索引(跳过边界)
|
|
|
|
|
|
if (row < grid.rows - 1 && col < grid.cols - 1) {
|
|
|
|
|
|
const topLeft = vertexIndex;
|
|
|
|
|
|
const topRight = topLeft + 1;
|
|
|
|
|
|
const bottomLeft = topLeft + grid.cols;
|
|
|
|
|
|
const bottomRight = bottomLeft + 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 两个三角形组成一个网格单元
|
|
|
|
|
|
indices.push(topLeft, bottomLeft, topRight);
|
|
|
|
|
|
indices.push(topRight, bottomLeft, bottomRight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vertexIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return positions;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const alllist = []
|
|
|
|
|
|
for (let index = 0; index<10; index++){
|
|
|
|
|
|
alllist.push(createGridGeometry(gridData,index+1))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return alllist
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getCzml(viewer) {
|
|
|
|
|
|
const gridData = {
|
|
|
|
|
|
minLon: 110.0, // 最小经度
|
|
|
|
|
|
minLat: 30.0, // 最小纬度
|
|
|
|
|
|
deltaLon: 0.1, // 经度间隔
|
|
|
|
|
|
deltaLat: 0.1, // 纬度间隔
|
|
|
|
|
|
rows: 10, // 行数(纬度方向)
|
|
|
|
|
|
cols: 10, // 列数(经度方向)
|
|
|
|
|
|
// heights: [ // 高度值数组(行优先存储)
|
|
|
|
|
|
// /* 10x10 网格高度值 */
|
|
|
|
|
|
// 100, 120, 140, ...,
|
|
|
|
|
|
// 110, 130, 150, ...,
|
|
|
|
|
|
// // ... 共 100 个值
|
|
|
|
|
|
// ]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 创建颜色映射函数(根据高度返回颜色)
|
|
|
|
|
|
function heightToColor(height) {
|
|
|
|
|
|
// 示例:根据高度值返回渐变色
|
|
|
|
|
|
const minH = 1, maxH = 300;
|
|
|
|
|
|
const ratio = Math.min(1, Math.max(0, (height - minH) / (maxH - minH)));
|
|
|
|
|
|
// 蓝 -> 绿 -> 红 渐变
|
|
|
|
|
|
const r = Math.floor(255 * ratio);
|
|
|
|
|
|
const g = Math.floor(255 * (1 - ratio));
|
|
|
|
|
|
const b = 128;
|
|
|
|
|
|
// return new Cesium.Color(r / 255, g / 255, b / 255, 1.0);
|
|
|
|
|
|
return [r,g,b,100]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 生成网格几何数据1帧
|
|
|
|
|
|
function createGridGeometry(grid,ccc) {
|
|
|
|
|
|
const positions = [];
|
|
|
|
|
|
const colors = [];
|
|
|
|
|
|
const indices = [];
|
|
|
|
|
|
let vertexIndex = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (let row = 0; row < grid.rows; row++) {
|
|
|
|
|
|
for (let col = 0; col < grid.cols; col++) {
|
|
|
|
|
|
// 计算当前网格点经纬度
|
|
|
|
|
|
const lon = grid.minLon + col * grid.deltaLon;
|
|
|
|
|
|
const lat = grid.minLat + row * grid.deltaLat;
|
|
|
|
|
|
const height = row+col+2;
|
|
|
|
|
|
const color = heightToColor(height*ccc*2);
|
|
|
|
|
|
// const color = heightToColor(height*ccc*0.1);
|
|
|
|
|
|
positions.push([
|
|
|
|
|
|
[lon-grid.deltaLon/2,lat,ccc===row?7000:3000],//左上
|
|
|
|
|
|
[lon+grid.deltaLon/2,lat,ccc===row?7000:3000],//右上
|
|
|
|
|
|
[lon,lat+grid.deltaLat,(ccc===(row+1))?7000:3000],//左下
|
|
|
|
|
|
color,//颜色
|
|
|
|
|
|
])
|
|
|
|
|
|
positions.push([
|
|
|
|
|
|
[lon+grid.deltaLon,lat+grid.deltaLat,(ccc===(row+1))?7000:3000],//左下
|
|
|
|
|
|
[lon,lat+grid.deltaLat,(ccc===(row+1))?7000:3000],//右下
|
|
|
|
|
|
[lon+grid.deltaLon/2,lat,ccc===row?7000:3000],//右上
|
|
|
|
|
|
color,//颜色
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将经纬度转换为笛卡尔坐标
|
|
|
|
|
|
// const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算颜色
|
|
|
|
|
|
// const color = heightToColor(height);
|
|
|
|
|
|
colors.push(color.red, color.green, color.blue, color.alpha);
|
|
|
|
|
|
// positions.push([lon,lat,height,[color.red,color.green,color.blue,color.alpha]]);
|
|
|
|
|
|
|
|
|
|
|
|
// 生成三角形索引(跳过边界)
|
|
|
|
|
|
if (row < grid.rows - 1 && col < grid.cols - 1) {
|
|
|
|
|
|
const topLeft = vertexIndex;
|
|
|
|
|
|
const topRight = topLeft + 1;
|
|
|
|
|
|
const bottomLeft = topLeft + grid.cols;
|
|
|
|
|
|
const bottomRight = bottomLeft + 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 两个三角形组成一个网格单元
|
|
|
|
|
|
indices.push(topLeft, bottomLeft, topRight);
|
|
|
|
|
|
indices.push(topRight, bottomLeft, bottomRight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vertexIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return positions;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// const geometryData = createGridGeometry(gridData,1);
|
|
|
|
|
|
const alllist = []
|
|
|
|
|
|
for (let index = 0; index<1; index++){
|
|
|
|
|
|
alllist.push(createGridGeometry(gridData,index+1))
|
|
|
|
|
|
}
|
|
|
|
|
|
const czmls = []
|
|
|
|
|
|
alllist.map((item,index)=>{
|
|
|
|
|
|
//时间维度
|
|
|
|
|
|
const czml = [{
|
|
|
|
|
|
id: "document",
|
|
|
|
|
|
name: "CZML Colors",
|
|
|
|
|
|
version: "1.0",
|
|
|
|
|
|
}]
|
|
|
|
|
|
item.map((item2,index2)=>{
|
|
|
|
|
|
czml.push({
|
|
|
|
|
|
id: "rgba"+index2,
|
|
|
|
|
|
name: "Rectangle with outline using RGBA Colors",
|
|
|
|
|
|
polygon: {
|
|
|
|
|
|
positions: {
|
|
|
|
|
|
cartographicDegrees: [
|
|
|
|
|
|
...item2[0],
|
|
|
|
|
|
...item2[1],
|
|
|
|
|
|
...item2[2],
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
// material: {
|
|
|
|
|
|
// solidColor: {
|
|
|
|
|
|
// color: {
|
|
|
|
|
|
// rgba: item2[3],
|
|
|
|
|
|
// },
|
|
|
|
|
|
// },
|
|
|
|
|
|
// },
|
|
|
|
|
|
material: {
|
|
|
|
|
|
image: {
|
|
|
|
|
|
image: {
|
|
|
|
|
|
uri: Cesium.buildModuleUrl(
|
|
|
|
|
|
`${process.env.PUBLIC_URL}/models/waternormals.jpg`
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
// color: {
|
|
|
|
|
|
// rgba: [255, 255, 255, 128],
|
|
|
|
|
|
// },
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
extrudedHeight: 0,
|
|
|
|
|
|
perPositionHeight: true,
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
czmls.push(czml)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let dataSourcePromise = null;
|
|
|
|
|
|
for (const item of czmls) {
|
|
|
|
|
|
// if(dataSourcePromise){
|
|
|
|
|
|
// viewer.dataSources.remove(dataSourcePromise);
|
|
|
|
|
|
// dataSourcePromise = null
|
|
|
|
|
|
// }
|
|
|
|
|
|
const dataSourcePromise = await Cesium.CzmlDataSource.load(item)
|
|
|
|
|
|
viewer.dataSources.add(dataSourcePromise);
|
|
|
|
|
|
// setTimeout(() => {
|
|
|
|
|
|
// viewer.dataSources.remove(dataSourcePromise);
|
|
|
|
|
|
// }, 1000);
|
|
|
|
|
|
await this.sleep(1000)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 11:28:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|