用 Rerun 可视化实时空中交通数据:GeoPandas + pyproj + `send_columns` 实战解析

发布时间:2026/9/17 1:38:50

用 Rerun 可视化实时空中交通数据:GeoPandas + pyproj + `send_columns` 实战解析 用 Rerun 可视化实时空中交通数据GeoPandas pyproj send_columns实战解析【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun本教程围绕 Rerun 官方示例 examples/python/air_traffic_data 展开演示如何把 INVOLI 提供的真实空中交通数据航班位置、高度、航速等接入 Rerun viewer在地图视图Map View与 3D 视图中同时呈现航班轨迹用 pyproj 完成坐标系重投影用 GeoPandas 加载真实国界地图数据并对比行式rr.log与列式rr.send_columns两种日志写入策略。读完本文你将掌握一套可复用的地理空间数据 Rerun 多视图的可视化工程方案。示例概览一个多视图的空中交通数据看板示例的核心脚本是 air_traffic_data.py它展示了 Rerun viewer 的多个能力维度使用**地图视图Map View**显示地理空间原始图元GeoPoints等使用pyproj将地理数据从一个坐标系变换到另一个坐标系EPSG:4326 经纬度 → 最适合当前区域的 UTM 投影坐标系使用GeoPandas加载真实行政边界矢量数据EU NUTS 边界并投影到 3D 视图使用Polars对数据分批batch再通过rr.send_columns()一次调用批量下发--batch模式。示例代码内部构建了一个固定布局的 blueprint上方横向并排一个 3D 视图Spatial3DView与一个地图视图MapView下方是一个时间序列视图TimeSeriesView并设置行高比例为row_shares[3, 1]blueprint rrb.Vertical( rrb.Horizontal(rrb.Spatial3DView(origin/), rrb.MapView(origin/)), rrb.TimeSeriesView(origin/aircraft), row_shares[3, 1], ) rr.script_setup(args, rerun_example_air_traffic_data, default_blueprintblueprint)关于地图视图的能力边界可以参考仓库内文档 map_view.md它是一个 2D 地图视图用于展示地理空间图元可配置zoom缩放级别与background底图当前可可视化的 archetype 为GeoLineStrings与GeoPoints其中GeoPoints的位置以 EPSG:4326 经纬度北/东为正的度数表达可选颜色与半径。运行示例环境准备示例要求本机已安装 Rerun SDK 并克隆本仓库Rerun 最新版本 SDK 对应的 Python 版本要求见仓库文档随后按 README 完成安装pip install --upgrade rerun-sdk # 安装最新版 Rerun SDK git clone gitgithub.com:rerun-io/rerun.git # 克隆仓库 cd rerun git checkout latest # 检出与最新 SDK 发布版匹配的提交示例的 Python 依赖声明在 pyproject.toml 中包括geopandas、numpy、polars、pyproj、requests、rerun-sdk、shapely、tqdm。以可编辑模式安装pip install -e examples/python/air_traffic_data启动与参数直接运行主脚本即可看到效果python -m air_traffic_data如需定制行为或保存数据用--help查看全部命令行参数python -m air_traffic_data --help从源码看示例实际支持的 CLI 参数包括参数默认值说明--dataset2h选择自动下载的数据集可选10min或2h见下方数据集一节--rawFalsestore_true若开启直接记录含缺失值等问题的原始数据用于在 viewer 中压测边界情况--batchTrue若开启使用批处理 logger基于rr.send_columns要求 Rerun 0.18--batch-size8192批处理 logger 的批次大小--dir无使用本地目录中的 JSON 数据而不是下载数据集此外rr.script_add_args(args)还会注入 Rerun 脚本的标准参数如连接/服务/保存等使得该示例可以直接以rerun支持的各种运行方式连接 viewer、起 server、保存.rrd文件启动。数据集与数据模型INVOLI 数据集数据由 INVOLI 提供脚本内置了两个可直接下载的数据集air_traffic_data.pyINVOLI_DATASETS { 10min: https://storage.googleapis.com/rerun-example-datasets/involi/involi_demo_set_1_10min.zip, 2h: https://storage.googleapis.com/rerun-example-datasets/involi/involi_demo_set_2_2h.zip, }下载带 tqdm 进度条、按 chunk 流式写入内存io.BytesIO并校验content-length是否一致随后解压到仓库内examples/python/air_traffic_data/dataset/目录首次运行时自动创建。如果你已经有同类 JSON 数据也可以用--dir指向本地目录脚本会递归收集该目录下所有*.json文件get_paths_for_directory。Measurement 数据模型每一条航班记录被建模为Measurementdataclassair_traffic_data.py字段与原始 JSON 的对应关系如下字段类型来源icao_idstrdata[ids][icao]ICAO 24 位地址码同时用作实体路径latitude/longitudefloat \| Nonedata.get(latitude)等允许缺失barometric_altitudefloat \| None气压高度用于 3D 点位与时间序列wg84_altitudefloat \| NoneWGS84 高度coursefloat \| None航向ground_speedfloat \| None地速vertical_speedfloat \| None垂直速度ground_statusstr \| None地面状态如起降阶段标记timestampfloatdata[timestamp][0] data[timestamp][1] / 1e9即秒 纳秒组合时间戳换算成浮点秒注意原始数据中大量字段允许为空None这一特点直接决定了后面批处理 logger 需要按字段分别drop_nulls再下发的设计。坐标系变换从经纬度到最优 UTM 投影这是本示例最有价值的技术点之一把地理坐标经度、纬度投影为适合展示的平面坐标同时保留一份经纬度原始坐标用于地图视图。自动挑选最优 UTM 分带find_best_utm_crsair_traffic_data.py根据所有测量点的经纬度跨度计算AreaOfInterest再通过pyproj.database.query_utm_crs_info(datum_nameWGS 84, area_of_interest...)查询覆盖该区域的最佳 UTM 带最终CRS.from_epsg(...)返回对应 CRSarea_of_interest get_area_of_interest(measurements) utm_crs_list query_utm_crs_info(datum_nameWGS 84, area_of_interestarea_of_interest) return CRS.from_epsg(utm_crs_list[0].code)因为航班数据集中在欧洲德国、瑞士上空自动选出的 UTM 带天然覆盖该区域无需硬编码投影参数。Transformer 的使用随后构造一个永远 x经度、y纬度顺序的变换器always_xyTrue避免经纬度顺序歧义proj Transformer.from_crs(EPSG:4326, utm_crs, always_xyTrue)在行式 logger 中每个测量点这样投影为 3D 坐标rr.log( entity_path, rr.Points3D( [self._proj.transform(measurement.longitude, measurement.latitude, measurement.barometric_altitude)], colorscolor, ), rr.GeoPoints(lat_lon[measurement.latitude, measurement.longitude]), )一次rr.log同时写入两类图元Points3DUTM 平面坐标 高度进入 3D 视图GeoPoints保留经纬度进入地图视图。航线所在实体的颜色由实体路径字符串确定性生成rr.components.Color.from_string(entity_path)同一架飞机在多个视图中颜色一致。高度夸张与 Transform3D由于航班高度约万米级相对横向距离尺度极小脚本对整棵aircraft实体树施加了一个静态的 z 轴 10 倍缩放rr.log(aircraft, rr.Transform3D(scale[1, 1, 10]), staticTrue)这是 Rerun 典型的静态数据 运行时变换组合用法staticTrue表示该变换不会随时间变化一次性写入即可作用于其下所有子实体。用 GeoPandas 加载真实地图边界为了在 3D/2D 视图中显示国界、区域边界脚本会从欧盟 GISCO 服务下载 NUTS 2021 边界数据1:1000 万比例尺EPSG:4326解压到examples/python/air_traffic_data/dataset/map_data/然后用 GeoPandas 读取并重投影到之前选定的 UTM CRSmap_data ( gpd.read_file(MAP_DATA_DIR / fNUTS_RG_01M_2021_4326_LEVL_{level}.json) .set_crs(epsg:4326) .to_crs(crs) )对每个属于目标国家示例硬编码为德国DE、瑞士CHlevel 0的多边形用shapely_geom_to_numpy把Polygon/MultiPolygon含内环interiors转成 numpy 坐标数组同一实体路径下同时记录 2D 与 3D 两组LineStrips2D 直接用平面坐标3D 用np.hstack([line, np.zeros((len(line), 1))])补齐 z0以rr.AnyValues(**metadata)把该边界多边形的属性如 NUTS_ID 等剔除 geometry 字段静态挂到实体上。rr.log(entity_path /2D, rr.LineStrips2D(lines, colorscolor), staticTrue) rr.log( entity_path /3D, rr.LineStrips3D([np.hstack([line, np.zeros((len(line), 1))]) for line in lines], colorscolor), staticTrue, )边界、地面状态等不随时间变化的数据都使用staticTrue这正符合 Rerun 数据模型中静态数据不占时间索引的设计详见 static.md。两种日志写入策略行式rr.log与列式rr.send_columns示例最有教学价值之处在于同一份数据分别实现了两种 loggerair_traffic_data.py源码中用LoggerProtocol 统一接口process_measurementflushlog_everything根据--batch选择具体实现。策略一MeasurementLogger逐行rr.log面向数据在运行中逐步产生的场景逐条处理每条测量记录rr.set_time(unix_time, timestampmeasurement.timestamp) # ... 投影后的 Points3D GeoPoints ... rr.log(entity_path, rr.AnyValues(**metadata)) # 其他属性 rr.log(entity_path /barometric_altitude, rr.Scalars(...), rr.SeriesLines(colorscolor)) # 高度时间序列要点时间通过rr.set_time(unix_time, ...)设置实体路径按aircraft/{icao_id}组织icao_id天然成为实体标识_ignored_fields中排除icao_id与timestamp避免重复记录在非--raw模式下dict_factory会过滤掉值为None的字段让记录更干净高度被单独记录为ScalarsSeriesLines供下方的TimeSeriesView展示。策略二MeasurementBatchLogger批量rr.send_columns当数据已经是列式存储例如从文件、数据库批量读出时逐行log会带来大量小调用。send_columns允许一次调用更新实体在多个时间点的状态是更高效的方案。相关概念可参考仓库文档 send-columns.md与面向行的logAPI 不同send_columns会绕过时间上下文与微批处理micro-batching且不会自动添加log_time/log_tick等内置时间线只包含调用中显式传入的时间列。批处理 logger 的核心流程air_traffic_data.pydf polars.DataFrame(self._measurements).sort(timestamp) # 原始数据未按时间排序先排序 for (icao_id,), group in df.group_by(icao_id): self.log_position_and_altitude(group, icao_id) self.log_ground_status(group, icao_id) self.log_metadata(group, icao_id)由于原始数据各字段缺失模式不同位置/高度、地面状态、航向等元数据被拆成三次独立的send_columns调用各自drop_nulls后再下发。位置与高度部分air_traffic_data.py最为典型timestamps rr.TimeColumn(unix_time, timestampdf[timestamp].to_numpy()) pos self._proj.transform(df[longitude], df[latitude], df[barometric_altitude]) rr.send_columns( entity_path, [timestamps], [ *rr.Points3D.columns(positionsnp.vstack(pos).T), *rr.GeoPoints.columns(positionsnp.vstack((df[latitude], df[longitude])).T), *rr.AnyValues.columns(latitude..., longitude..., barometric_altitude...), ], ) rr.send_columns( entity_path /barometric_altitude, [timestamps], rr.Scalars.columns(scalarsdf[barometric_altitude].to_numpy()), )几个值得注意的实现细节先注册静态指示器indicator每个飞机实体第一次出现时用rr.Points3D.from_fields(colorscolor)、rr.SeriesLines.from_fields(colorscolor)配合staticTrue写入一次用于声明颜色等静态属性此后send_columns不再重复传颜色。源码中对此有注释说明_position_indicators集合去重且留有一处已知限制的 TODOGeoPoints.from_fields(colors...)在 untagged index 下暂时是未定义行为因此批处理模式下地图视图的点位颜色由 3D 指示器间接决定。批大小默认 8192process_measurement累积满self._batch_size即触发flush最终在log_everything末尾还会再flush()一次确保残留数据被写入。时间列与组件列分离rr.TimeColumn(unix_time, ...)作为索引列*.columns(...)返回组件列send_columns把若干索引列 若干组件列一次性提交等价于多条时间戳的批量log。对应概念详见 chunks.md 与 chunk-processing-api.md。排序的收益get_paths_for_directory用自然排序human sortre.split(r(\d))按数字段排序整理 JSON 文件路径。虽然 Rerun 本身接受乱序数据但乱序会带来较小的性能开销日志侧先做廉价排序总是更优——源码注释明确说明了这一取舍。实体层级与数据组织从代码可以归纳出完整的实体树设计供读者参考其组织方式aircraft/ # Transform3D(scale[1,1,10]) 静态变换 ├── {icao_id}/ # Points3D GeoPoints AnyValues(航向/地速/垂直速度/地面状态) │ └── barometric_altitude/ # Scalars SeriesLines高度时间序列 region_boundaries/ ├── DE/{level}/{NUTS_ID}/ # LineStrips2D LineStrips3D AnyValues(属性) └── CH/{level}/{NUTS_ID}/时间线统一使用unix_time浮点秒由rr.set_time行式或rr.TimeColumn列式写入静态数据边界、变换、指示器用staticTrue动态数据每架飞机的轨迹、高度序列按时间推进。延伸把方案迁移到自己的地理数据综合上述实现若你要在自己的项目里复刻这套可视化管线核心步骤可归纳为确定 CRS用query_utm_crs_infoAreaOfInterest自动挑选覆盖数据范围的最优 UTM 带或按需固定使用某个投影构造 TransformerTransformer.from_crs(EPSG:4326, target_crs, always_xyTrue)同时保留原始经纬度数据分层位置/轨迹写入Points3D投影坐标与GeoPoints经纬度双份静态背景边界、底图要素以LineStrips*staticTrue写入时序属性高度、速度单独写成Scalars供时间序列视图消费选写入策略实时流式数据用行式rr.log批量/列式数据Polars/DataFrame/文件用rr.send_columnsrr.TimeColumn并按字段缺失模式分组下发组织布局用rrb.Vertical/rrb.Horizontal/rrb.Spatial3DView/rrb.MapView/rrb.TimeSeriesView构建多视图 dashboard把 3D、地图、时序三个视角并置。本示例的完整代码air_traffic_data.py、依赖声明pyproject.toml与官方说明README.md都位于本仓库内可随时对照阅读地图视图与列式 API 的完整参考分别见 map_view.md 与 send-columns.md。【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 1:38:50

