资讯动态

三维智慧城市系统实战:Cesium与SuperMap融合开发指南

发布时间:2026/10/25 2:59:43 来源:尧图企业网站定制
简介这是一套面向三维WebGIS开发者与智慧城市项目实践者的Cesium三维可视化工程兼容超图SuperMap三维服务适合具备一定前端与WebGL基础、希望快速搭建三维城市场景的读者参考。工程内含智慧城市、警情模拟、水积警情模拟三个独立场景每个HTML对应一个可运行示例可直接在VSCode或HBuilder中打开运行后台三维服务调用超图在线范例场景所有3D模型均已内置无需额外下载素材。压缩包共约2000个文件涵盖png、jpg等贴图资源js脚本、css样式与json配置以及s3m、gltf、glb等三维模型数据另有kml、geojson、terrain、wasm等地理与渲染相关文件整体约202.4MB。目录中Build、examples与cesium-d3kit.js、city系列脚本构成核心框架便于按模块查阅与二次开发。目前已有2355人学习下载适合作为三维智慧城市可视化项目的起步模板与场景搭建参考。1. 三维智慧城市系统从需求到选型为什么是 Cesium 加 SuperMap做三维智慧城市项目绕不开一个核心矛盾前端要好看、要流畅后端要能接住 GIS 平台沉淀的空间数据。很多团队一开始用游戏引擎做可视化效果确实惊艳但一碰到真实地理坐标系、倾斜摄影模型、地下管线、实时视频融合立刻翻车。另一条路是直接用 GIS 平台自带的三维客户端数据接入稳了但定制交互和视觉表现又受限于平台能力。这套方案要解决的就是在这两者之间找一个平衡点——用 Cesium 做三维 WebGL 渲染底座兼容超图 SuperMap 的三维服务让前端既有自由度又能直接消费 GIS 平台已经发布好的三维缓存、地形、影像和空间查询能力。适合正在做三维智慧城市毕设、课程设计或者需要交付一套可演示、可扩展的三维 GIS 方案的读者。2. 总体架构设计前后端分离与三维服务分层2.1 四层架构的职责划分这套系统我一般会拆成四层数据层、服务层、渲染层、应用层。数据层负责存放倾斜摄影 OSGB 数据、地形瓦片、影像瓦片、矢量面数据以及业务属性数据。服务层由 SuperMap iServer 承担把三维瓦片、地形、影像、数据查询、空间分析统一发布成 REST 或 WebSocket 服务。渲染层就是 Cesium 的 Viewer 加上自定义的图层管理、实体管理、交互工具。应用层则是具体的智慧城市业务面板比如楼宇分层、管线开挖、摄像头调阅、人口热力。这样分的好处是三维渲染和 GIS 服务解耦。Cesium 只负责“画”SuperMap 负责“算”和“管”。前端不需要直接解析 OSGB 或 S3M 格式只需要按约定的 URL 去请求瓦片或查询接口。后期如果换渲染引擎服务层不用动如果换 GIS 平台渲染层也不用大改。2.2 三维服务接入方式与坐标系约定Cesium 原生支持 3D Tiles而 SuperMap 的三维服务通常输出 S3M 或 3D Tiles 格式。实际对接时优先让 iServer 把三维缓存发布成 3D Tiles这样 Cesium 可以直接用Cesium3DTileset加载兼容性最好。如果平台版本只支持 S3M那就需要引入 SuperMap 提供的 Cesium 扩展包或者通过 iServer 的 REST 接口做一层转换。坐标系是血泪经验最多的地方。Cesium 内部用 WGS84 地理坐标SuperMap 数据可能是 CGCS2000 或地方坐标系。我的做法是所有服务发布前在 iServer 里统一转成 EPSG:4326 或 EPSG:4490前端不再做动态投影。如果确实需要地方坐标系就在 Cesium 里用Cesium.CustomDataSource配合Cesium.Transforms做局部偏移但偏移参数必须由后端下发不能写死在前端。// Cesium 加载 SuperMap iServer 发布的 3D Tiles 服务 const viewer new Cesium.Viewer(cesiumContainer, { terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( http://localhost:8090/iserver/services/3D-terrain/rest/realspace/terrain // 地形服务地址 ), imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ url: http://localhost:8090/iserver/services/map-img/rest/maps/img/wmts, // 影像瓦片服务 layer: img, style: default, format: image/png, tileMatrixSetID: c }) }); // 加载三维模型瓦片 const tileset await Cesium.Cesium3DTileset.fromUrl( http://localhost:8090/iserver/services/3D-building/rest/realspace/datas/building/tileset.json ); viewer.scene.primitives.add(tileset); viewer.zoomTo(tileset);这段代码里CesiumTerrainProvider负责地形WebMapTileServiceImageryProvider负责影像底图Cesium3DTileset负责建筑白模或倾斜摄影。三个 URL 都指向 iServer 的不同服务。参数上tileMatrixSetID要和 iServer 里 WMTS 能力文档中的一致通常是c或EPSG:4326。如果地形服务加载失败先检查 iServer 是否开启了地形缓存以及 Cesium 的terrainProvider是否在Viewer初始化时异步等待完成。2.3 模块划分与数据流前端模块我通常分成五块场景初始化、图层控制、实体交互、空间查询、业务面板。场景初始化负责创建 Viewer、加载地形影像和三维瓦片。图层控制用树形结构管理不同数据源支持显隐、透明度、叠加顺序。实体交互处理鼠标点击、悬停、绘制点线面。空间查询调用 iServer 的 REST API做缓冲区分析、通视分析、淹没分析。业务面板则根据查询结果渲染图表和属性表。数据流是单向的用户操作触发查询请求请求发到 iServer返回 GeoJSON 或 JSON 结果前端解析后生成 Cesium 实体或更新面板。反向的数据流只有一种用户在面板上修改属性通过 POST 请求写回数据库然后刷新对应图层。这种单向数据流让调试变得简单出问题先看请求有没有发出去再看返回结果对不对最后看渲染有没有生效。3. 核心功能实现三维场景、空间查询与业务联动3.1 三维场景初始化与性能调优场景初始化不只是 new 一个 Viewer。智慧城市项目动辄几十平方公里的倾斜摄影模型不加控制直接加载浏览器内存直接爆掉。我一般会做三件事第一开启 Cesium 的requestRenderMode只在需要重绘时渲染降低 GPU 占用第二设置maximumScreenSpaceError控制瓦片加载精度通常设 16 到 32 之间太大模型粗糙太小加载卡顿第三用Cesium3DTileset的maximumMemoryUsage限制内存默认 512MB可以根据机器配置调到 1024MB。viewer.scene.requestRenderMode true; // 按需渲染 viewer.scene.maximumScreenSpaceError 16; // 屏幕空间误差 tileset.maximumMemoryUsage 1024; // 最大内存占用 MB tileset.style new Cesium.Cesium3DTileStyle({ color: { conditions: [ [${height} 100, color(red)], [${height} 50, color(orange)], [true, color(white)] ] } });样式这段是按建筑高度着色${height}是三维瓦片里自带的属性字段。如果模型没有这个字段需要先在 iServer 里做属性挂接或者在前端用tileset.getProperty动态计算。性能调优没有银弹通常的做法是先用 Chrome Performance 录一段看是瓦片请求慢还是渲染帧率低再针对性调整。3.2 空间查询与 SuperMap REST API 对接空间查询是智慧城市系统的核心交互。用户在地图上画一个多边形系统要返回范围内的建筑、管线、人口等信息。SuperMap iServer 提供了 REST 空间查询接口前端用fetch或axios发 POST 请求请求体里带几何对象和查询参数。// 多边形缓冲区查询示例 const queryParam { queryMode: BufferQuery, queryParameters: { name: building, bufferDistance: 100, // 缓冲距离 100 米 spatialQueryMode: INTERSECT // 相交查询 }, geometry: { type: Polygon, points: [ { x: 116.397, y: 39.908 }, { x: 116.407, y: 39.908 }, { x: 116.407, y: 39.918 }, { x: 116.397, y: 39.918 } ] } }; const response await fetch( http://localhost:8090/iserver/services/data-building/rest/data/featureResults.json, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(queryParam) } ); const result await response.json(); // result.features 是 GeoJSON 格式的要素集合参数说明queryMode选BufferQuery表示缓冲区查询spatialQueryMode可以是INTERSECT、CONTAIN、WITHIN等。bufferDistance单位是米和坐标系有关如果是地理坐标系iServer 会自动按米做近似计算。返回的features可以直接用Cesium.GeoJsonDataSource.load加载到场景里也可以手动遍历生成实体。如果查询结果为空先检查几何对象的坐标顺序是不是经度在前、纬度在后这是最常见的踩坑点。3.3 业务面板与三维场景的联动业务面板和三维场景的联动我一般用事件总线做解耦。Cesium 的ScreenSpaceEventHandler监听鼠标点击拿到拾取的实体 ID然后通过事件总线通知面板组件加载对应属性。面板上的操作比如切换楼层、显示管线也通过事件总线反向通知场景更新样式。// 点击拾取实体 const handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction((movement) { const picked viewer.scene.pick(movement.position); if (Cesium.defined(picked) picked.id) { const entityId picked.id.id; eventBus.emit(entity-selected, entityId); // 通知面板 } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 面板控制楼层显隐 eventBus.on(floor-change, (floor) { tileset.style new Cesium.Cesium3DTileStyle({ color: { conditions: [ [${floor} ${floor}, color(cyan)], [true, color(white, 0.3)] ] } }); });这种模式的好处是面板组件不需要知道 Cesium 的存在场景也不需要知道面板怎么渲染。后期换 UI 框架或者把面板拆成独立微前端都不会影响三维核心逻辑。唯一要注意的是事件命名要统一我习惯用模块-动作的格式比如entity-selected、floor-change避免不同开发者起冲突。4. 避坑与常见问题坐标系、瓦片加载与内存泄漏4.1 模型位置偏移或漂浮现象三维建筑模型加载后整体偏移几百米或者悬浮在地形上方。原因通常是数据坐标系和 Cesium 场景坐标系不一致或者地形服务和模型服务的高程基准不同。解决先在 iServer 里确认模型数据的坐标系统一转成 EPSG:4490。如果地形有高程偏移用tileset.modelMatrix做平移修正但修正值必须从后端配置读取不能硬编码。4.2 瓦片加载慢或浏览器卡死现象场景旋转时瓦片一直加载帧率掉到个位数严重时浏览器无响应。原因一般是maximumScreenSpaceError设得太小或者同时加载了多个高精度图层。解决把maximumScreenSpaceError调到 16 到 32关闭暂时不需要的图层用viewer.scene.globe.show控制底图显隐。另外iServer 的瓦片服务要开启缓存第一次访问慢是正常的后续应该走缓存。4.3 空间查询返回空结果现象前端画了多边形调用查询接口返回features: []。原因可能是几何坐标顺序反了或者查询图层名和 iServer 里发布的数据源名称不一致。解决先检查 GeoJSON 的坐标是不是[经度, 纬度]再检查queryParameters.name是否和 iServer 服务列表里的数据集名称完全一致。如果还不行用 iServer 自带的查询页面测试同一组参数排除前端传参问题。4.4 内存泄漏与页面崩溃现象长时间运行后浏览器内存持续上涨最终页面崩溃。原因通常是 Cesium 实体只增不减或者事件监听没有销毁。解决在组件卸载时调用viewer.entities.removeAll()、viewer.scene.primitives.removeAll()并移除所有ScreenSpaceEventHandler。如果用了 Vue 或 React在beforeDestroy或useEffect的清理函数里做这些事。我一般会封装一个destroyViewer方法统一处理资源释放。4.5 服务跨域与 HTTPS 混合内容现象本地开发正常部署到服务器后三维服务请求被浏览器拦截。原因通常是 iServer 没有开启 CORS或者 HTTPS 页面请求了 HTTP 服务。解决在 iServer 的web.xml里配置 CORS 过滤器允许前端域名。如果页面是 HTTPS所有服务地址也必须升级到 HTTPS否则浏览器会阻止混合内容。这个坑在答辩演示时特别致命建议提前在目标环境完整跑一遍。5. 验收与答辩怎么证明这套三维智慧城市系统真的能跑验收三维智慧城市系统不能只看截图。我一般会准备一套演示脚本按顺序走一遍先展示地形和影像底图加载证明基础场景可用再加载倾斜摄影模型旋转缩放证明三维瓦片服务正常然后画多边形做缓冲区查询展示返回的建筑列表和属性面板最后演示一个业务联动比如点击楼宇显示楼层信息切换楼层高亮。每一步都要有明确的成功标准比如“模型加载后无偏移”“查询返回要素数量大于零”“面板数据与三维实体一致”。答辩时评委最容易问三个问题坐标系怎么统一的、性能怎么优化的、数据怎么更新的。坐标系问题回答“服务端统一转 EPSG:4490前端不做动态投影”。性能问题回答“按需渲染加屏幕空间误差控制瓦片走 iServer 缓存”。数据更新问题回答“通过 iServer 的数据服务接口做增量更新前端定时刷新或手动触发”。如果评委追问 SuperMap 和 Cesium 的版本兼容性就如实说“以 iServer 发布 3D Tiles 为准S3M 需要额外扩展包”不要编造版本号。验收表格可以这样设计验收项操作步骤预期结果实际结果地形加载打开页面观察地形起伏地形显示正常无裂缝通过模型加载加载建筑瓦片旋转缩放模型位置正确无漂浮通过空间查询画多边形执行缓冲区查询返回要素列表面板显示通过业务联动点击楼宇切换楼层三维高亮面板同步通过性能表现连续旋转 1 分钟帧率不低于 30fps通过从那以后我每次做三维项目都强制走一遍“坐标系确认、服务连通性测试、内存释放检查”这三步不管工期多紧都不跳过。希望这套方案能帮到你需要完整工程文件和配置说明的可以按文末方式获取。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