Cesium 空间分析:把 “坡向” 计算搬到浏览器
前端做 GIS 空间分析不是新鲜事但把坡向计算搬到浏览器里跑、还要能交互式选范围中间藏了多少细节这篇文章把完整实现拆开给你看。开篇CesiumJS 提供了sampleTerrainAPI 可以采样地形高度但没有内置坡向分析这个功能。你得自己把整个计算流水线搭起来从 DEM 采样到梯度计算从色带映射到 Canvas 叠图最后再盖一层方向箭头。每一步都有坑。这篇文章就是我的实测笔记——我会逐段拆解aspect_analysis.html的核心实现环境搭建和底图加载一笔带过重点放在 计算链路 和 可视化策略 上。核心思路从地形到坡向的四步流水线整个工具的逻辑其实不复杂——就四步地形采样 —— 在用户绘制的矩形范围内按网格密度采样地形高度梯度计算 —— 用中心差分法算出每个格网的东西向和南北向坡度坡向转换 —— 把梯度分量转为 0°~360° 的方位角0°北顺时针可视化呈现 —— 用 Canvas 生成色带叠加层 箭头矢量表示方向这四步串起来就是一条流水线每一步的输出是下一步的输入。贴个简化版流程矩形范围→ sampleTerrain → 高度矩阵 → 梯度计算 → 坡度坡向 → Canvas色带叠图 → 箭头渲染看代码的时候你会注意到整条流水线全部塞在analyzeCurrentRectangle()这一个方法里。这么做不是偷懒——是为了保证每一步的数据都是最新的避免参数改了但结果没刷新这种前端常见的状态不同步问题。下面我一步步拆。地形采样sampleTerrain的几个坑坑一采样点数组不能随便构造采样是整个链条的第一步也是最容易翻车的一步。Cesium 的sampleTerrain接受一个Cartographic数组和一个采样层级返回带高度的Cartographic数组。关键点在构造这个数组letpositions[];for(letj0;jrows;j){letlatsouth(latSpan*j)/(rows-1);for(leti0;icols;i){letlonwest(lonSpan*i)/(cols-1);positions.push(newCesium.Cartographic(lon,lat,0));}}letsampledawaitCesium.sampleTerrain(this.viewer.terrainProvider,this.params.terrainLevel,positions,);注意这里terrainLevel是可调的8-15并且这里精度其实没设置。两个采样点的间距直接由矩形范围的经纬度跨度和网格数决定。这点和桌面 GIS 不太一样——桌面软件通常让你指定像元大小而这里是纯数学网格每个网格点就是一个采样点。坑二采样层级是个性能杠杆terrainLevel的值越大采样精度越高但耗时也越长。我默认设了 12——经过实测100×100 的网格在 level 12 时大概 2-3 秒level 15 直接上 6-8 秒。这就是为什么我在面板里加了autoAnalyze开关——关掉它你可以先调好所有参数再点开始分析省得每改一个参数就触发一次 3 秒的重新计算。坑三地形返回的高度可能 undefinedDEM 数据不是全地球都有。采样点落在 DEM 覆盖范围之外时sampleTerrain返回的height就是undefined。代码里必须兜底letheightsnewFloat64Array(cols*rows);letvalidnewUint8Array(cols*rows);for(letk0;ksampled.length;k){letheightsampled[k].height;if(heightundefined||Number.isNaN(height))continue;heights[k]height;valid[k]1;}用valid数组标记有效点后续梯度计算时遇到无效点就直接跳过。这个细节不处理后面梯度计算会给你各种 NaN 污染。梯度和坡向这部分纯数学但很容易算错方向拿到高度矩阵之后就可以计算每个格网的坡度和坡向了。梯度中心差分法代码用的是最简单的中心差分法——每个格网的东西向梯度用左右两个邻点的高度差除以两倍格网间距南北向同理。这是标准做法不稀奇。但这里有两个细节值得说一下leteastMeterPerRadearthRadius*Math.cos(lat);第一经纬度换算成米。东西向 1 度的实际距离随纬度变化——赤道最大极点趋近于零。所以每次迭代都要乘以Math.cos(lat)。你直接用(nextLon - prevLon) * earthRadius算东西向梯度的话高纬度地区会严重失真。第二坡向角的定义。GIS 里坡向是坡面面向的方向坡面法向量在水平面上的投影不是坡面下降的方向。所以代码里传到getAspectAzimuthDeg时梯度分量都取了反号letaspectDegthis.getAspectAzimuthDeg(-dhdEast,-dhdNorth);dhdEast和dhdNorth是高度沿东西、南北方向的变化率。坡面上升最快的方向是(dhdEast, dhdNorth)但坡向要输出的是坡面朝哪个方向所以取反——下降最快的方向和坡面朝向一致。坡向角到色带算出来的 0°~360° 方位角要映射到色带颜色上。代码支持 4 种内置色带色带视觉风格适合场景八方向8 色离散区分度高快速识别 N/NE/E/SE/S/SW/W/NW冷暖方位蓝→白→红渐变南北坡对比明显彩虹方位多色渐变精细方位辨识灰度方位黑白渐变叠加在影像上不抢视觉色带切换是onChange→ 直接触发reanalyzeIfReady()全程实时重算不用等、不用手动点刷新。可视化Canvas 叠图 箭头两个图层各有门道Canvas 叠图给每个格网画一个像素这部分是整个工具最手工的地方。计算完所有格网的坡向后不是用 Cesium 的 Entity 或 Primitive 来渲染——而是直接画到 Canvas 上再把 Canvas 转成SingleTileImageryProvider贴到地球上。letcanvasdocument.createElement(canvas);canvas.widthcols;canvas.heightrows;letcontextcanvas.getContext(2d);letimageDatacontext.createImageData(cols,rows);// ... 逐像素 fillcontext.putImageData(imageData,0,0);letprovidernewCesium.SingleTileImageryProvider({url:canvas.toDataURL(image/png),rectangle,});this.resultLayerthis.viewer.imageryLayers.addImageryProvider(provider);这个方案的好处是性能好——无论多少格网点最终都是一张图渲染可控——每个像素的颜色、透明度完全自己掌控不需 Entity——不用创建成千上万个 Entity 来渲染但它有个限制Canvas 的cols × rows不能太大。我试过 1000×1000浏览器直接卡死。代码里用Math.min(1000, ...)做了上限保护——这个保护不是可有可无是生产环境必须加的。箭头坡向的方向可视化色带用颜色表示方向但人眼对颜色的方向感知其实不直观——东是红的、西是蓝的这需要看色卡才能读懂。所以代码里又加了一层箭头层——在格网范围内按固定间隔绘制箭头箭头从低处指向高处坡向的反方向…不对应该是指向坡面朝向。等一下让我再确认一下箭头的方向getArrow(lon,lat,lonLen,latLen,aspectDeg){letradCesium.Math.toRadians(aspectDeg);letdxMath.sin(rad)*lonLen;letdyMath.cos(rad)*latLen;return{startLon:lon-dx*0.5,startLat:lat-dy*0.5,endLon:londx*0.5,endLat:latdy*0.5,};}aspectDeg是坡向的方位角——坡面面向的方向。箭头从中心向(dx, dy)方向延伸这就是箭头指向的方向。所以箭头指向的就是坡面朝的方向——(地理上北是 0°箭头往北就是朝北坡)。箭头用的是 Cesium 的PolylineArrowMaterialProperty以线条形式 clamp 在地形上方向感非常直截了当。arrowStep控制箭头间距——值越小箭头越密但性能也越差。默认 10 格一跳100×100 的网格大概产生 100 个箭头渲染压力不大。交互矩形绘制也得自己搞Cesium 没有内置的画矩形选择范围功能得自己实现。代码用的是ScreenSpaceEventHandler第一次左键点击 → 记录第一个角点鼠标移动 → 实时预览半透明青色矩形第二次左键点击 → 确定范围触发分析这里有 一个容易忽略的坑矩形绘制用LEFT_CLICK但 Cesium 默认的LEFT_CLICK还会触发选中 Entity。如果你的场景里有很多 Entity比如之前分析留下的箭头点下去可能选中的是箭头而不是角点。代码里先clearAll()再开始绘制解决了这个问题。另外预览矩形的heightReference: CLAMP_TO_GROUND让它贴在地形表面classificationType: TERRAIN确保它跟随高低起伏——而不是悬在空中。写在最后回头看这个工具最有价值的不是坡向分析本身——桌面 GIS 早就有这个功能了——而是它证明了前端可以做空间分析这件事而且能做到可交互、可调参、即时出结果。有几个经验以后做类似项目时能复用把采样计算和 Canvas 渲染拆成独立步骤。采样参数改了 → 重新跑计算 → 重新画 Canvas。每次改渲染参数透明度、色带→ 只重建 Canvas 叠图不重新采样。这样参数切换的响应速度从几秒降到几十毫秒。能用一个图层解决就别用 Entity。SingleTileImageryProvider是 Cesium 里被低估的功能——可以当成一个万能贴图工具用。地形精度和性能是跷跷板。terrainLevelgridCols/gridRows这两个参数决定了计算耗时。100×100 level 12 大概 2-3 秒是一个比较甜的性能点。说说不足——这个工具目前最明显的短板是不支持不规则范围。只能画矩形多边形不行、流域边界更不行。这是下一步要考虑迭代的方向。如果读者有需求我后面补一篇多边形的实现。这篇文章的完整代码可以在aspect_analysis.html里找到配图用的色带效果见正文。有问题或更好的实现方案欢迎留言交流。完整代码见原文https://mp.weixin.qq.com/s/iewp3NNTWps0EhcoX7QwNQ关注公众号 “GIS 开发手记”及时获取首发内容往期精选Cesium 空间分析坡度分析Cesium 通视分析3D 城市模型上划线看可见区Cesium 3D 热力图从 Canvas 热力到 GPU 顶点着色器Cesium 点聚合海量点地图可视化方案自定义虚线箭头材质把两个内置 Material 焊在一起Cesium 中文字体贴地 / 贴墙 / 动态文字方案网络地图坐标系完全指南WGS84 / GCJ02 / BD09 / CGCS2000 与坐标转换实战