Linux防火墙firewalld只允许特定IP访问配置与排查实战

1. 需求先拆清楚:什么场景下才叫"只允许特定IP访问"去年帮一个朋友收拾一台被暴力破解的测试机,登进去一看/var/log/secure里刷了几万条失败登录记录,来源IP换着花样来。他当时的诉求很朴素:这台机器只给自己公司的两台…

2026/9/17 1:38:50

OpenEuler22.04部署Docker:系统级适配与华为云镜像源实战

1. 这不是普通安装:OpenEuler22.04上Docker部署的本质是“系统级适配”你搜“docker安装教程”,满屏都是Ubuntu、CentOS的步骤,复制粘贴到OpenEuler22.04上——十有八九卡在apt update报错、yum install docker-ce提示包不存在、或者装完启动…

2026/9/17 1:33:50

C语言实现SBC音频编解码算法:从原理到嵌入式优化

简介:SBC(Subband Coding,子带编码)是蓝牙音频传输中广泛使用的低复杂度音频编解码算法。这份C语言实现资源面向嵌入式开发者和音频算法学习者,帮助理解子带划分、滤波、量化、熵编码等核心环节在资源受限环境下的落地…

2026/9/17 3:28:58

Vue 3 核心 API 解析:defineComponent 与 defineAsyncComponent 实战指南

前两天帮同事排查一个奇怪的问题:他写了一个 Vue 3 组件,函数命名也对、组件也正常注册了,但在 IDE 里 props 和 emits 完全没有任何类型提示。他第一反应是“是不是 Volar 插件坏了”?我让他把代码发过来一看——他确实用了 defi…

2026/9/17 3:28:58

交换机端口模式详解:Access、Trunk、Hybrid与VLAN标签转发

我第一次在交换机上敲下port link-type trunk的时候,心里其实没底:为什么一个物理口非得规定成某种模式?后来复习计算机网络,再看到“端口模式”四个字,又差点把它和 TCP 端口号搞混。这个概念卡了我很久,直…

2026/9/17 3:28:58

Windows文件复制进阶:从copy到robocopy,掌握健壮的文件同步与备份命令

直接在Windows命令提示符里敲copy去复制文件,很多人第一反应就是“这不就够用了吗”。但等你真正面对几万个文件、跨磁盘拷贝、增量备份、日志记录这些需求的时候,copy命令那点能力立马就显得捉襟见肘。所以Windows其实内置了一个很多人没用过的“搬家神…

2026/9/17 3:23:58

仿美团外卖菜单实战:数据模型与RecyclerView联动全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码