Python+CesiumLabv4.0.17生成上W个高度不一、颜色不一立方体的3D TILES文件

一、生成SHP文件

复制代码
import geopandas as gpd
import numpy as np
import os
from shapely.geometry import Polygon  # <--- 添加这一行即可解决报错

def generate_cube_shp_optimized(output_dir="cube_shp_data_rgb", num_cubes=100):
    """
    生成带有独立RGB颜色字段的SHP文件,以完美兼容CesiumLab
    """
    # 1. 创建输出目录
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    
    polygons, heights = [], []
    colors_r, colors_g, colors_b = [], [], []
    
    # 2. 循环生成随机立方体数据
    for _ in range(num_cubes):
        # 随机生成中心点坐标 (长沙附近区域)
        center_x = np.random.uniform(112.9, 113.0)
        center_y = np.random.uniform(28.1, 28.2)
        
        # 设置立方体底面的边长
        size = 0.0005 
        half_size = size / 2
        
        # 创建闭合的矩形面
        polygon = gpd.pd.Series([Polygon([
            (center_x - half_size, center_y - half_size),
            (center_x + half_size, center_y - half_size),
            (center_x + half_size, center_y + half_size),
            (center_x - half_size, center_y + half_size),
            (center_x - half_size, center_y - half_size) 
        ])])[0]
        polygons.append(polygon)
        
        # 赋予高度属性 (10 到 100 米)
        heights.append(np.random.randint(10, 100))
        
        # 生成独立的 RGB 颜色值 (0-255)
        colors_r.append(np.random.randint(0, 256))
        colors_g.append(np.random.randint(0, 256))
        colors_b.append(np.random.randint(0, 256))
        
    # 3. 构建 GeoDataFrame
    gdf = gpd.GeoDataFrame({
        'geometry': polygons,
        'height': heights,      # 高度字段
        'color_r': colors_r,    # 红色通道
        'color_g': colors_g,    # 绿色通道
        'color_b': colors_b     # 蓝色通道
    })
    
    # 4. 设置坐标系 (WGS84)
    gdf.set_crs(epsg=4326, inplace=True)
    
    # 5. 导出为 Shapefile
    output_path = os.path.join(output_dir, "cubes_rgb.shp")
    gdf.to_file(output_path, driver="ESRI Shapefile")
    
    print(f"成功生成 {num_cubes} 个带RGB颜色的立方体数据!")
    print(f"文件保存路径: {os.path.abspath(output_dir)}")

# 执行生成函数
if __name__ == "__main__":
    generate_cube_shp_optimized()

二、CesiumLab中处理

导入数据与模型切片

打开CesiumLab软件,在左侧菜单栏选择"数据处理"模块,点击"通用模型切片"(部分版本或场景下也称为"矢量楼块切片")。在输入文件选项中,点击"+SHP"导入准备好的矢量数据文件。

三、Cesium中加载3d-tiles并设置颜色

复制代码
<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cesium GeoJSON 线要素加载示例</title>
    <!-- 引入 Cesium 库(这里使用官方 CDN,你也可以替换为本地路径) -->
    <script src="https://unpkg.com/cesium@1.138.0/Build/Cesium/Cesium.js"></script>
    <link
      href="https://unpkg.com/cesium@1.138.0/Build/Cesium/Widgets/widgets.css"
      rel="stylesheet"
    />
    <style>
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }

      .cesium-point-cloud {
        pointsize: 10px !important;
      }
    </style>
  </head>

  <body>
    <div id="cesiumContainer"></div>

    <script type="module">
      // 1. 初始化 Cesium 地图(替换 MFmap 为原生 Cesium 初始化)
      Cesium.Ion.defaultAccessToken =
        "defaultAccessToken"; // 替换为你的 Token,可从 Cesium 官网获取
      const viewer = new Cesium.Viewer("cesiumContainer", {
        // geocoder: false,
        // timeline: false,
        // animation: false,
        // baseLayerPicker: false,
        // fullscreenButton: false,
        // vrButton: false,
        // homeButton: false,
        // infoBox: false,
        // selectionIndicator: false,
        // navigationHelpButton: false,
        // sceneModePicker: false,
        // imageryProvider: false
      });

      // // 添加到地图
      // viewer.imageryLayers.addImageryProvider(gaodeImagery);

      // 定义异步加载函数
      async function loadLocalTileset() {
        try {
          // 拼接本地服务器URL
          // 注意:端口号需与你启动的服务器端口一致
          const url = "./3DTILES/cube/tileset.json";

          // 调用最新的 fromUrl 方法
          const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
            maximumScreenSpaceError: 0.5, // 强制最高精度
            skipLevelOfDetail: true, // 强制加载所有点
            dynamicScreenSpaceError: false, // 关闭自动隐藏
            cullRequestsWhileMoving: false, // 移动时不卸载
            cullWithChildrenBounds: false,
          });

          tileset.style = new Cesium.Cesium3DTileStyle({
            color: {
              conditions: [
                // 读取属性表中的 RGB 字段并应用颜色
                [
                  "true",
                  "rgba(${feature['color_r']}, ${feature['color_g']}, ${feature['color_b']}, 1.0)",
                ],
              ],
            },
          });

          // 添加到场景
          viewer.scene.primitives.add(tileset);

          // 调试:等待tileset加载完成后查看位置
          console.log("Tileset边界球中心:", tileset.boundingSphere.center);
          console.log("边界球半径:", tileset.boundingSphere.radius);

          // 尝试创建一个红色标记点来辅助定位
          const centerPoint = viewer.entities.add({
            position: tileset.boundingSphere.center,
            point: {
              color: Cesium.Color.RED,
              pixelSize: 10,
            },
          });

          // 尝试将相机移动到tileset位置
          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(
              116.403874,
              39.914885,
              300,
            ),
            orientation: {
              heading: 0,
              pitch: Cesium.Math.toRadians(-60),
              roll: 0,
            },
            duration: 1,
          });
        } catch (error) {
          console.error("加载失败:", error);
        }
      }

      loadLocalTileset();
    </script>
  </body>
</html>
相关推荐
不争不抢的佛系少年2 天前
Cesium模型没有动画怎么办?手把手教你通过代码给GLB模型添加动画!
cesium
用户83134859306984 天前
Vue3 + Cesium 实现城市 3D 场景下雪特效(按钮开关控制下雪启停)
cesium
BJ-Giser10 天前
CesiumJS升级全新VFX特效粒子系统
前端·可视化·cesium
白嫖叫上我10 天前
Cesium抗锯齿处理
cesium
白嫖叫上我10 天前
Cesium地球风格切换、昼夜交替效果
cesium
用户831348593069811 天前
Vue3 + Cesium 实现热气球第一人称自动飞行(支持手机端)
cesium
青山Coding12 天前
Cesium应用(六):三维地形中坡度分析的实现过程
前端·cesium
爱喝铁观音的谷力景辉15 天前
在Cesium中实现带箭头方向路线样式的技术详解
javascript·cesium
Nian.Baikal16 天前
Cesium 3D Tiles 加载与优化实战
前端·cesium