ArcGIS JS 基础教程(7):Global与Local场景模式
- 零、写在前面
- 一、功能介绍
- 二、功能实现
- 三、功能应用
- 四、核心代码
- 五、在线示例
- 六、关键API说明
- 两种模式核心差异对比
- 七、系列导航
零、写在前面
📌本系列教程完整目录:ArcGIS JS 系列基础教程(100个项目常用热门功能)
💡在线示例:完整可运行的 HTML 示例,无需任何环境配置,可直接在浏览器中打开体验
🗂️专栏导航:收藏 + 关注,专栏文章第一时间送达
❤️一键三连:点赞(给教程充电)+ 评论(提问必回)+ 收藏(下次再看)
一、功能介绍
SceneView 支持两种场景模式:Global(全球球面模式)和Local(局部平面模式),通过viewingMode属性控制。
- Global 模式:在 WGS84 球面坐标系下渲染完整的地球球体,适合展示大范围、跨区域的三维数据。地球曲率真实可见,支持全球尺度漫游。
- Local 模式:在投影坐标系下将场景渲染为局部平面区域,适合城市级或园区级的精细化展示。平面投影下量算更精准,无地球曲率干扰。
两种模式对高程数据的处理方式也不同:Global 模式下高程贴合球面曲率;Local 模式下高程在投影平面上拉伸,精度更高。根据项目尺度正确选择模式,是三维场景构建的关键第一步。
二、功能实现
SceneView.viewingMode属性决定场景模式,可选值为"global"(默认)或"local"。
Global 模式关键配置:
- 坐标系:WGS84(EPSG:4326),经纬度直接驱动
map.ground加载全球高程服务world-elevation- 相机参数:
camera.position使用[longitude, latitude, altitude]
Local 模式关键配置:
- 坐标系:需使用投影坐标系(如 Web Mercator EPSG:3857,或地方投影带)
- 通过设置
extent约束场景显示范围,避免平面无限延伸 - 局部模式下相机
position的 x/y 为投影平面坐标,z 仍为高程
动态切换注意:Global 与 Local 模式不能在同一个 SceneView 实例中动态切换,需要销毁原有视图、创建新的 SceneView 实例。实际项目中通常在入口页提供模式选择,或维护两个独立页面。
核心代码如下:
- 创建 Global 模式:
viewingMode: "global"(可省略,默认即为 global) - 创建 Local 模式:
viewingMode: "local",并建议同时设置constraints.clipToExtent限制渲染范围 - Local 模式需确保底图和支持的图层在投影坐标系下可用(Web Mercator 兼容性最好)
三、功能应用
| 场景 | 推荐模式 | 理由 |
|---|---|---|
| 全球物流航线可视化 | Global | 需要展示跨大洲的球面航线,地球曲率不可忽略 |
| 智慧园区精细化管理 | Local | 园区范围小,平面坐标系下量算和建模更精准 |
| 城市数字孪生(区县尺度) | Local | 城市级场景在平面投影下建筑对齐更自然 |
| 气象/海洋全球数据展示 | Global | 全球尺度的气象云图、洋流需要在球面上连续展示 |
| 应急指挥(局部区域) | Local | 局部区域分析无需地球曲率,平面量算更符合业务习惯 |
| 航空航天态势感知 | Global | 卫星轨道、飞行轨迹跨越全球,球面模式是唯一选择 |
选择原则:
- 数据范围大于 100km(如全省、全国、全球)→ 选Global
- 数据范围小于 50km(如园区、城区)→ 选Local
- 介于之间需结合业务:涉及球面几何(大圆航线)选 Global,涉及精密量算选 Local
四、核心代码
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>第7课:Global与Local场景模式</title><linkrel="stylesheet"href="https://js.arcgis.com/5.0/esri/themes/light/main.css"><scripttype="module"src="https://js.arcgis.com/5.0/"></script><style>body{margin:0;padding:0;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);}.control-panel{position:absolute;top:80px;left:20px;background:rgba(255,255,255,0.95);padding:16px;border-radius:8px;box-shadow:0 2px 12pxrgba(0,0,0,0.15);z-index:100;min-width:220px;}.mode-badge{display:inline-block;padding:4px 12px;border-radius:12px;font-size:13px;font-weight:bold;margin-bottom:12px;}.badge-global{background:#1890ff;color:white;}.badge-local{background:#52c41a;color:white;}.btn-group{display:flex;flex-direction:column;gap:8px;}.btn-group button{padding:10px 16px;border:none;border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;}.btn-global{background:#1890ff;color:white;}.btn-local{background:#52c41a;color:white;}.btn-compare{background:#722ed1;color:white;}.btn-group button:hover{opacity:0.85;}.info-box{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);background:rgba(255,255,255,0.95);padding:12px 20px;border-radius:8px;font-size:13px;line-height:1.8;z-index:100;box-shadow:0 2px 12pxrgba(0,0,0,0.15);max-width:600px;}.info-box code{background:#f0f0f0;padding:1px 4px;border-radius:3px;}</style></head><body><h1class="page-title">第7课:Global 与 Local 场景模式</h1><divclass="control-panel"><divid="modeBadge"class="mode-badge badge-global">当前模式:GLOBAL</div><divclass="btn-group"><buttonclass="btn-global"id="btnGlobal">切换为 Global 模式</button><buttonclass="btn-local"id="btnLocal">切换为 Local 模式</button><buttonclass="btn-compare"id="btnCompare">对比:北京 vs 小范围园区</button></div></div><divclass="info-box">🌐<b>Global 模式</b>:球面坐标系(WGS84),适合<code>全省/全国/全球</code>尺度<br>📐<b>Local 模式</b>:平面投影坐标系,适合<code>园区/城区</code>尺度,量算更精准</div><divid="mapContainer"></div><scripttype="module">constMap=await$arcgis.import("@arcgis/core/Map.js");constSceneView=await$arcgis.import("@arcgis/core/views/SceneView.js");constgetTianditu=await$arcgis.import("https://openlayers.vip/examples/resources/tianditu.js");// ========== 天地图图层 ==========constvecLayers=getTianditu.default({type:"vec_w"});// ========== 创建 Map ==========constmap=newMap({basemap:{baseLayers:[vecLayers.base,vecLayers.anno]},ground:{surface:{elevationLayers:[{url:"https://www.geosceneonline.cn/image/rest/services/OpenData/ChinaTerrain3D/ImageServer/"}]}}});// ========== 初始为 Global 模式 ==========letcurrentMode="global";letview=newSceneView({container:"mapContainer",map:map,viewingMode:"global",// 关键属性:global | localcenter:[116.39,39.9],zoom:10,tilt:60,constraints:{altitude:{max:20000000}// 限制最大高度,避免缩太小}});// ========== 更新 UI 徽章 ==========functionupdateBadge(mode){constbadge=document.getElementById("modeBadge");if(mode==="global"){badge.className="mode-badge badge-global";badge.textContent="当前模式:GLOBAL(球面)";}else{badge.className="mode-badge badge-local";badge.textContent="当前模式:LOCAL(平面)";}}// ========== 切换为 Global 模式 ==========functionswitchToGlobal(){if(currentMode==="global")return;currentMode="global";// 销毁旧视图,创建新视图(viewingMode 创建后不可更改)view.destroy();view=newSceneView({container:"mapContainer",map:map,viewingMode:"global",center:[116.39,39.9],zoom:10,tilt:60});updateBadge("global");};// ========== 切换为 Local 模式 ==========functionswitchToLocal(){if(currentMode==="local")return;currentMode="local";view.destroy();view=newSceneView({container:"mapContainer",map:map,viewingMode:"local",// 关键:切换为局部平面模式center:[116.39,39.9],zoom:14,tilt:55,constraints:{clipToExtent:true,// 限制仅渲染 extent 范围内altitude:{max:50000}}});updateBadge("local");};// ========== 对比演示:分别定位到全球视角和局部园区 ==========functioncompareModes(){if(currentMode==="global"){// 当前是 Global → 飞到北京上空(展示球面效果)view.goTo({position:[116.39,39.9,2500000],tilt:0,heading:0});}else{// 当前是 Local → 定位到小规模园区范围view.goTo({position:[116.39,39.9,2000],tilt:55,heading:0});}};document.getElementById("btnGlobal").onclick=switchToGlobal;document.getElementById("btnLocal").onclick=switchToLocal;document.getElementById("btnCompare").onclick=compareModes;updateBadge("global");view.when(()=>{});</script></body></html>五、在线示例
🔗在线体验地址(GitHub资源,等待时间较长,或者架梯子):https://southjor.github.io/arcgis-examples/lessons/lesson7.html
操作说明:
- 点击「切换为 Local 模式」按钮,观察地球从球面变为平面的视觉效果
- 在 Global 模式下大幅缩小,可看到完整地球球体
- 在 Local 模式下放大,建筑与地面贴合更自然,无球面扭曲
六、关键API说明
| API | 说明 |
|---|---|
SceneView.viewingMode | 场景模式:"global"(球面,默认)/"local"(平面) |
SceneView.constraints.clipToExtent | Local 模式下是否仅渲染 extent 范围内(避免平面无限延伸) |
SceneView.constraints.altitude.max | 限制最大视角高度,Global 模式下防止缩太小看不到地球 |
camera.position | Global 模式为[lng, lat, alt];Local 模式 x/y 为投影坐标 |
map.ground | 两种模式下高程数据的处理和显示方式不同,Local 精度更高 |
view.destroy() | 切换模式时需先销毁旧视图实例,再创建新模式视图 |
两种模式核心差异对比
| 对比维度 | Global 模式 | Local 模式 |
|---|---|---|
| 坐标系 | WGS84(球面) | 投影坐标系(平面) |
| 地球曲率 | 有(真实球面) | 无(平面投影) |
| 适用尺度 | 全省/全国/全球 | 园区/城区 |
| 量算精度 | 球面距离(大范围准确) | 平面距离(小范围更精准) |
| 高程处理 | 贴合球面 | 平面拉伸,精度更高 |
| 性能建议 | 注意全球数据加载性能 | 可加载更高精度局部数据 |
七、系列导航
⬅️上一篇:ArcGIS JS 基础教程(6):地图弹窗信息窗口
⬅️下一篇:ArcGIS JS 基础教程(8):环境光照与阴影
💡小贴士:如果你在 Local 模式下使用自定义切片底图,请确保切片服务的坐标系为投影坐标系(如 EPSG:3857),否则会出现图像偏移或无法显示的问题。