相关新闻

RAG、GraphRAG 与 LLM Wiki:有什么区别?分别适合哪些应用场景

RAG、GraphRAG 与 LLM Wiki:有什么区别?分别适合哪些应用场景

RAG 解决“从哪里找到相关内容”,GraphRAG 解决“如何理解知识之间的关系”,LLM Wiki 解决“如何让知识长期沉淀、持续维护并被人和 AI 共同使用”。 关键词: RAG、GraphRAG、LLM Wiki、知识库、知识图谱、AI Agent 在构建企业知识库、智能问…

2026/7/29 11:33:43阅读更多 →
嵌入式开发中MP3模块通信故障排查:波特率匹配原理与实战调试指南

嵌入式开发中MP3模块通信故障排查:波特率匹配原理与实战调试指南

1. 项目概述:当MP3模块“哑火”时,我们到底在调试什么? “求助求助!!!”——在嵌入式开发社区里,看到这样标题的帖子,我几乎能立刻感受到屏幕那头朋友的焦灼。一个简单的MP3播放功能…

2026/7/29 11:33:43阅读更多 →
3分钟实现电影级视频抠像:MatAnyone一致性记忆传播技术深度解析

3分钟实现电影级视频抠像:MatAnyone一致性记忆传播技术深度解析

3分钟实现电影级视频抠像:MatAnyone一致性记忆传播技术深度解析 【免费下载链接】MatAnyone [CVPR 2025] MatAnyone: Stable Video Matting with Consistent Memory Propagation 项目地址: https://gitcode.com/gh_mirrors/ma/MatAnyone 在视频内容创作日益普…

