增加:体渲染、三维热力图、蜂窝热力图

This commit is contained in:
贾宛龙 2025-09-23 18:22:05 +08:00
parent 3f1ab3d08f
commit 803eb2879b
18 changed files with 48052 additions and 137 deletions

View File

@ -56,7 +56,7 @@
## 打赏列表:
| 捐赠人 | 额 | 时间 |
| 捐赠人 | 额 | 时间 |
| ---------- | ------- | -----------|
| 不浪 | 88 | 2025.02.17 |
| 一心一意 | 5 | 2025.03.07 |
@ -86,6 +86,7 @@
| 一杯茶 | 100 | 2025.08.25 |
| M Y M | 8.88 | 2025.08.27 |
| hawken | 100 | 2025.09.08 |
| 打不掉头的僵尸 | 20 | 2025.09.23 |
### 关于打赏
- 您的每一笔打赏,我都会原封不动以**您的名义**捐赠到腾讯公益。

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

View File

@ -43,6 +43,7 @@
<img src="./159308476120250827E9KER945HV.jpg">
<img src="./159308476120250827E5KEYBVL5Y.jpg">
<img src="./159297686120250908E6I6WNCDJ8.jpg">
<img src="./159297686120250923E6KP3S7L8P.jpg">
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -15,10 +15,35 @@
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<script>
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwNDljNWFmZC03MzRlLTRiMDMtYWIwMi00Yjk4YWQ4NzQwZGEiLCJpZCI6MjU5LCJpYXQiOjE3NTEzNzkyMzR9.OTqPNs3UGNnT1LYkPTavV80wN8Es_YphpJgQcpdnqWc'
const viewer = new Cesium.Viewer('map', {});
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
infoBox: false,
selectionIndicator: false,
animation: false,//是否创建动画小器件,左下角仪表
baseLayerPicker: false,//是否显示图层选择器
fullscreenButton: false,//是否显示全屏按钮
geocoder: false,//是否显示geocoder小器件右上角查询按钮
homeButton: false,//是否显示Home按钮
infoBox: false,//是否显示信息框
sceneModePicker: false,//是否显示3D/2D选择器
selectionIndicator: false,//是否显示选取指示器组件
timeline: false,//是否显示时间轴
navigationHelpButton: false,//是否显示右上角的帮助按钮
scene3DOnly: true,//如果设置为true则所有几何图形以3D模式绘制以节约GPU资源
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
viewer.scene.debugShowFramesPerSecond = true;
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(100, 20, 120, 40),
});
// !!!!!!!!!!!!!!教程!!!!!!!!!!!!!!!!!!!!!
/*
1、数据获取

View File

@ -0,0 +1,150 @@
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
<script src="./turf.min.js"></script>
<script src="./kriging.js"></script>
</head>
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<script>
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
const polygonGeojson = turf.polygon([[[110, 30], [110.1, 30], [110.1, 30.1], [110, 30.1], [110, 30]]]);
const points = [];
const bbox = [110, 30, 110.1, 30.1]
turf.randomPoint(125, { bbox: bbox }).features.forEach(element => {
points.push({
lng: element.geometry.coordinates[0],
lat: element.geometry.coordinates[1],
value: getRandomNum(0, 1000)
});
});
// 2. 提取数据
const lons = points.map(point => point.lng);
const lats = points.map(point => point.lat);
const values = points.map(point => point.value);
// 3. 训练变异函数
const variogram = kriging.train(values, lons, lats, 'exponential', 0, 100);
const xMin = bbox[0], yMin = bbox[1], xMax = bbox[2], yMax = bbox[3];
const polygons = [[[xMin, yMin], [xMin, yMax], [xMax, yMax], [xMax, yMin]]];
const gridWidth = 0.002; // 调整此值!
const grid = kriging.grid(polygons, variogram, gridWidth);
// 5. 创建并裁剪方块单元
const xLim = [grid.xlim[0], grid.xlim[1]];
const yLim = [grid.ylim[0], grid.ylim[1]];
const features = [];
for (let i = 0; i < grid.data.length; i++) {
for (let j = 0; j < grid.data[i].length; j++) {
const value = grid.data[i][j];
const x = xLim[0] + i * gridWidth;
const y = yLim[0] + j * gridWidth;
const cellBbox = [x, y, x + gridWidth, y + gridWidth];
const cellPolygon = turf.bboxPolygon(cellBbox);
const clippedCell = turf.booleanContains(polygonGeojson, cellPolygon);
if (clippedCell) {
cellPolygon.properties = { 'value': value };
features.push(turf.feature(cellPolygon.geometry, cellPolygon.properties));
}
}
}
let myEntityCollection = new Cesium.CustomDataSource("clickEntityCollection");
viewer.dataSources.add(myEntityCollection);
features.forEach(function (feature) {
myEntityCollection.entities.add({
polygon: {
extrudedHeight: Number(Number(feature.properties.value)),
hierarchy: Cesium.Cartesian3.fromDegreesArray(feature.geometry.coordinates[0].flat()),
material: Cesium.Color.fromCssColorString(getElevationColor(Number(feature.properties.value))),
outline: false
}
});
});
viewer.flyTo(myEntityCollection);
// 高程颜色映射算法
function getElevationColor(elevation) {
// 确保高程值在0-10000范围内
const clampedElevation = Math.max(0, Math.min(10000, elevation));
// 定义10个关键高程点的颜色
const colorStops = [
{ value: 0, color: [0, 100, 0] }, // 深绿色 - 海平面
{ value: 100, color: [34, 139, 34] }, // 森林绿
{ value: 200, color: [152, 251, 152] }, // 浅绿色
{ value: 300, color: [240, 230, 140] }, // 卡其色
{ value: 400, color: [255, 215, 0] }, // 金黄色
{ value: 500, color: [255, 165, 0] }, // 橙色
{ value: 600, color: [255, 140, 0] }, // 深橙色
{ value: 700, color: [255, 99, 71] }, // 番茄红
{ value: 800, color: [255, 69, 0] }, // 红橙色
{ value: 900, color: [255, 0, 0] }, // 红色
{ value: 1000, color: [128, 0, 0] } // 深红色 - 最高点
];
// 找到高程值所在的区间
for (let i = 0; i < colorStops.length - 1; i++) {
const currentStop = colorStops[i];
const nextStop = colorStops[i + 1];
if (clampedElevation >= currentStop.value && clampedElevation <= nextStop.value) {
// 计算在当前区间中的比例 (0-1)
const ratio = (clampedElevation - currentStop.value) /
(nextStop.value - currentStop.value);
// 对RGB三个通道分别进行插值
const r = Math.round(currentStop.color[0] +
ratio * (nextStop.color[0] - currentStop.color[0]));
const g = Math.round(currentStop.color[1] +
ratio * (nextStop.color[1] - currentStop.color[1]));
const b = Math.round(currentStop.color[2] +
ratio * (nextStop.color[2] - currentStop.color[2]));
// 返回RGB颜色字符串
return `rgb(${r}, ${g}, ${b},0.5)`;
}
}
// 如果高程值超出范围,返回最后一个颜色
const lastStop = colorStops[colorStops.length - 1];
return `rgb(${lastStop.color[0]}, ${lastStop.color[1]}, ${lastStop.color[2]},0.5)`;
}
function getRandomNum(Min, Max) {
const Range = Max - Min + 1;
const Rand = Math.random();
return Min + Math.floor(Rand * Range);
}
</script>
</body>
</html>

View File

@ -0,0 +1,113 @@
import numpy as np
from scipy.interpolate import griddata
import json
# 输入数据
data = [
{"x":117.224793, "y":31.826156, "z":146.9, "value":10},
{"x":117.225075, "y":31.826087, "z":146.7, "value":20},
{"x":117.224762, "y":31.826164, "z":126.4, "value":40},
{"x":117.22503, "y":31.826097, "z":122.1, "value":10},
{"x":117.224726, "y":31.826172, "z":76.4, "value":50},
{"x":117.225057, "y":31.826091, "z":73.7, "value":30},
{"x":117.225231, "y":31.826224, "z":139.5, "value":60},
{"x":117.225226, "y":31.826208, "z":111.9, "value":70},
{"x":117.225282, "y":31.826299, "z":52, "value":20},
{"x":117.225176, "y":31.826403, "z":147.1, "value":10},
{"x":117.22491, "y":31.826468, "z":137.1, "value":100},
{"x":117.225166, "y":31.826406, "z":120.9, "value":30},
{"x":117.224881, "y":31.826476, "z":108, "value":40},
{"x":117.225204, "y":31.826396, "z":72.2, "value":60},
{"x":117.224856, "y":31.826482, "z":67.6, "value":90}
]
# 提取坐标和值
points = np.array([(d['x'], d['y'], d['z']) for d in data])
values = np.array([d['value'] for d in data])
# 创建网格
x_min, x_max = points[:, 0].min(), points[:, 0].max()
y_min, y_max = points[:, 1].min(), points[:, 1].max()
z_min, z_max = points[:, 2].min(), points[:, 2].max()
# 生成网格点 - 增加网格密度以获得更精细的点云
grid_x, grid_y, grid_z = np.mgrid[
x_min:x_max:30j,
y_min:y_max:30j,
z_min:z_max:30j
]
# 进行三维插值
grid_values = griddata(
points,
values,
(grid_x, grid_y, grid_z),
method='linear',
fill_value=np.nan # 对于超出凸包的区域填充NaN
)
# 提取所有有效点非NaN值
valid_mask = ~np.isnan(grid_values)
interpolated_points = {
"x": grid_x[valid_mask].tolist(),
"y": grid_y[valid_mask].tolist(),
"z": grid_z[valid_mask].tolist(),
"values": grid_values[valid_mask].tolist()
}
# 保存插值点云到JSON文件
with open('interpolated_point_cloud.json', 'w') as f:
json.dump(interpolated_points, f, indent=2)
print("插值点云已保存到 interpolated_point_cloud.json")
# 创建可视化图形(可选)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
# 绘制原始点
scatter1 = ax.scatter(points[:, 0], points[:, 1], points[:, 2],
c=values, cmap=cm.viridis, s=50, label='Original Points')
# 绘制插值点云(采样部分点以避免过于密集)
sample_mask = np.random.choice(len(interpolated_points["x"]),
min(1000, len(interpolated_points["x"])),
replace=False)
sampled_x = [interpolated_points["x"][i] for i in sample_mask]
sampled_y = [interpolated_points["y"][i] for i in sample_mask]
sampled_z = [interpolated_points["z"][i] for i in sample_mask]
sampled_values = [interpolated_points["values"][i] for i in sample_mask]
scatter2 = ax.scatter(sampled_x, sampled_y, sampled_z,
c=sampled_values, cmap=cm.viridis, s=10, alpha=0.5,
label='Interpolated Points')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Original and Interpolated Points')
ax.legend()
plt.colorbar(scatter1, ax=ax, shrink=0.5, aspect=5)
plt.savefig('point_cloud_visualization.png', dpi=300, bbox_inches='tight')
plt.show()
print("可视化结果已保存到 point_cloud_visualization.png")
# 返回JSON数据
print("\n插值点云JSON数据结构:")
print(f"点数: {len(interpolated_points['x'])}")
print(f"X范围: [{min(interpolated_points['x']):.6f}, {max(interpolated_points['x']):.6f}]")
print(f"Y范围: [{min(interpolated_points['y']):.6f}, {max(interpolated_points['y']):.6f}]")
print(f"Z范围: [{min(interpolated_points['z']):.6f}, {max(interpolated_points['z']):.6f}]")
print(f"值范围: [{min(interpolated_points['values']):.2f}, {max(interpolated_points['values']):.2f}]")
# 如果您需要直接使用这个JSON数据可以这样访问:
# interpolated_points["x"] - 所有点的X坐标列表
# interpolated_points["y"] - 所有点的Y坐标列表
# interpolated_points["z"] - 所有点的Z坐标列表
# interpolated_points["values"] - 所有点的值列表

View File

@ -0,0 +1,152 @@
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
<script src="./Volume .js"></script>
</head>
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<script>
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(117.22603, 31.821097, 500),
orientation: {
heading: Cesium.Math.toRadians(348.3), // 水平旋转围绕Y轴0为正北方向
pitch: Cesium.Math.toRadians(-35.8), // 上下旋转围绕X轴-90为俯视地面
roll: 0.0 // 视口的翻滚角度围绕Z轴0为不翻转
},
});
function getElevationColor(elevation) {
// 确保高程值在0-10000范围内
const clampedElevation = Math.max(0, Math.min(100, elevation));
// 定义10个关键高程点的颜色
const colorStops = [
{ value: 0, color: [0, 100, 0] }, // 深绿色 - 海平面
{ value: 10, color: [34, 139, 34] }, // 森林绿
{ value: 20, color: [152, 251, 152] }, // 浅绿色
{ value: 30, color: [240, 230, 140] }, // 卡其色
{ value: 40, color: [255, 215, 0] }, // 金黄色
{ value: 50, color: [255, 165, 0] }, // 橙色
{ value: 60, color: [255, 140, 0] }, // 深橙色
{ value: 70, color: [255, 99, 71] }, // 番茄红
{ value: 80, color: [255, 69, 0] }, // 红橙色
{ value: 90, color: [255, 0, 0] }, // 红色
{ value: 100, color: [128, 0, 0] } // 深红色 - 最高点
];
// 找到高程值所在的区间
for (let i = 0; i < colorStops.length - 1; i++) {
const currentStop = colorStops[i];
const nextStop = colorStops[i + 1];
if (clampedElevation >= currentStop.value && clampedElevation <= nextStop.value) {
// 计算在当前区间中的比例 (0-1)
const ratio = (clampedElevation - currentStop.value) /
(nextStop.value - currentStop.value);
// 对RGB三个通道分别进行插值
const r = Math.round(currentStop.color[0] +
ratio * (nextStop.color[0] - currentStop.color[0]));
const g = Math.round(currentStop.color[1] +
ratio * (nextStop.color[1] - currentStop.color[1]));
const b = Math.round(currentStop.color[2] +
ratio * (nextStop.color[2] - currentStop.color[2]));
// 返回RGB颜色字符串
return `rgb(${r}, ${g}, ${b},0.3)`;
}
}
// 如果高程值超出范围,返回最后一个颜色
const lastStop = colorStops[colorStops.length - 1];
return `rgb(${lastStop.color[0]}, ${lastStop.color[1]}, ${lastStop.color[2]},0.3)`;
}
ininPolygonByPosition();
// 根据经纬度创建多边形
function ininPolygonByPosition() {
let geometryInstances1 = []
aaa.x.forEach((element, index) => {
const center = Cesium.Cartesian3.fromDegrees(element, aaa.y[index], aaa.z[index]);
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
const boxInstances = []; // 填充部分
const FILL_COLOR = Cesium.Color.fromCssColorString(getElevationColor(aaa.values[index]))
let xLength = 1.5;
let yLength = 1.5;
let zLength = 1.5;
geometryInstances1.push(
new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
minimum: new Cesium.Cartesian3(-xLength, -yLength, -zLength),
maximum: new Cesium.Cartesian3(xLength, yLength, zLength)
}),
modelMatrix: enuMatrix,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(FILL_COLOR)
},
})
)
});
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: geometryInstances1,
appearance: new Cesium.PerInstanceColorAppearance({
translucent: true,
flat: true
}),
}));
}
const tileset = new Cesium.Cesium3DTileset({
url: "https://data.mars3d.cn/3dtiles/qx-teh/tileset.json",
});
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
// viewer.zoomTo(tileset)
var r = 255;
var g = 255;
var b = 255;
var a = 0.75;
tileset.style = new Cesium.Cesium3DTileStyle({ color: "color('rgba(" + r + "," + g + "," + b + ", " + a + ")')" })
})
.catch(function (error) {
console.log(error);
});
</script>
</body>
</html>

View File

@ -0,0 +1,178 @@
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
</head>
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<script>
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(110, 30, 10000)
});
initBoxByCenterPoint();
initBoxByPoint();
ininBoxByPosition();
ininPolygonByPosition();
// 根据中心点+x,y,z 组合
function initBoxByCenterPoint() {
const center = Cesium.Cartesian3.fromDegrees(110, 30, 1000);
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
const boxInstances = []; // 填充部分
const FILL_COLOR = Cesium.Color.fromCssColorString("rgba(53,203,196, 0.5)"); // 填充色
let xLength = 1000;
let yLength = 500;
let zLength = 500;
// 体
boxInstances.push(new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
minimum: new Cesium.Cartesian3(-xLength, -yLength, -zLength),
maximum: new Cesium.Cartesian3(xLength, yLength, zLength)
}),
modelMatrix: enuMatrix,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(FILL_COLOR)
},
id: '局部坐标立方体',
datas: {
name: '局部坐标立方体'
}
}));
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: boxInstances,
appearance: new Cesium.PerInstanceColorAppearance({
translucent: true,
flat: true
}),
asynchronous: false
}));
}
// 根据中心坐标+局部顶点坐标+三角形索引创建盒子
function initBoxByPoint() {
const positions = new Float64Array([
0.0, 0.0, 0.0,
1000.0, 0.0, 0.0,
0.0, 1000.0, 0.0,
0.0, 0.0, 0.0,
1000.0, 0.0, 0.0,
0.0, 0, 1000.0
]);
const geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: positions
})
},
indices: new Uint16Array([0, 1, 2, 3, 4, 5, 0, 5, 2]),
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
});
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(110.03, 29.99, 1000));
let geometryInstances = [
new Cesium.GeometryInstance({
geometry: geometry,
id: 'webgl顶点',
modelMatrix: modelMatrix,
attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED) }
})
];
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: geometryInstances,
appearance: new Cesium.MaterialAppearance({
material: Cesium.Material.fromType('Color')
})
}));
}
// 根据经纬度创建多边形BOX
function ininBoxByPosition() {
let obj = {
minx: 110.02,
miny: 30.02,
maxx: 110.04,
maxy: 30.06,
minz: 0,
maxz: 2000
}
let geometryInstances1 = [
new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(obj.minx, obj.miny, obj.maxx, obj.maxy),
height: obj.minz,
extrudedHeight: obj.maxz,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
}),
id: '矩形1',
attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.2)) }
}),
]
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: geometryInstances1,
appearance: new Cesium.PerInstanceColorAppearance({
translucent: true,
flat: true
}),
}));
}
// 根据经纬度创建多边形
function ininPolygonByPosition() {
let geometryInstances1 = [
new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArrayHeights([110.01,30.01,0.0,110.015,30.015,0.0,110.015,30.015,2000.0,110.01,30.01,2000.0,110.01,30.01,0.0,])
),
perPositionHeight: true, //是否使用高度
}),
id: '多边形',
attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GREEN.withAlpha(1)) }
}),
]
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: geometryInstances1,
appearance: new Cesium.PerInstanceColorAppearance({
translucent: true,
flat: true
}),
}));
}
</script>
</body>
</html>

View File

@ -0,0 +1,129 @@
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
</head>
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<script>
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
const modelCenter = Cesium.Cartesian3.fromDegrees(112, 23, 0)
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(modelCenter)
// 4. 创建着色器程序
const vertexShaderText = `
in vec3 position;
void main() {
gl_Position = czm_projection * czm_modelView * vec4(position, 1.0);
}
`;
const fragmentShaderText = `
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色
}
`;
const createCommand = (frameState, matrix) => {
const attributeLocations = {
"position": 0,
}
const uniformMap = {
u_color() {
return Cesium.Color.HONEYDEW
},
}
const positionBuffer = Cesium.Buffer.createVertexBuffer({
usage: Cesium.BufferUsage.STATIC_DRAW,
typedArray: new Float32Array([
0.0, 0.0, 0.0,
1000.0, 0.0, 0.0,
0.0, 1000.0, 0.0,
0.0, 0.0, 0.0,
1000.0, 0.0, 0.0,
0.0, 0, 1000.0
]),
context: frameState.context,
})
const vertexArray = new Cesium.VertexArray({
context: frameState.context,
attributes: [{
indices: new Uint16Array([0, 1, 2, 3, 4, 5, 0, 5, 2]),
vertexBuffer: positionBuffer,
componentsPerAttribute: 3,
componentDatatype: Cesium.ComponentDatatype.FLOAT
}]
})
const program = Cesium.ShaderProgram.fromCache({
context: frameState.context,
vertexShaderSource: vertexShaderText,
fragmentShaderSource: fragmentShaderText,
attributeLocations: attributeLocations,
})
const renderState = Cesium.RenderState.fromCache({
depthTest: {
enabled: true
}
})
return new Cesium.DrawCommand({
modelMatrix: matrix,
vertexArray: vertexArray,
shaderProgram: program,
uniformMap: uniformMap,
renderState: renderState,
pass: Cesium.Pass.OPAQUE,
})
}
/* ----- See Here ↓ ------ */
class StaticTrianglePrimitive {
/**
* @param {Matrix4} modelMatrix matrix to WorldCoordinateSystem
*/
constructor(modelMatrix) {
this._modelMatrix = modelMatrix
}
/**
* @param {FrameState} frameState
*/
update(frameState) {
const command = createCommand(frameState, this._modelMatrix)
frameState.commandList.push(command)
}
}
viewer.scene.globe.depthTestAgainstTerrain = true
viewer.scene.primitives.add(new StaticTrianglePrimitive(modelMatrix))
// 设置相机位置以查看三角形
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(112, 23, 5000.0)
});
</script>
</body>
</html>

