资讯动态

Cesium与SuperMap三维服务兼容实战:S3M与3D Tiles加载与避坑

发布时间:2026/10/20 23:18:11 来源:尧图企业网站定制
简介面向WebGIS与三维可视化开发者的Cesium智慧城市工程兼容超图SuperMap三维服务内置智慧城市场景、警情模拟与水积警情模拟三个独立HTML场景所有3D模型均预先放置在工程内可直接在浏览器中体验城市级三维可视化效果降低二次开发门槛。压缩包共2000个文件大小约202.4MB其中647个png与274个jpg构成主要贴图与界面素材175个js承载业务逻辑69个css和37个json分别完成样式与数据配置s3m、gltf、glb等模型文件涵盖建筑与设施网格另有gif动画、svg图标、kml地理标注等补充资源整体类型丰富且目录层次清楚。当前已有2355人学习下载。工程通过Build、examples与city.js等模块组织场景便于按需定位使用VSCode或HBuild打开智慧城市.html、警情模拟示例.html等文件即可运行适合需要学习Cesium与SuperMap服务融合、开发智慧城市或警情可视化Demo的开发者参考。1. 基于Cesium的三维智慧城市系统为何先要解决SuperMap三维服务的兼容问题接手智慧城市项目时最常见的形态不是买一套GIS平台让用户装客户端而是要把已有成果塞进Web管理系统里。三维数据往往早用SuperMap相关产品发布好了倾斜摄影、白模、地下管网都在iServer里可前端框架指定了Cesium。第一个冒出来的问题就是Cesium能直接加载SuperMap的三维服务吗答案不是单纯能或不能而是“用对扩展就能”。这篇内容围绕一个核心场景展开Cesium作为前端三维底座SuperMap iServer作为数据服务端两者如何在一个三维智慧城市系统里共存。你会看到S3M与3D Tiles的真实差异、三条兼容路线的取舍、从最小页面到生产环境的完整代码以及几个能让调试进度倒退两天的坑。适合正在做WebGIS交付、被多源三维数据接入卡住的开发者和团队。2. 先搞懂数据格式再谈兼容S3M与3D Tiles的差异和三条落地路线2.1 为什么SuperMap发布的三维服务不能直接被Cesium拖进球里SuperMap iServer发布的三维服务底层数据绝大多数是S3M格式。S3M最初是面向海量三维空间数据的流式分块格式支持LOD、属性挂接、纹理压缩和实例化服务端通过REST接口按需返回节点数据。它和Cesium原生的3D Tiles在设计目标上高度相似都是为了解决“浏览器不能一次加载几十GB三维数据”的问题把大模型切碎、做多级细节、随视点调度。问题出在解析层。Cesium原生内核只认3D Tiles以及构成它的b3dm、i3dm、pnts等格式没有内置S3M解析器。也就是说浏览器拿到iServer返回的S3M二进制块并不知道该怎么渲染。把S3M服务地址直接塞给Cesium最常见的结果是控制台报错、图层列表为空或者地球一片白。这不是数据坏了也不是Cesium不行而是两者之间缺少一个“翻译层”。走兼容路线前先把这条底层结论放在心里只要目标是浏览器端用Cesium渲染SuperMap体系的三维成果本质工作就是解决“S3M或iServer三维服务如何在Cesium内核中变成可渲染对象”。围绕这个结论展开的三条路线成熟度、维护成本、交付效果差别很大。2.2 三条兼容路线扩展加载、转换发布、自研解析路线A是使用SuperMap体系提供的Cesium扩展版本业内最常见的叫法是iClient3D for Cesium。它是在Cesium基础上扩展出S3MTilesLayer等能力的前端库加入后Cesium可以直接请求iServer的S3M服务并完成解析、调度和渲染。这条路最大的优势是保留S3M的属性、LOD和空间索引不用动服务端数据适合已有大量S3M缓存的存量项目。路线B是把数据重新组织成3D Tiles再交给原生Cesium加载。实现方式有两类一类是在SuperMap桌面端工具里把模型、倾斜摄影或S3M缓存导出为3D Tiles另一类是用第三方转换工具做格式中转。做完后用Nginx或iServer静态发布前端用Cesium3DTileset加载。它的优点是前端不再依赖扩展库团队可以完全跟随Cesium社区生态走但代价是转换过程可能损失属性字段和构件级结构而且三维数据量极大时转换耗时和存储成本都不低。路线C是自研S3M解析器或写前端加载插件。听上去很技术实际维护成本极高。S3M的节点编码、纹理压缩、实例化结构都在持续演进团队如果没有源码级维护精力不建议碰。我见过有人为了绕开扩展库选择自研解析最终陷在格式兼容的泥潭里交付周期翻倍。2.3 选型标准按数据存量、团队结构和交付形态判断路线选型不是技术越新越好而是看手里的牌。如果iServer里已经发布了几百个S3M图层且后续数据更新还会继续走SuperMap生产管线那么路线A几乎是不用犹豫的选择——扩展加载可以把现有服务原封不动接到Cesium里数据更新后前端无需重新发版。如果项目交付物明确要求“前端零私有依赖”或者甲方指定只能用原生Cesium API那就得走路线B。需要注意数据体系越是深度使用SuperMap转换损耗越明显尤其是BIM构件、地下管网这类强调对象ID和属性查询的数据。选路线B之前一定要先做小范围数据试转验证属性保留率和加载性能别等全部数据转完才发现关键字段丢了。团队结构也要纳入考量。纯前端团队上手路线A最快因为接口形态接近Cesium原生写法如果有专职GIS工程师配合路线B可以做得更精致比如在转换前重做LOD分层、优化纹理压缩。对大多数三维智慧城市交付项目我的建议是第一版先用路线A跑通业务把S3M图层原样加载后续如果甲方有明确生态要求再抽一两个专题图层转3D Tiles做对比。这样可以最小成本验证CesiumiServer这套组合能否满足业务而不是一上来就在格式转换上押注。3. 搭建最小工程接入Cesium与SuperMap扩展先把三维地球初始化出来3.1 依赖引入的两种方式与版本管理不管最后选哪条路线第一步都是把Cesium和对应扩展库引到工程里。最省事的验证方式是用HTML页面直接引CDN确认目标数据能在浏览器里渲染再决定是否搬进Vue、React等框架。这样做的好处是能隔离问题渲染不出来时先排除工程构建的影响。!DOCTYPE html html head meta charsetutf-8 / title三维智慧城市最小页面/title link relstylesheet hrefcdn-path/Cesium/Widgets/widgets.css / script srccdn-path/Cesium/Cesium.js/script script srccdn-path/iclient3d/iclient3d.min.js/script /head body div idmap stylewidth:100%;height:100vh;/div script // 初始化三维地球viewer 是后续所有图层、相机操作的主入口 const viewer new Cesium.Viewer(map, { animation: false, // 关闭左下角动画控件让界面更干净 timeline: false, // 关闭时间轴避免误以为三维场景和时空数据强绑定 baseLayerPicker: false, // 不显示底图切换器减少用户误操作 terrainProvider: Cesium.createWorldTerrain() // 全球地形生产环境通常换本地地形 }); /script /body /html这段代码的关键点有两个。一是Cesium的CSS必须和JS来自同一个构建版本否则控件布局会错乱、图标加载不出来二是iClient3D的扩展库要放在Cesium之后加载因为它内部会基于Cesium做原型扩展。用CDN验证时我习惯先打开浏览器控制台确认Cesium对象存在再确认扩展库挂载的S3MTilesLayer存在两步都通过再进入下一步编码。如果是正式工程常见做法是npm install cesium安装Cesium扩展库则从官方SDK包下载后放到项目的静态资源目录里按相对路径引入。这里有个最容易翻车的细节Cesium版本和扩展库所依赖的Cesium版本必须严格对应。扩展库基于某个Cesium版本编译直接搭在更高版本上可能出现图层能创建、渲染却黑屏的隐性冲突控制台还不一定有明确报错。所以进入工程化之前先把版本组合写进项目的README。3.2 初始化地球时的参数取舍创建Viewer时很多人习惯把所有控件默认保留结果是页面上铺满了动画控件、时间轴、底图切换器业务还没做界面先乱成一团。我的建议是关闭非必要控件只留sceneModePicker用于二维/三维切换三维智慧城市系统里这个交互频率其实不高也可以关掉。// 更贴近智慧城市交付形态的 Viewer 配置 const viewer new Cesium.Viewer(map, { animation: false, timeline: false, baseLayerPicker: false, geocoder: false, // 关闭搜索框地址搜索能力由业务系统接管 homeButton: false, // 关闭相机归位按钮避免用户跳出业务设定的相机视角 sceneModePicker: false, // 锁死三维模式防止切到哥伦布视图导致图层表现异常 navigationHelpButton: false, infoBox: true, // 保留信息框属性查询弹窗可以复用它 selectionIndicator: true, terrainProvider: Cesium.createWorldTerrain() }); viewer.scene.globe.depthTestAgainstTerrain true; // 开启深度检测否则地形会穿透建筑配置项本身不复杂真正影响后续开发的是depthTestAgainstTerrain。这个参数控制三维对象是否与地形做深度遮挡很多人在初始化时忽略它结果地下管线穿透地表、建筑物悬浮在山上。智慧城市场景里管线、隧道、边坡这些数据对深度关系敏感建议在早期就打开。如果你的S3M数据里包含刻意叠加在地表下方的管线开启深度检测后反而看不见那就要在数据层级上做处理而不是关闭深度检测。3.3 地形、影像与坐标系加载三维服务前先对齐这三件事很多S3M加载不出来或位置偏移根因不在代码而在初始化阶段的地形和影像配置。Cesium默认的全球地形是WGS84椭球基准而SuperMap iServer发布三维场景时通常使用CGCS2000或地方坐标系。你可能会问坐标系不一致会不会导致S3M图层直接偏到海里去实际上S3M节点自带坐标信息服务端会按场景定义好的坐标系输出前端Cesium再做地理投影多数情况下不需要手动转换。真正出问题的是投影坐标系场景没有在发布时配置好动态投影参数导致节点坐标被当成经纬度处理。地形源也要注意。如果项目在内网环境没有外网地形服务就不要用createWorldTerrain改用本地地形服务或者干脆关闭地形用viewer.scene.globe.terrainProvider new Cesium.EllipsoidTerrainProvider()。内网环境强行引用外网地形会导致影像加载慢、地形没显示S3M贴在地球表面时产生高程差。影像底图同理智慧城市系统一般用本地发布的影像服务这里推荐用Cesium的ImageryLayer接收本地WMTS或TMS服务避免踩到域名白名单和跨域限制。初始化阶段的“坐标系对齐”本质上不是让你在前端做投影转换而是要确保场景数据用什么坐标系前端就用什么方式解释它。只要S3M图层的URL来自iServer的REST地址坐标系信息由服务端声明前端不要拿自己的经纬度再去做叠加偏移。如果确实需要把WebGIS业务坐标比如数据库里存的经纬度和三维场景对应起来请通过Cartesian3.fromDegrees这类标准入口生成相机位置和标绘点不要手工修改图层坐标。4. 把SuperMap三维服务真正加载进Cesium从S3M图层到3D Tiles4.1 加载S3M图层的最小代码与参数说明完成Viewer初始化后加载S3M图层的代码比想象中短。核心对象是S3MTilesLayer创建后添加到viewer.scene上即可。// 基于 iClient3D for Cesium 加载 S3M 图层 async function addS3MLayer(viewer, serviceUrl) { const layer new Cesium.S3MTilesLayer({ name: 倾斜摄影, // 图层名用于后续的显隐管理和图层树展示 url: serviceUrl, // iServer 三维服务的图层数据地址 selectEnabled: false // 关闭默认选中效果自定义拾取时减少干扰 }); viewer.scene.addS3MTilesLayer(layer); return layer; } // 调用示例serviceUrl 通常是 iServer 场景中某个数据集对应的 tiles 地址 const layer await addS3MLayer(viewer, http://iserver-address/iserver/services/3D-xxx/rest/realspace/datas/dataset-name/tiles );这里最需要注意的是URL结构。iServer发布的三维服务路径一般包含服务名、场景数据集名和tiles入口形如rest/realspace/datas/xxx/tiles。不同版本的iServer在URL组织上会有差异最稳妥的方式是打开iServer服务管理页面找到对应三维服务下的“数据集列表”从页面里复制真实的请求地址而不是手拼。name参数建议和业务图层对应后续做图例、图层树都会用到。selectEnabled是否关闭取决于你的交互设计默认开启时点击建筑会高亮但这个高亮样式往往和业务系统的配色冲突我通常先关掉等属性查询功能做成后统一控制。4.2 从iServer服务目录动态发现三维服务实际项目里不会只有一个图层。倾斜摄影、白模、路网、地下管线可能有十几个数据集分层发布。手动维护一大堆URL并不明智常见做法是通过iServer的服务目录接口去发现可用服务再按命名规则过滤出三维服务。// 动态发现 iServer 上的三维服务 async function find3DService(serverBase) { // iServer 根目录会返回服务列表 JSON其中每个服务带名称和访问地址 const url ${serverBase}/iserver/services.json; const resp await fetch(url); const json await resp.json(); // 按服务类型过滤三维服务的名称或类型标识中通常包含 3D / realspace const target json.services.find(item { return item.name.startsWith(3D-) || /realspace/.test(item.url); }); if (!target) return null; return target.url; // 返回场景 REST 地址再拼接具体数据集 tiles 地址 }这段逻辑的价值不在代码本身而在对服务目录结构的理解。iServer服务列表是分页返回的数据量大时可能拿不全需要按分页参数遍历服务发布后不会立刻出现在目录里通常要等服务状态变为“运行中”再请求。另外过滤条件不要写死成startsWith(3D-)因为不同项目的服务命名习惯差别很大有些叫city-terrain有些叫realspace_xxx。更稳的判断依据是服务类型字段或URL中的realspace标识。拿到场景REST地址后我一般会再发一次请求获取场景的详细信息拿到该场景下的图层列表然后智能生成每个图层的S3M URL。这一步能省掉大量手写配置也让系统在数据更新后更容易保持同步。注意这类请求建议放在后端做代理避免前端直接暴露iServer地址和端口。4.3 用3D Tiles替代S3M转换流程与加载参数走路线B的场景通常有两个典型特征一是前端不打算引入任何扩展库二是数据总量可控、转换成本可接受。这时需要把数据转为3D Tiles再交给原生Cesium加载。常见做法是在SuperMap桌面端把模型、倾斜摄影、地形缓存等导出为3D Tiles或借助通用三维数据转换工具做处理。操作流程通常是先确认原始数据格式——倾斜摄影的OSGB还是模型数据集然后设置坐标系、LOD层级和纹理压缩参数最后导出成包含tileset.json的目录。// 原生 Cesium 加载 3D Tiles 的常用写法 const tileset await Cesium.Cesium3DTileset.fromUrl( http://static-server/tileset.json, { maximumScreenSpaceError: 16, // 调大更省流量、细节变少卡顿优先调大这个值 skipLevelOfDetail: true, // 允许跳过中间LOD层级减少请求数量 cullWithChildrenBounds: true, // 子节点整体不可见时跳过父节点渲染优化遮挡剔除 preferLeaves: false // 不强制优先加载最精细层按开销顺序调度 } ); viewer.scene.primitives.add(tileset);Cesium3DTileset的加载比S3M图层更直观因为它就是Cesium的原生格式。参数里最常被忽视的是maximumScreenSpaceError。这个概念简单说就是屏幕空间误差阈值数值越大系统越倾向于用低精度的父节点替身高精度子节点画面细节少但加载快数值越小模型越精细但请求数量会暴涨。对于智慧城市这种需要看全貌、又同时在多个图层间切换的系统16到20是常见的起步值当用户聚焦到某个建筑做单体化查询时再动态调小这个值保证细节。转换路线有一个绕不开的注意点属性字段和对象ID的保留程度取决于导出工具的实现。如果业务里必须要点击某栋楼弹出它的权属信息转3D Tiles前务必在测试环境验证属性是否随模型一起导出。很多转换工具默认只保留几何和纹理属性表需要额外配置关联等到全量数据转换后再回头补救代价非常高。5. 智慧城市高频功能落地图层显隐、属性查询与三维飞行5.1 图层显隐与透明度哪些场景真的需要前端控制三维智慧城市系统的图层管理本质上就是一堆S3M图层的显隐开关。图层显隐最简单的写法是操作layer.show这和Cesium原生的Entity、Primitive控制方式一致。需要注意隐藏图层不等于销毁图层下次显示时数据会重新请求如果用户频繁在多个专题之间切换会明显看到加载过程。更平滑的做法是保留图层实例只在显隐状态变化时触发一次viewer.scene.requestRender()。// 图层显隐切换 layer.show false; // 隐藏 // 重新显示前可先确认图层已从服务端拿到数据避免闪空白 layer.show true; // 3D Tiles 图层的整层半透明样式常用于地下管线透视 tileset.style new Cesium.Cesium3DTileStyle({ color: rgba(130, 220, 255, 0.6) });透明度的情况要分两类说。3D Tiles有原生的Cesium3DTileStyle可以直接给整层加半透明S3M图层的半透明则更多依赖服务端场景属性或者数据本身的材质设置。如果业务上必须让S3M建筑群半透明来透视地下管网前端硬做不是不行但要让扩展库配合后处理管线重写渲染状态调试成本高、跨浏览器表现不稳定。我的习惯是能在服务端配置的场景样式不要放到前端代码里写死前端只做显隐和开关半透明需求在数据生产阶段就提给数据加工方。5.2 属性查询点击拾取与REST查询兜底点击查询是智慧城市最基础也最容易让新手迷惑的功能。很多人以为拿到S3M图层就能直接点击取属性实际上能不能取到取决于数据是单体化模型还是倾斜摄影Mesh。单体化模型每个建筑物是独立对象属性容易挂接倾斜摄影Mesh本质是一整块连续三角网没有天然的对象边界点击得到的往往是三角面片而不是“这栋楼叫什么名字”。// 点击拾取三维对象 const handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction((movement) { const picked viewer.scene.pick(movement.position); if (Cesium.defined(picked)) { // 不同数据格式返回的命中对象字段不同先用 console.log 看结构 console.log(picked); // 常见对象属性挂载位置picked.id、picked.primitive 或 attributes 字段 } }, Cesium.ScreenSpaceEventType.LEFT_CLICK);这段代码能跑通但只完成了“拾取到对象”这一步。真正生产环境里我更推荐把点击事件里拿到的位置或对象ID交给iServer的REST查询接口去匹配业务属性。比如点击得到经纬度后请求附近的要素查询服务让服务端返回对应的权属、性质、编码等字段。这样做的好处是属性数据不必强行塞进三维模型文件里业务数据库更新后查询结果随之更新不用同步重建模型。还有一个容易忽略的交互坑点击时如果同时选中了多个叠加图层scene.pick默认只返回最上层对象。要做“穿透查询”或“地下管线查询”需要显式遍历所有图层并判断命中这就涉及scene.drillPick之类的深层拾取能力。实现前先想清楚业务到底是点建筑还是点建筑同时也要感知地下有没有管线穿过。5.3 三维飞行定位让业务视角说人话智慧城市系统的相机操控最终要落到“按业务语义定位”上。比如用户输入某栋楼的门牌号系统要把相机飞到楼前而不是飞到天空俯瞰整个城市。Cesium的camera.flyTo提供了足够精细的控制参数。// 按经纬度、高度和视角方向飞行定位 viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(116.39, 39.90, 800), orientation: { heading: Cesium.Math.toRadians(30), // 相机朝向0为正北 pitch: Cesium.Math.toRadians(-35), // 俯仰角负值表示向下看 roll: 0 }, duration: 2.5, // 飞行时长单位秒 easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT // 先慢后快再慢视觉更自然 });这里最容易让新手翻车的是heading和pitch的弧度换算。如果不包Cesium.Math.toRadians直接写数字相机会飞到完全不可预期的方向。飞行前如果目标是图层上的某个对象更通用的做法是先取到对象的中心点位置再拼进destination。对S3M图层很多版本没有直接暴露boundingSphere给业务代码我会在后端预先存储每个图层的中心经纬度飞行时直接查询避免在前端猜API。返回列表时记得viewer.camera.cancelFlight()否则用户快速切换目标时前一个飞行动画会抢占相机控制权出现“飞到一半突然拐走”的失控感。6. 三维服务加载避坑指南白球、黑模型、坐标偏移与查询失效6.1 白球Cesium版本与扩展库版本不对付现象地球能显示但S3M图层加载后一片空白只有底图连模型轮廓都没有。控制台没有红色报错或者只有一条无关紧要的纹理警告。原因大概率是版本组合错位。用CDN引Cesium时版本较新而扩展库是基于旧版Cesium编译的原型扩展没有被正确挂载导致S3M图层创建成功但请求数据后无法解码渲染。另一个常见组合问题是工程里同时存在npm安装的Cesium和页面里手动引的Cesium两个实例互相覆盖最终生效的根本不是你以为的那个。解决方法是固定版本组合。先用官方示例页面跑通确认示例用的Cesium版本和扩展库版本再对照到自己的工程里。如果必须用npm管理依赖把Cesium版本锁定到扩展库依赖的版本不要轻易升级。这个关系一旦确定建议写进团队内部的依赖约定文档。6.2 黑模型显卡渲染状态与数据解码冲突现象模型能加载但全部是黑块或者部分瓦片是黑色旋转视角后偶尔恢复。我见过最典型的诱因是浏览器WebGL上下文在开启某些抗锯齿选项时与扩展库的纹理处理流程冲突导致部分纹理解码失败显示为黑。另一个诱因是机器显卡驱动过旧GPU解码S3M纹理时崩溃自动回退到软件渲染性能骤降且出现黑色块。先不要怀疑数据坏了。第一步用另一台机器打开同一个页面如果正常基本锁定是渲染环境和驱动问题。第二步在创建Viewer时不要开启强制抗锯齿或者干脆用无头浏览器截图对比。第三步更新显卡驱动并关闭浏览器的硬件加速再试。这一步不看代码但往往能救回一整天。6.3 坐标偏移投影坐标系被当成经纬度解释现象S3M图层加载出来了但位置明显不对比如整个城市模型偏移了几百米或者模型飘在空中与底图影像错位。这种现象多发生在SuperMap iServer场景用的是高斯投影或地方坐标系而发布时没有正确配置动态投影能力或有配置却被前端以默认坐标系方式读取。S3M节点坐标本身是“按场景坐标系输出”服务端没把投影参数传明白前端只能按默认规则解释偏移就产生了。解决思路在服务端而不在前端。回到iServer管理页面检查场景的坐标系设置确保发布的服务能正确表达原始坐标系。不要在前端手动加经纬度偏移补偿那只能让某个点对得上整个模型的变形和旋转补偿不来。如果服务端确实无法修改退而求其次在转换3D Tiles时强制指定坐标系用转换工具把坐标统一到WGS84地理坐标系。6.4 服务请求401或404跨域与访问令牌现象图层加载不出来查看网络请求全是401或404个别请求还出现CORS报错。S3M服务地址在浏览器里直接打开能看到JSON但代码里就是加载失败。原因有两个方向。一是访问令牌iServer三维服务启用了安全认证后普通请求拿不到数据二是跨域配置iServer的端口和前端页面端口不一致CORS没放开。解决方法是先确认服务地址的认证方式把token通过请求头或查询参数统一带上。前端如果直接管理token要处理好token过期后的刷新逻辑否则用户用着用着三维数据突然全部消失。跨域问题则优先用反向代理解决让前端域名下的/iserver代理到真实iServer地址既隐藏端口也顺手解决了CORS。不要寄希望于让甲方给每个浏览器装跨域插件。6.5 帧率直线下降调度参数没有按业务调整现象数据全部加载出来后视角一旋转就卡到无法操作GPU占用拉满浏览器风扇狂转。三维智慧城市项目最常见的数据体量是几十GB如果所有图层一次性加载、LOD调度参数保持默认帧率必然崩溃。默认参数面向通用场景不代表适合你的数据特征。优先调整maximumScreenSpaceError把值从默认调大到16或20系统会明显降低精细层级的加载频率。其次是按业务控制图层同时可见的数量不要把所有专题图层一股脑全显示。地下管线在默认视角下根本不需要渲染只有相机下探到地下时才打开。这层功夫在代码之外取决于你对业务场景的理解但这往往是三维智慧城市系统能不能真正“飞起来”的分水岭。7. 进阶从“能显示”到“能交付”三维场景的验证习惯与性能兜底先做最小验证再铺开工程化这是我带项目时最坚持的流程。拿到iServer服务地址后先花半天时间做一个独立HTML页面把Cesium、扩展库、S3M图层跑通。页面不做业务功能只验证三件事图层能否显示、位置是否对齐、属性能否拾取。验证数据如下表。验证项指标方法与工具图层可加载3秒内出现首帧模型清空缓存后刷新页面记录tileset纹理请求位置对齐模型与影像底图偏差小于1米在影像底图上选明显参照物与模型轮廓对比渲染稳定5分钟连续旋转无黑块、无崩溃Chrome DevTools记录WebGL报错属性可拾取点击单体建筑能返回业务ID控制台打印picked对象并核对属性字段内存占用长时操作后内存无明显泄漏Performance面板记录JS Heap曲线验证通过后再搬进工程。工程化阶段我会把每个S3M图层的服务地址、坐标系、token、版本信息都记录在数据配置表里而不是散落在业务代码中。这样后续数据更新时只改配置不改代码。加载逻辑也建议封装成一个独立的图层管理器业务侧只传图层名和显隐状态不必感知S3M和3D Tiles的区别。性能兜底有一个我踩过不少次跟头的习惯不要试图在业务代码里堆各种参数来掩盖数据问题。如果数据本身切片层级不合理、节点粒度太大无论前端怎么调maximumScreenSpaceError卡顿都只能缓解不能根治。遇到性能瓶颈先去看数据生产参数再看前端调度。很多团队把性能问题全部抛给前端最后折腾一星期不如回头让数据侧重新出一次LOD合理的切片。最后一个技巧是给地图交互留“后悔药”。三维场景里用户的误操作成本很高一次误触可能把相机飞到地心或者把所有图层都关掉。我习惯在系统里保留一个“复位视图”按钮保存系统上线时的默认相机状态用户怎么折腾都能一键回来。这个按钮的代码不过十来行但验收演示时的救命效果非常明显。一次项目演示A同学把相机拉到了地下管线的Z轴深处整个屏幕是黑的他点了一下复位按钮全场就看见系统恢复正常了。从那以后每个三维项目我都默认加这个功能。希望这篇文章里的经验能帮你少踩几个坑也希望你的三维智慧城市项目在Cesium和SuperMap之间顺利打通别再为格式兼容熬到半夜。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