:VoxelLayer 时间维度动画)
ArcGIS JS 基础教程35VoxelLayer 时间维度动画零、写在前面一、功能介绍二、功能实现2.1 判断体积类型并读取时间信息2.2 用 TimeSlider 驱动时间维度2.3 时间联动原理useViewTime三、功能应用四、核心代码五、在线示例六、关键 API 说明七、系列导航零、写在前面本系列教程完整目录ArcGIS JS 系列基础教程100个项目常用热门功能在线示例完整可运行的 HTML 示例无需任何环境配置可直接在浏览器中打开体验️专栏导航收藏 关注专栏文章第一时间送达❤️一键三连点赞 评论 收藏一、功能介绍VoxelLayer不仅能表达空间三维还可以承载时间维度——这类体数据被称为时间感知体数据典型如随时间变化的地下污染物扩散、大气/海洋时序场等。体积类型VoxelVolume.volumeType决定了时间如何表达volumeType含义能否用 TimeSliderxyz纯地理三维无时间❌xyzt第四维是时间 t图层具备timeInfo是真正的时间感知体✅xyt时间被编码在 z高度维度上❌不能用 TimeSlider 过滤时间对xyzt体只需把TimeSlider与SceneView绑定SDK 会自动按当前时间瞬间渲染对应的体切片——无需手动setTime。重要时间感知体数据在 ArcGIS Online / Enterprise 上通常作为 WebScene 的一部分发布。正确做法是先new WebScene({ portalItem })加载整个场景再用webscene.layers.find(l l.type voxel)取出体数据图层。千万不要直接用new VoxelLayer({ portalItem })去指向那个 WebScene 的 item——因为该 item 的类型是 Web Scene 而非 Voxel Layer会导致图层加载失败。参考VoxelLayer APItimeInfo/timeExtent/useViewTime | 官方示例 VoxelLayer and time二、功能实现2.1 判断体积类型并读取时间信息constWebSceneawait$arcgis.import(arcgis/core/WebScene.js);// 时间感知体数据通常封装在一个 WebScene 中其体素自带正确的空间参考与底图constwebscenenewWebScene({portalItem:{id:220c04143e704fbe8b17cb3d30639f3b}});constviewnewSceneView({container,map:webscene,viewingMode:local});webscene.when((){// 从 WebScene 中取出体数据图层constvoxelLayerwebscene.layers.find(ll.typevoxel);voxelLayer.when((){constvolvoxelLayer.getVolume(null);constvolumeTypevol.volumeType;// xyz | xyzt | xytif(volumeTypexyzt){// 时间感知体timeInfo 提供完整时间范围与所有时间瞬点constfullvoxelLayer.timeInfo.fullTimeExtent;// TimeExtentconststopsvoxelLayer.timeInfo.stops;// Date[] 时间瞬点console.log(full.start,full.end,stops.length);}});});2.2 用 TimeSlider 驱动时间维度把TimeSlider绑定到view并将fullTimeExtent/stops设为timeInfo的值即可constTimeSliderawait$arcgis.import(arcgis/core/widgets/TimeSlider.js);consttimeSlidernewTimeSlider({view,mode:instant,playRate:2000});view.ui.add(timeSlider,bottom-left);// 图层加载后填充滑块的时间范围与刻度timeSlider.fullTimeExtentvoxelLayer.timeInfo.fullTimeExtent;timeSlider.stops{dates:voxelLayer.timeInfo.stops};timeSlider.tickConfigs[{mode:position,values:voxelLayer.timeInfo.stops.map(dd.getTime()),labelsVisible:true,labelFormatFunction:(value)newDate(value).getUTCFullYear().toString()}];2.3 时间联动原理useViewTimeVoxelLayer默认useViewTime true图层会跟随view.timeExtent渲染对应时间切片。而TimeSlider绑定了view、mode:instant在拖动/播放时会改写view.timeExtent于是体数据自动随时间更新——这就是时间动画的全部耦合机制无需额外调用。voxelLayer.useViewTimetrue;// 默认即 true跟随视图时间// 也可手动设置不依赖 TimeSlider// voxelLayer.timeExtent new TimeExtent({ start: someDate, end: someDate });若想让体数据相对真实时间整体偏移可用voxelLayer.timeOffsetTimeInterval。三、功能应用应用场景实现要点污染物随时间扩散xyzt体 TimeSlidermode:instant播放时序海洋/大气场timeInfo.stops作为滑块刻度跟随view.timeExtent任意时间瞬点定格拖动 TimeSlider 或timeSlider.timeExtent时间偏移对齐voxelLayer.timeOffset四、核心代码完整代码已保存至sample/lesson35_voxel_time.html可直接在浏览器打开。!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8metanameviewportcontentwidthdevice-width, initial-scale1.0title第35课VoxelLayer 时间维度动画/titlelinkrelstylesheethrefhttps://js.arcgis.com/5.0/esri/themes/light/main.cssscripttypemodulesrchttps://js.arcgis.com/5.0//scriptstyle*{margin:0;padding:0;box-sizing:border-box;}body{font-family:Microsoft YaHei,sans-serif;}#mapContainer{width:100vw;height:100vh;}.page-title{position:absolute;top:20px;left:50%;transform:translateX(-50%);background:rgba(255,255,255,0.95);padding:10px 24px;border-radius:6px;font-size:18px;font-weight:bold;z-index:100;box-shadow:0 2px 8pxrgba(0,0,0,0.15);}.info-card{position:absolute;top:80px;right:20px;background:rgba(255,255,255,0.95);padding:12px 14px;border-radius:8px;box-shadow:0 2px 12pxrgba(0,0,0,0.15);z-index:100;min-width:240px;font-size:12px;line-height:1.7;border-left:3px solid #1890ff;}.info-card .val{font-weight:bold;color:#1890ff;}.status-text{position:absolute;bottom:90px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.7);color:white;padding:8px 20px;border-radius:20px;font-size:13px;z-index:100;pointer-events:none;white-space:nowrap;}/style/headbodyh1classpage-title第35课VoxelLayer 时间维度动画/h1divclassinfo-carddiv体积类型spanclassvalidvolType加载中.../span/divdiv时间瞬点数spanclassvalidstopCount-/span/divdiv当前时间spanclassvalidcurTime-/span/divdivstylemargin-top:6px;color:#888;拖动底部 TimeSlider 播放时序/div/divdivclassstatus-textidstatusTextVoxelLayer 时间维度 | xyzt 体积 TimeSlider/divdividmapContainer/divscripttypemoduleconstWebSceneawait$arcgis.import(arcgis/core/WebScene.js);constSceneViewawait$arcgis.import(arcgis/core/views/SceneView.js);constTimeSliderawait$arcgis.import(arcgis/core/widgets/TimeSlider.js);// 海牙地下土壤污染物随时间的体数据打包在一个 WebScene 中// 其空间参考为荷兰 RD New 28992自带底图避免与天地图 3857 冲突constwebscenenewWebScene({portalItem:{id:220c04143e704fbe8b17cb3d30639f3b}});constviewnewSceneView({container:mapContainer,map:webscene,viewingMode:local});window.viewview;// TimeSlider 组件绑定到 viewinstant 模式即按时间瞬间过滤consttimeSlidernewTimeSlider({view:view,mode:instant,playRate:2000});view.ui.add(timeSlider,bottom-left);webscene.when((){// 从 WebScene 中找到体数据图层type voxelconstvoxelLayerwebscene.layers.find(ll.typevoxel);if(!voxelLayer){document.getElementById(statusText).textContentWebScene 中未找到体数据图层;return;}voxelLayer.popupEnabledtrue;voxelLayer.when((){constvolvoxelLayer.getVolume(null);constvolumeTypevol.volumeType;document.getElementById(volType).textContentvolumeType;// 仅当体积类型为 xyzt 时才用 TimeSlider 驱动时间维度if(volumeTypexyzt){timeSlider.fullTimeExtentvoxelLayer.timeInfo.fullTimeExtent;timeSlider.stops{dates:voxelLayer.timeInfo.stops};timeSlider.tickConfigs[{mode:position,values:voxelLayer.timeInfo.stops.map(dd.getTime()),labelsVisible:true,labelFormatFunction:(value){constdatenewDate(value);returndate.getUTCFullYear().toString();// 仅显示年份}}];document.getElementById(stopCount).textContentvoxelLayer.timeInfo.stops.length;timeSlider.watch(timeExtent,(){constttimeSlider.timeExtent;if(t){constdnewDate(t.start);document.getElementById(curTime).textContentd.getUTCFullYear()-String(d.getUTCMonth()1).padStart(2,0);}});view.goTo(voxelLayer.fullExtent,{duration:2000});}else{document.getElementById(statusText).textContent该体数据非 xyzt无时间维度;}}).catch(err{document.getElementById(statusText).textContent体数据加载失败;console.error(err);});}).catch(err{document.getElementById(statusText).textContentWebScene 加载失败;console.error(err);});/script/body/html五、在线示例在线体验https://southjor.github.io/arcgis-examples/lessons/lesson35.html操作说明场景加载后信息卡显示volumeType应为xyzt与时间瞬点数量。拖动底部TimeSlider或点击播放按钮观察体数据随时间变化本例为海牙地下土壤污染物扩散。点击体素可弹出该处各变量值已启用popupEnabled。六、关键 API 说明API说明voxelLayer.getVolume(null).volumeType体积类型xyzt才是时间感知体voxelLayer.timeInfo只读TimeInfofullTimeExtent/stopsDate[] 时间瞬点voxelLayer.timeExtent手动设置图层时间范围不依赖 TimeSlider 时voxelLayer.useViewTime默认true跟随view.timeExtent渲染时间切片voxelLayer.timeOffsetTimeInterval整体时间偏移TimeSlider组件fullTimeExtent/stops/mode:instant/tickConfigs/playRate绑定view即可驱动体数据参考链接VoxelLayertimeInfo/timeExtent/useViewTime | 官方示例 VoxelLayer and time七、系列导航⬅️上一篇ArcGIS JS 基础教程34VoxelIsosurface 等值面➡️下一篇ArcGIS JS 基础教程36三维要素聚合 featureReduction小贴士时间维度的前提是volumeType xyzt——若你的体数据是xyt时间藏在 z 里timeInfo为空TimeSlider 无法过滤时间只能靠verticalExaggeration之类的方式拉开不同时间层。动手前先console.log(volumeType)确认类型能省下大量排查时间。