View File

@ -0,0 +1,277 @@
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
</head>
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
<div style="position: absolute; z-index: 1000; left: 0;top: 0;">
<button onclick="customShader1()">贴图</button>
<button onclick="customShader2()">贴图2</button>
<button onclick="customShader3()">贴图3</button>
<button onclick="clears()">清除</button>
</div>
<script type="text/javascript">
window.viewer = new Cesium.Viewer('map', {
imageryProvider: false,
baseLayerPicker: false,
});
var xyz = new Cesium.UrlTemplateImageryProvider({
"credit": "安徽",
"url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
})
viewer.imageryLayers.addImageryProvider(xyz)
// 开启帧率
viewer.scene.debugShowFramesPerSecond = true;
const tileset = new Cesium.Cesium3DTileset({
url: "./data/tileset.json",
});
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset)
})
.catch(function (error) {
console.log(error);
});
function customShader1() {
let customShader = new Cesium.CustomShader({
//设置变量,由顶点着色器传递给片元着色器
varyings: {
v_normalMC: Cesium.VaryingType.VEC3,
v_st: Cesium.VaryingType.VEC3
},
//外部传给顶点着色器或者片元着色器
uniforms: {
u_texture: {
value: new Cesium.TextureUniform({
url: "./z.png"
}),
type: Cesium.UniformType.SAMPLER_2D
},
u_texture1: {
value: new Cesium.TextureUniform({
url: "./z.png"
}),
type: Cesium.UniformType.SAMPLER_2D
},
z_texture1: {
value: new Cesium.TextureUniform({
url: "./z.png"
}),
type: Cesium.UniformType.SAMPLER_2D
}
},
//贴纹理
//顶点着色器
//将法向量从顶点着色器设置变量传给片元着色器
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
v_normalMC = vsInput.attributes.normalMC;
v_st=vsInput.attributes.positionMC ;
}`,
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
//这里是设置要贴图的图片的尺寸,设置小了会重复
float width = 190.0;
float height = 190.0;
vec3 rgb;
//这是是设置了屋顶的颜色当和法向量平行时就是屋顶这里设置0.95,相当于垂直,建筑物四周开始贴图
if (dot(vec3(0.0, 1.0, 0.0), v_normalMC) > 0.95) {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
float textureY = mod(positionMC.y, height) / height;
textureX = mod(positionMC.x, width) / width;
rgb = texture(z_texture1, vec2(textureX, textureY)).rgb;
material.diffuse = rgb;
} else {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
float textureY = mod(positionMC.y, height) / height;
if (dotYAxis > 0.71 || dotYAxis < -0.71) {
//x代表的是前后面
textureX = mod(positionMC.x, width) / width;
rgb = texture(u_texture, vec2(textureX, textureY)).rgb;
} else {
//z代表的是左右面
textureX = mod(positionMC.z, width) / width;
rgb = texture(u_texture1, vec2(textureX, textureY)).rgb;
}
material.diffuse = rgb;
}
}`
})
tileset.customShader = customShader
}
function customShader2() {
let customShader = new Cesium.CustomShader({
// lightingModel: Cesium.LightingModel.UNLIT,
// lightingModel: Cesium.LightingModel.PBR,
//设置变量,由顶点着色器传递给片元着色器
varyings: {
v_normalMC: Cesium.VaryingType.VEC3,
v_st: Cesium.VaryingType.VEC3
},
//外部传给顶点着色器或者片元着色器
uniforms: {
u_texture: {
value: new Cesium.TextureUniform({
url: "./wall.jpg"
}),
type: Cesium.UniformType.SAMPLER_2D
},
u_texture1: {
value: new Cesium.TextureUniform({
url: "./wall.jpg"
}),
type: Cesium.UniformType.SAMPLER_2D
}
},
//贴纹理
//顶点着色器
//将法向量从顶点着色器设置变量传给片元着色器
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
v_normalMC = vsInput.attributes.normalMC;
v_st=vsInput.attributes.positionMC ;
}`,
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
//这里是设置要贴图的图片的尺寸,设置小了会重复
float width = 30.0;
float height = 70.0;
vec3 rgb;
//这是是设置了屋顶的颜色当和法向量平行时就是屋顶这里设置0.95,相当于垂直,建筑物四周开始贴图
if (dot(vec3(0.0, 1.0, 0.0), v_normalMC) > 0.95) {
material.diffuse = vec3(0.65, 0.65, 0.65);
} else {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
// cos(45deg) 约等于 0.71,这里是建筑物四周的向量与法向量会大于四十五度夹角
if (dotYAxis > 0.71 || dotYAxis < -0.71) {
//x代表的是前后面
textureX = mod(positionMC.x, width) / width;
} else {
//z代表的是左右面
textureX = mod(positionMC.z, width) / width;
}
float textureY = mod(positionMC.y, height) / height;
//我这里是根据建筑物高度贴了两张不同的图片
if (positionMC.y > 30.0) {
rgb = texture(u_texture, vec2(textureX, textureY)).rgb;
} else {
rgb = texture(u_texture1, vec2(textureX, textureY)).rgb;
}
material.diffuse = rgb;
//此处以下为光线效果
float _baseHeight = 10.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
float _glowRange = 120.0; // 光环的移动范围(高度)
float vtxf_height = fsInput.attributes.positionMC.y - _baseHeight;
float vtxf_a13 = fract(czm_frameNumber / 360.0); //此处括号内分母为移动速度,数值越大,速度越慢
float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
float vtxf_diff = step(0.01, abs(vtxf_h - vtxf_a13)); // 0.1 为高亮光条的范围(粗细)
material.diffuse += material.diffuse * (1.0 - vtxf_diff);
}
}`
})
tileset.customShader = customShader
}
function customShader3() {
let customShader = new Cesium.CustomShader({
varyings: {
v_normalMC: Cesium.VaryingType.VEC3,
v_st: Cesium.VaryingType.VEC3
},
//外部传给顶点着色器或者片元着色器
uniforms: {
u_texture: {
value: new Cesium.TextureUniform({
url: "./wall.jpg"
}),
type: Cesium.UniformType.SAMPLER_2D
},
u_texture1: {
value: new Cesium.TextureUniform({
url: "./wall1.jpg"
}),
type: Cesium.UniformType.SAMPLER_2D
}
},
//贴纹理
//顶点着色器
//将法向量从顶点着色器设置变量传给片元着色器
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
v_normalMC = vsInput.attributes.normalMC;
v_st=vsInput.attributes.positionMC ;
}`,
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
//这里是设置要贴图的图片的尺寸,设置小了会重复
float width = 30.0;
float height = 70.0;
vec3 rgb;
//这是是设置了屋顶的颜色当和法向量平行时就是屋顶这里设置0.95,相当于垂直,建筑物四周开始贴图
if (dot(vec3(0.0, 1.0, 0.0), v_normalMC) > 0.95) {
material.diffuse = vec3(0.65, 0.65, 0.65);
} else {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
// cos(45deg) 约等于 0.71,这里是建筑物四周的向量与法向量会大于四十五度夹角
if (dotYAxis > 0.71 || dotYAxis < -0.71) {
textureX = mod(positionMC.x, width) / width;
} else {
textureX = mod(positionMC.z, width) / width;
}
float textureY = mod(positionMC.y, height) / height;
rgb = texture(u_texture1, vec2(textureX, textureY)).rgb;
material.diffuse = rgb;
}
}`
})
tileset.customShader = customShader
}
function clears() {
let customShader = new Cesium.CustomShader({})
tileset.customShader = customShader
}
</script>
</body>
</html>