2026/7/29 11:31:42阅读更多 →
打造家庭游戏串流中心:Sunshine完全配置指南

打造家庭游戏串流中心:Sunshine完全配置指南

打造家庭游戏串流中心:Sunshine完全配置指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源的自托管游戏串流服务器,专门为Moonlight客…

2026/7/29 12:33:55阅读更多 →
ncmdumpGUI:3步轻松将网易云音乐ncm文件转换为MP3的完整指南

ncmdumpGUI:3步轻松将网易云音乐ncm文件转换为MP3的完整指南

ncmdumpGUI:3步轻松将网易云音乐ncm文件转换为MP3的完整指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾为网易云音乐下载的歌曲只能在…

2026/7/29 12:33:55阅读更多 →
当保龄球馆的“心脏”被换掉:用1600美元的ESP32替代12万美元的商用系统

当保龄球馆的“心脏”被换掉:用1600美元的ESP32替代12万美元的商用系统

当保龄球馆的“心脏”被换掉:用1600美元的ESP32替代12万美元的商用系统 在Hacker News上,一个名为“我用1600美元的ESP32替代了12万美元的保龄球馆计分系统”的项目获得了超过1400票的热度。这个看似疯狂的举动,背后隐藏着关于技术成本、工业…

2026/7/29 12:33:55阅读更多 →
终极Sunshine游戏串流指南:免费打造你的家庭游戏共享平台

终极Sunshine游戏串流指南:免费打造你的家庭游戏共享平台

终极Sunshine游戏串流指南:免费打造你的家庭游戏共享平台 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾想过在客厅电视上畅玩书房电脑里的3A大作&#xff1f…

2026/7/29 12:33:55阅读更多 →
Arduino串口数据解析实战:从字符串分割到PWM控制应用

Arduino串口数据解析实战:从字符串分割到PWM控制应用

1. 从“逗号难题”到“数据流”:一个Arduino串口解析的实战场景 如果你玩过Arduino,大概率遇到过这个场景:你想通过电脑串口给Arduino发送一组数据,比如“1024,512,256,128”,希望Arduino能把这串字符拆开,…

2026/7/29 12:33:55阅读更多 →
锂电池SOC估算与EKF算法技术详解

锂电池SOC估算与EKF算法技术详解

1. 锂电池SOC估算与扩展卡尔曼滤波技术解析在新能源和储能领域,锂电池的荷电状态(State of Charge, SOC)估算是电池管理系统(BMS)的核心功能之一。准确估算SOC不仅关系到电池的高效使用,更是安全运行的重要…

2026/7/29 12:31:55阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“! 在构建复杂的 Agent 系统时,我们经常会遇到这样的场景:Agent 正在执行一个多步骤的任务,比如“下单购买商品”,但执行到一半时,我们…

2026/7/29 0:01:46阅读更多 →
自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…

2026/7/29 0:01:46阅读更多 →
【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:01:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/29 4:31:51阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →