Rerun MapView 地图视图详解:从 Blueprint 配置到源码级渲染原理
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
MapView 是 Rerun 中用于展示地理空间数据(GPS 轨迹、无人机航迹、机器人位姿等)的 2D 地图视图。本文以 map_view.md 为骨架,结合仓库内类型定义、渲染实现与官方示例,完整讲解 MapView 的属性配置、GeoPoints/GeoLineStrings数据接入方式,以及底层瓦片加载、缩放控制和 GPU 拾取的实现机制,帮助你快速构建可运行的地理可视化方案。
MapView 是什么
MapView 是一个2D 地图视图(View),用于在平面地图底图上展示地理空间图元。它由 Rerun 的类型定义系统(re_types_builder)生成,核心定义位于 map.def.rs:
/// A 2D map view to display geospatial primitives. #[rerun::rerun_type] #[rerun(view_identifier = "Map")] #[rerun(state = "unstable")] pub struct MapView { /// Configures the zoom level of the map view. pub zoom: rerun::blueprint::archetypes::MapZoom, /// Configuration for the background map of the map view. pub background: rerun::blueprint::archetypes::MapBackground, }⚠️稳定性提示:MapView 当前标记为unstable(不稳定)。这意味着其数据格式可能在未来版本发生不向后兼容的重大变化,用于长期存储的录屏数据需要留意这一点。该警告同时体现在官方文档与生成的各语言绑定中(例如 Python 的 map_view.py 类 docstring)。
在 Rerun 视图体系中,MapView 对应的视图类标识符(ViewClassIdentifier)为"Map",其生成结构体定义在 map_view.rs。凡是具备地理坐标组件(LatLon)的实体,都可能被自动建议放进地图视图。
属性详解:zoom 与 background
MapView 只有两个蓝图(Blueprint)属性,均在视图中通过"属性(Properties)"面板或 Blueprint API 进行配置。
zoom:缩放级别
zoom属性对应MapZoomarchetype,其类型定义见 map_zoom.def.rs:
pub struct MapZoom { /// Zoom level for the map. #[rerun(optional)] pub zoom: rerun::blueprint::components::ZoomLevel, }缩放级别遵循OpenStreetMap 的缩放级别定义(z0 最缩小、z22 最放大),取值范围由 zoom_level.def.rs 明确给出:0 为最低(完全缩小),22 为最高(完全放大),数据类型为 64 位浮点数。
从渲染实现看,缩放并不是简单地把相机拉近拉远,而是直接驱动底图瓦片层级的选择。在 map_view.rs 中,视图的缩放逻辑如下:
- 若蓝图中显式设置了
ZoomLevel,则优先使用该值; - 否则根据当前所有地理对象的外包范围(span)自动计算一个能"把所有对象放进屏幕"的缩放级别(
span.zoom_for_screen_size(...)); - 如果连对象范围也没有(还没有数据),则回退到默认值16.0;
- 计算出的缩放级别会交给
walkers地图库的set_zoom应用;若超出当前地图服务商支持的层级,日志会以re_log::debug!级别记录一条"zoom level rejected"提示。
另外,用户手动缩放地图后,新的缩放值会被写回蓝图(map_zoom.save_blueprint_component(...)),从而持久化到 Blueprint 中——这是你调整过一次缩放后再次打开仍能保留视图状态的原因。
background:背景地图
background属性对应MapBackgroundarchetype,其定义见 map_background.def.rs:
pub struct MapBackground { /// Map provider and style to use. #[rerun(optional)] pub provider: rerun::blueprint::components::MapProvider, }provider是一个枚举组件MapProvider,可选值定义于 map_provider.def.rs:
| 枚举值 | 底层数值 | 说明 |
|---|---|---|
OpenStreetMap | 1 | 默认地图源,无需任何 API Key |
MapboxStreets | 2 | Mapbox 极简风格街道图 |
MapboxDark | 3 | Mapbox 深色主题地图 |
MapboxSatellite | 4 | Mapbox 卫星影像(使用高分辨率瓦片) |
MapboxLight | 5 | Mapbox 浅色主题地图 |
选择OpenStreetMap时开箱即用;选择任意 Mapbox 系列源时,必须在RERUN_MAPBOX_ACCESS_TOKEN环境变量中提供有效的 Mapbox API Key,否则瓦片无法加载。
Mapbox Token 的读取逻辑位于 app_options.rs:优先返回 UI 设置里保存的 token,为空时回退读取环境变量RERUN_MAPBOX_ACCESS_TOKEN。你还可以在 Viewer 的设置界面(Settings)中直接填写 token,该输入框位于 settings_screen.rs 的map_view_section_ui函数中——注意它会在提示文案中说明"token 将以明文形式保存在配置文件中"。
每种 provider 在代码中会实例化为不同的walkers瓦片源(见 map_view.rs 的get_tile_manager):OpenStreetMap 使用walkers::sources::OpenStreetMap,Mapbox 系列则按样式映射到walkers::sources::Mapbox,其中Satellite源会开启high_resolution: true。当 provider 切换时,已缓存的瓦片管理器会被重置(state.tiles = None),强制重新按新源加载。
快速上手:用 Blueprint 创建一个地图视图
官方示例 map.py 演示了最完整的用法:先记录两个地理点,再用 Blueprint 创建一个MapView:
"""Use a blueprint to customize a map view.""" import rerun as rr import rerun.blueprint as rrb rr.init("rerun_example_map_view", spawn=True) rr.log( "points", rr.GeoPoints( lat_lon=[[47.6344, 19.1397], [47.6334, 19.1399]], radii=rr.Radius.ui_points(20.0), ), ) # Create a map view to display the chart. blueprint = rrb.Blueprint( rrb.MapView( origin="points", name="MapView", zoom=16.0, background=rrb.MapProvider.OpenStreetMap, ), collapse_panels=True, ) rr.send_blueprint(blueprint)Python 侧MapView构造参数(来自生成的 map_view.py):
origin:视图的原点 EntityPath,其他实体都相对它展示,默认/;contents:视图内容查询表达式,默认"$origin/**"(原点下所有子实体);name/visible:视图显示名与显隐控制;defaults/overrides:为视图内实体注入默认组件或强制指定 Visualizer 的映射表;zoom:接受MapZoomarchetype 或直接传一个浮点数(示例中zoom=16.0即被自动包装为MapZoom);background:接受MapBackground或直接传MapProvider枚举(示例中background=rrb.MapProvider.OpenStreetMap即被自动包装为MapBackground)。
zoom与background最终会分别写入 Blueprint 属性"MapZoom"与"MapBackground",与上文的类型定义一一对应。运行上述脚本后,你会在 Viewer 中看到一张以这两个点为中心的 OSM 地图,点以 20.0 UI 像素半径渲染。
可在地图中展示的数据类型
MapView 目前支持两类地理空间 archetype,在 on_register 中注册了对应的两个 Visualizer:GeoPointsVisualizer与GeoLineStringsVisualizer。
GeoPoints:地理点
GeoPoints用于表示一组地理坐标点,坐标采用EPSG:4326(WGS84)经纬度(北/东为正方向、单位为度)。字段结构见 geo_points.md:
- 必填
positions:LatLon组件; - 推荐
radii:Radius半径、colors:Color颜色; - 可选
class_ids:ClassId,用于配合 Annotation Context 做分类着色。
其视觉器实现位于 geo_points.rs:查询时以LatLon为必需组件(VisualizerQueryInfo::single_required_component::<LatLon>(...)),批处理结果GeoPointBatch中把LatLon转成walkers::Position,再连同半径、颜色、拾取实例 ID 一起交给渲染器绘制。
GeoLineStrings:地理线串
GeoLineStrings表示地理折线(也称 line strips / polylines),坐标同样使用 EPSG:4326 经纬度。字段结构见 geo_line_strings.md:
- 必填
line_strings:GeoLineString组件(每根线串的经纬度顶点序列); - 推荐
radii、colors:线宽与颜色。
两者都属于"稳定"程度较高的数据 archetype,并且除了MapView外也都可以在DataframeView中查看(原文档的"Can be shown in"部分)。
源码级原理:地图是怎么画出来的
瓦片底图与缓存
底图由walkers库驱动。MapViewState持有一个Option<HttpTiles>瓦片管理器与MapMemory(map_view.rs):
- 每次进入绘制时通过
ensure_and_get_mut_refs惰性初始化瓦片管理器; - 原生(非 wasm)平台上,瓦片会缓存到磁盘子目录
map_view(cache_subdirectory("map_view")),walkers::HttpOptions的缓存目录配置见http_options函数; - 状态中还估算瓦片缓存的内存占用(
walkers内部为容量 256 的 LRU 缓存,见heap_size_bytes中的WALKERS_TILE_CACHE_CAPACITY)。
交互操作
View 的交互帮助(Help,见 map_view.rs)定义了三个基本操作:
- 平移(Pan):按住鼠标左键拖动;
- 缩放(Zoom):
Cmd/⌘+ 滚轮(macOS 为 Command,其他平台见Modifiers::COMMAND的处理); - 重置视图(Reset view):双击鼠标左键,会恢复到"跟随所有地理对象"的自动缩放/居中状态(
map_memory.follow_my_position()并重新套用自动缩放级别)。
平移缩放状态由walkers的MapMemory维护:初始(无数据时)视图中心被设置为 Rerun 总部坐标(59.319224, 18.075514)(walkers::lat_lon(...));一旦有了地理对象,中心即跟随对象经纬度范围的中点(span.center())。
绘制管线与 GPU 拾取
地理对象不是画在 egui 画布上的简单图元,而是通过re_renderer的 GPU 管线叠加绘制(map_view.rs):
- 用正射投影(
Orthographic、TopLeftCornerAndExtendZ、far_plane_distance: 100.0)构建ViewBuilder; - 依次调用
GeoLineStringsVisualizer与GeoPointsVisualizer的queue_draw_data,通过walkers::Projector把经纬度投影到屏幕矩形; - 渲染回调以
BlendWithBackground::AlphaToCoverage混合方式叠加到地图底图上,保证底图不被完全覆盖; - 底图的版权归属声明(
tiles.attribution(),如 OSM/Mapbox 版权文本)会以覆盖层(acknowledgement_overlay)形式绘制在地图一角,这是使用第三方地图源时的合规要求。
鼠标悬停拾取采用 GPU 拾取(picking_gpu):读取渲染层的拾取回读结果,在光标周围(半径约 5 个 UI 点、换算后上下限 8–128 像素)寻找最近的已拾取对象,命中后展示实体路径与数据 tooltip;由于 GPU 回读存在数帧延迟,代码用last_gpu_picking_result缓存最近一次结果以消除闪烁。双击地图上的对象会将该实体设为选中状态。
自动生成与导航
spawn_heuristics决定"什么情况下自动创建地图视图"(map_view.rs):只要当前数据中存在任一个被GeoPointsVisualizer或GeoLineStringsVisualizer指示的实体,就会在根层级自动生成一个地图视图(ViewSpawnHeuristics::root())——这就是你直接rr.log地理数据(不开 Blueprint)也能看到地图的原因。地图视图本身支持可见时间范围(supports_visible_time_range返回true),可以配合时间轴回放。
使用建议与注意事项
- 没有 Mapbox Key 就用 OSM:
OpenStreetMap是默认且无需认证的地图源;只有需要 Mapbox 的暗色、卫星或浅色样式时才配置RERUN_MAPBOX_ACCESS_TOKEN(或 Viewer 设置界面填写)。 - 缩放级别的边界:0–22 是通用范围,实际可用的最大层级取决于所选地图服务商提供的瓦片;代码中若传入超出范围的缩放,
walkers会拒绝并打印 debug 日志。 - 自动缩放优先于手写 zoom:未在 Blueprint 中指定
zoom时,视图会按数据外包范围自动缩放并居中;单对象场景回退到 16.0。想要稳定的初始视野,建议显式传入zoom。 - 数据格式:
GeoPoints与GeoLineStrings的经纬度必须符合 EPSG:4326(北/东为正、度为单位),这是 MapView 内部投影与拾取正确性的前提。 - API 稳定性:MapView 属于 unstable 类型,官方警告其数据可能在未来发生不向后兼容的变化,用于存档或跨版本共享的
.rrd文件需谨慎评估。
如需进一步探索,可阅读视图注册与实现 map_view.rs、两个 Visualizer 的实现 geo_points.rs 与 geo_line_strings.rs,以及本仓库中基于 Foxglove / ROS2 数据导入地理定位信息的透镜(Lens)实现,例如 location_fix.rs 与 nav_sat_fix.rs,它们展示了真实机器人定位数据如何被映射为 MapView 可渲染的组件。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考