46803
examples/cesiumEx/Volume .js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -195,138 +195,138 @@ var exampleConfig = {
name_en: "",
thumbnail: "0.jpg",
fileName: "00"
},{
name: "1.1、默认设置",
name_en: "1.1、默认设置",
thumbnail: "1.1、默认设置.jpg",
fileName: "1.1、默认设置"
},
{
name: "1.2、颜色",
name_en: "1.2、颜色",
thumbnail: "1.2、颜色.jpg",
fileName: "1.2、颜色"
},
{
name: "1.3、坐标、坐标转换",
name_en: "1.3、坐标、坐标转换",
thumbnail: "1.3、坐标、坐标转换.jpg",
fileName: "1.3、坐标、坐标转换"
},
{
name: "1.4、屏幕、场景、地表坐标",
name_en: "1.4、屏幕、场景、地表坐标",
thumbnail: "1.4、屏幕、场景、地表坐标.jpg",
fileName: "1.4、屏幕、场景、地表坐标"
},
{
name: "1.5、相机",
name_en: "1.5、相机",
thumbnail: "1.5、相机.jpg",
fileName: "1.5、相机"
},
{
name: "1.6、事件",
name_en: "1.6、事件",
thumbnail: "1.6、事件.jpg",
fileName: "1.6、事件"
},
{
name: "1.7、飞行漫游",
name_en: "1.7、飞行漫游",
thumbnail: "1.7、飞行漫游.jpg",
fileName: "1.7、飞行漫游"
},
{
name: "1.8、时间运动",
name_en: "1.8、时间运动",
thumbnail: "1.8、时间运动.jpg",
fileName: "1.8、时间运动"
},
{
name: "1.9、气泡窗口",
name_en: "1.9、气泡窗口",
thumbnail: "1.9、气泡窗口.jpg",
fileName: "1.9、气泡窗口"
},
{
name: "1.10、反选遮罩",
name_en: "1.10、反选遮罩",
thumbnail: "1.10、反选遮罩.jpg",
fileName: "1.10、反选遮罩"
},
{
name: "1.11、加载shp",
name_en: "1.11、加载shp",
thumbnail: "1.11、加载shp.jpg",
fileName: "1.11、加载shp"
},
{
name: "1.12、加载mvt",
name_en: "1.12、加载mvt",
thumbnail: "1.12、加载mvt.jpg",
fileName: "1.12、加载mvt"
},
{
name: "1.13、地表透明度",
name_en: "1.13、地表透明度",
thumbnail: "1.13、地表透明度.jpg",
fileName: "1.13、地表透明度"
},
{
name: "1.14、倾斜摄影单体",
name_en: "1.14、倾斜摄影单体",
thumbnail: "1.14、倾斜摄影单体.jpg",
fileName: "1.14、倾斜摄影单体"
},
{
name: "1.15、罗盘、导航条",
name_en: "1.15、罗盘、导航条",
thumbnail: "1.15、罗盘、导航条.jpg",
fileName: "1.15、罗盘、导航条"
},
{
name: "1.16、绕点飞行",
name_en: "1.16、绕点飞行",
thumbnail: "1.16、绕点飞行.jpg",
fileName: "1.16、绕点飞行"
},
{
name: "1.17、深度检测",
name_en: "1.17、深度检测",
thumbnail: "1.17、深度检测.jpg",
fileName: "1.17、深度检测"
},
{
name: "1.18、echarts时间轴",
name_en: "1.18、echarts时间轴",
thumbnail: "1.18、echarts时间轴.jpg",
fileName: "1.18、echarts时间轴"
},
{
name: "1.19、任意坐标转换",
name_en: "1.19、任意坐标转换",
thumbnail: "1.19、任意坐标转换.jpg",
fileName: "1.19、任意坐标转换"
},
{
name: "1.20、echarts配置",
name_en: "1.20、echarts配置",
thumbnail: "1.20、echarts配置.jpg",
fileName: "1.20、echarts配置"
},
{
name: "1.22、根据点获取高度",
name_en: "1.22、根据点获取高度",
thumbnail: "1.22、根据点获取高度.jpg",
fileName: "1.22、根据点获取高度"
},
{
name: "加载超图S3M模型",
name_en: "加载超图S3M模型",
thumbnail: "s3m.jpg",
fileName: "s3m"
},
}, {
name: "1.1、默认设置",
name_en: "1.1、默认设置",
thumbnail: "1.1、默认设置.jpg",
fileName: "1.1、默认设置"
},
{
name: "1.2、颜色",
name_en: "1.2、颜色",
thumbnail: "1.2、颜色.jpg",
fileName: "1.2、颜色"
},
{
name: "1.3、坐标、坐标转换",
name_en: "1.3、坐标、坐标转换",
thumbnail: "1.3、坐标、坐标转换.jpg",
fileName: "1.3、坐标、坐标转换"
},
{
name: "1.4、屏幕、场景、地表坐标",
name_en: "1.4、屏幕、场景、地表坐标",
thumbnail: "1.4、屏幕、场景、地表坐标.jpg",
fileName: "1.4、屏幕、场景、地表坐标"
},
{
name: "1.5、相机",
name_en: "1.5、相机",
thumbnail: "1.5、相机.jpg",
fileName: "1.5、相机"
},
{
name: "1.6、事件",
name_en: "1.6、事件",
thumbnail: "1.6、事件.jpg",
fileName: "1.6、事件"
},
{
name: "1.7、飞行漫游",
name_en: "1.7、飞行漫游",
thumbnail: "1.7、飞行漫游.jpg",
fileName: "1.7、飞行漫游"
},
{
name: "1.8、时间运动",
name_en: "1.8、时间运动",
thumbnail: "1.8、时间运动.jpg",
fileName: "1.8、时间运动"
},
{
name: "1.9、气泡窗口",
name_en: "1.9、气泡窗口",
thumbnail: "1.9、气泡窗口.jpg",
fileName: "1.9、气泡窗口"
},
{
name: "1.10、反选遮罩",
name_en: "1.10、反选遮罩",
thumbnail: "1.10、反选遮罩.jpg",
fileName: "1.10、反选遮罩"
},
{
name: "1.11、加载shp",
name_en: "1.11、加载shp",
thumbnail: "1.11、加载shp.jpg",
fileName: "1.11、加载shp"
},
{
name: "1.12、加载mvt",
name_en: "1.12、加载mvt",
thumbnail: "1.12、加载mvt.jpg",
fileName: "1.12、加载mvt"
},
{
name: "1.13、地表透明度",
name_en: "1.13、地表透明度",
thumbnail: "1.13、地表透明度.jpg",
fileName: "1.13、地表透明度"
},
{
name: "1.14、倾斜摄影单体",
name_en: "1.14、倾斜摄影单体",
thumbnail: "1.14、倾斜摄影单体.jpg",
fileName: "1.14、倾斜摄影单体"
},
{
name: "1.15、罗盘、导航条",
name_en: "1.15、罗盘、导航条",
thumbnail: "1.15、罗盘、导航条.jpg",
fileName: "1.15、罗盘、导航条"
},
{
name: "1.16、绕点飞行",
name_en: "1.16、绕点飞行",
thumbnail: "1.16、绕点飞行.jpg",
fileName: "1.16、绕点飞行"
},
{
name: "1.17、深度检测",
name_en: "1.17、深度检测",
thumbnail: "1.17、深度检测.jpg",
fileName: "1.17、深度检测"
},
{
name: "1.18、echarts时间轴",
name_en: "1.18、echarts时间轴",
thumbnail: "1.18、echarts时间轴.jpg",
fileName: "1.18、echarts时间轴"
},
{
name: "1.19、任意坐标转换",
name_en: "1.19、任意坐标转换",
thumbnail: "1.19、任意坐标转换.jpg",
fileName: "1.19、任意坐标转换"
},
{
name: "1.20、echarts配置",
name_en: "1.20、echarts配置",
thumbnail: "1.20、echarts配置.jpg",
fileName: "1.20、echarts配置"
},
{
name: "1.22、根据点获取高度",
name_en: "1.22、根据点获取高度",
thumbnail: "1.22、根据点获取高度.jpg",
fileName: "1.22、根据点获取高度"
},
{
name: "加载超图S3M模型",
name_en: "加载超图S3M模型",
thumbnail: "s3m.jpg",
fileName: "s3m"
},
// {
// name: "相机",
@ -1322,6 +1322,42 @@ var exampleConfig = {
thumbnail: "8.1.5、等值面.jpg",
fileName: "8.1.5、等值面"
},
{
name: "8.2.6、蜂窝热力图",
name_en: "8.2.6、蜂窝热力图",
thumbnail: "8.2.6、蜂窝热力图.jpg",
fileName: "8.2.6、蜂窝热力图"
},
{
name: "8.2.7、体渲染",
name_en: "8.2.7、体渲染",
thumbnail: "8.2.7、体渲染.jpg",
fileName: "8.2.7、体渲染"
},
]
},
}
},
"OGC": {
name: "9、性能优化",
name_en: "9、性能优化",
content: {
"map11cdddwsss3111111233231": {
name: "9.1、数据",
name_en: "9.1、数据端",
content: [
{
name: "9.1.1、Primitive",
name_en: "9.1.1、Primitive",
thumbnail: "9.1.1、Primitive.jpg",
fileName: "9.1.1、Primitive"
},
{
name: "9.1.2、DrawCommand",
name_en: "9.1.2、DrawCommand",
thumbnail: "9.1.2、DrawCommand.jpg",
fileName: "9.1.2、DrawCommand"
},
]
},
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
examples/cesiumEx/x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
examples/cesiumEx/y.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
examples/cesiumEx/z.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB