rerun icon indicating copy to clipboard operation
rerun copied to clipboard

Map Space View and GPS Coordinates archetype (Mapbox/OSM support)

Open tfoldi opened this issue 1 year ago • 14 comments

What

Map Space View for GNSS/GPS data logged through new GPS Coordinates archetype.

https://github.com/rerun-io/rerun/assets/82426/86b13ba3-97af-47d2-9422-7052d7064265

  • Added a new re_space_view_map crate for visualizing Points3D with gps coordinates.
    • map_visualizer_system.rs implements the VisualizerSystem trait. It has only one meaningful function, that takes the Positions3D components and turns into vec<MapEntry> array along with optional Color and Radius components. This vec<MapEntry> is the only field of the MapVisualizerSystem.
    • map_space_view.rs is where the magic happens. It uses walkers slippy map implementation to show an OpenStreetMap or Mapbox map. On the selection_ui you can change the map providers. To view Mapbox maps, you need to set mapbox tokens (you can get free tokens from Mapbox's site) and pass it via the env variable (MAPBOX_ACCESS_TOKEN) or via the blueprint
    • map_windows.rs is a small helper to show the zoom controls and acknowledgment on the UIs.
  • For blueprints I made MapProvider component (enum with providers+styles), and a MapOptions archetype.

The logging of data is performed as follows:

//! Log some GPS coordinates

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let rec = rerun::RecordingStreamBuilder::new("rerun_example_gps_coordinates").spawn()?;

    rec.log(
        "points",
        &rerun::Points3D::new([(47.6344, 19.1397, 0.0), (47.6344, 19.1399, 1.0)]),
    )?;

    Ok(())
}

The blueprint is defined as follows:

"""Use a blueprint to show a map."""

import rerun as rr
import rerun.blueprint as rrb

rr.init("rerun_example_gps_coordinates", spawn=True)

rr.log("points", Points3D([[47.6344, 19.1397, 0], [47.6334, 19.1399, 1]]))

# Create a map view to display the chart.
blueprint = rrb.Blueprint(
    rrb.MapView(
        origin="points",
        name="MapView",
        map_options=rrb.archetypes.MapOptions(provider=rrb.components.MapProvider.MapboxStreets),
    ),
    collapse_panels=True,
)

rr.send_blueprint(blueprint)

The PR is not perfect, but the view is usable.

Please review the changes and evaluate their potential utility for your needs. If you don't like, prefer not to merge just close it - no hard feelings.

To be discussed

  • Check with you guys to see if the name is right at all. Maybe instead of GPS we can go with something better
  • Position3D is limited to f32 instead of f64. This makes it less precise than /NavSatFix

Checklist

  • [x] I have read and agree to Contributor Guide and the Code of Conduct
  • [x] I've included a screenshot or gif (if applicable)
  • [x] I have tested the web demo (if applicable):
    • Using my own lame demo app which is not part of the PR.
  • [ ] The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG

To run all checks from main, comment on the PR with @rerun-bot full-check.

tfoldi avatar Jun 13 '24 12:06 tfoldi

Awesome work! Sorry if it's a noob question, but how do I check this out?

ubuntu@localhost:~/workspace/rerun-tfoldi$ pixi run rerun-web-release
 Pixi task (rerun-build-web-release in default): rustup target add wasm32-unknown-unknown && cargo run -p re_dev_tools -- build-web-viewer --release -g
info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date
    Finished dev [optimized + debuginfo] target(s) in 0.10s
     Running `target/debug/re_dev_tools build-web-viewer --release -g`
Building web viewer…

Compiling Rust to wasm in /home/ubuntu/workspace/rerun-tfoldi/target_wasm…
/home/ubuntu/workspace/rerun-tfoldi> CARGO_ENCODED_RUSTFLAGS="--cfg=web_sys_unstable_apis" RUSTFLAGS="--cfg=web_sys_unstable_apis" "cargo" "build" "--quiet" "--package" "re_viewer" "--lib" "--target" "wasm32-unknown-unknown" "--target-dir" "/home/ubuntu/workspace/rerun-tfoldi/target_wasm" "--no-default-features" "--features=analytics" "--release"
error: package `bitstream-io v2.4.2` cannot be built because it requires rustc 1.79 or newer, while the currently active rustc version is 1.76.0
Either upgrade to rustc 1.79 or newer, or use
cargo update [email protected] --precise ver
where `ver` is the latest version of `bitstream-io` supporting rustc 1.76.0
Error: Failed to build Wasm

k-bx avatar Jun 18 '24 07:06 k-bx

Either upgrade to rustc 1.79 or newer, or use cargo update [email protected] --precise ver where ver is the latest version of bitstream-io supporting rustc 1.76.0 Error: Failed to build Wasm

New rerun needs rust version 1.79 while you have only 1.76. Update your rust toolchain and try it again.

tfoldi avatar Jun 18 '24 07:06 tfoldi

Ah, needed to update the rust-toolchain file. All good, compiled fine!

k-bx avatar Jun 18 '24 08:06 k-bx

Few changes we discussed:

  • Remove GpsCoordinate archetype
  • Add ViewCoordinates.LAT_LON_ALT enum value to indicate that a Position3D represents lat/lon/alt values
  • Use ViewCoordinates in view heuristics to select the right heuristics for view
  • due to walkers' reqwest dependency it should be an optional feature

tfoldi avatar Jun 19 '24 07:06 tfoldi

* Add `ViewCoordinates.LAT_LON_ALT` enum value to indicate that a `Position3D` represents lat/lon/alt values 
* Use `ViewCoordinates` in view heuristics to select the right heuristics for view

I talked this one over with some folks and the desire is to keep ViewCoordinates separate and somewhat dedicated to interpretation of camera-orientation, as distinct from data semantics.

I'm going to put together a proposal for a new archetype, probably named something like CRS (CoordinateReferenceSystem). We can start with this somewhat dedicated to the mapping use-cases, but I think it could be helpful for other things like CAD import where it might be useful to carry context like unit-sizes.

jleibs avatar Jun 19 '24 16:06 jleibs

Here's my proposal for adding a very simple CRS type as an indicator: https://github.com/rerun-io/rerun/issues/6601

jleibs avatar Jun 19 '24 17:06 jleibs

The new image crate depends on a newer version of Rust by default unless you disable it by setting default-features = false. Since walkers enables default features, this is causing the Rust build to fail on CI. I will look into how this can be addressed in the original repository.

The current cargo tree:

    ├── re_data_source v0.17.0-alpha.4 (/Users/.../rerun/crates/re_data_source)
    │   ├── re_data_loader v0.17.0-alpha.4 (/Users/.../rerun/crates/re_data_loader)
    │   │   ├── image v0.25.1
    │   │   │   ├── ravif v0.11.5
    │   │   │   │   ├── rav1e v0.7.1
    │   │   │   │   │   ├── bitstream-io v2.4.2  <--- this requires 1.79

In image's Cargo.toml:

ravif = { version = "0.11.2", default-features = false, optional = true }

tfoldi avatar Jun 21 '24 07:06 tfoldi

  • Removed GpsCoordinates in favor of pure Points3D.
  • Removed default features from image in walkers repo so now the code works with older rustc.
  • Formatted/linted/removed all gps position related stuff
  • Added ZoomLevel and Secret components for the map options archetype
    • Secret component displayed as password field in selection_ui

What is left from what we discussed:

  1. add feature flags to make the map view optional

For 1, I'm open to your suggestions. Should the feature be enabled or disabled by default? Either way, how should the CI/CD integration work? Should we test all features by default or test combinations of features?

tfoldi avatar Jun 22 '24 18:06 tfoldi

@tfoldi nice work! Excited to see it merged :)

patrickelectric avatar Jun 29 '24 00:06 patrickelectric

Extended the nuScenes example with MapView to have at least one example using the new view:

https://github.com/rerun-io/rerun/assets/82426/8b329788-a928-4f5a-b228-514642104203

tfoldi avatar Jun 30 '24 08:06 tfoldi

would this support plotting a scatter of points across the map (instead of a single point/track) ? from the PR seems yes a la rr.log("points", Points3D([[47.6344, 19.1397, 0], [47.6334, 19.1399, 1]])) however the visual confused me (centers on a single point)

journaux avatar Aug 12 '24 00:08 journaux

would this support plotting a scatter of points across the map (instead of a single point/track) ? from the PR seems yes a la rr.log("points", Points3D([[47.6344, 19.1397, 0], [47.6334, 19.1399, 1]])) however the visual confused me (centers on a single point)

yes, it does support multiple points

tfoldi avatar Aug 12 '24 06:08 tfoldi

good to know ! curious if team/egui has evaluated integrating cesium

-> its rendering pipeline for large set of N points may be faster -> it has 3d terrain capability

journaux avatar Aug 15 '24 19:08 journaux

Hey, still very keen to see this. What's the current blocker?

k-bx avatar Oct 03 '24 18:10 k-bx

The same from my side, will it be continued? Is there any plan to make GPS coordinates using float64? With 32 bits it's very 'rough'

samorr avatar Oct 14 '24 11:10 samorr

The same from my side, will it be continued?

I’m open to continuing this, but it's largely dependent on the Rerun team's priorities. As you may have seen from the PR history, I tried to keep it up-to-date for a few versions but eventually paused due to the complexity involved. There are many moving parts in Rerun, and with so much auto-generated code and changing internals, maintaining consistency across view-related PRs isn’t straightforward.

I received two key comments from @jleibs:

  1. #6601: Suggestion to introduce a new CoordinateReferenceSystem type as type indicator. Personally, I’m not sure this is necessary on day one. We could potentially move forward by logging Position3D types and setting the view to Map in the blueprint.
  2. The walker egui component brings in the reqwest crate, so making it an optional feature might be a cleaner approach.

On June 22nd, I asked a few questions regarding these points, but since I didn’t receive any responses, so I paused further updates. That said, I’m happy to rebase the PR to the latest main branch if there’s a realistic chance it could be merged.

tfoldi avatar Oct 17 '24 09:10 tfoldi

@tfoldi First, thanks again for your contribution, and for putting up with our slow responses so far. With 0.19 out and the huge push on the dataframe and video fronts, we are now ready to focus on other areas—and this one is high up our list. Starting on Monday, I'll make it my priority to help you land this PR.

Would you be willing to rebase it to latest main? My plan would then be to dive in, give it a thorough review, and help (including hands-on) to land it sooner than later.

~As for the "feature flag": yes we want one, that is disabled by default (at least initially). This will give us more confidence to land stuff before they are 100% polished. To be clear, by "feature flag", we don't necessarily mean a Cargo-style feature, but a global application setting which dynamically enable/disable the map view in the viewer. That's often how we signify to users that a particular view is "in beta". (For illustration, I recently removed the feature flag we had on the dataframe view in this PR).~

Edit: users already have to explicitly opt-in by logging a new, specific GeoPoints archetype. So we do need another "experimental" option to check.

abey79 avatar Oct 18 '24 14:10 abey79

I just discussed the data model aspect of this PR with @jleibs and we reached the following decision.

We introduce a new GeoPoints archetype as per this outline:

table GeoPoints  {
  /// All the 3D positions at which the point cloud shows points.
  latlon: [rerun.components.LatLon];  // datatype: DVec2D

  // --- Recommended ---

  /// Optional radii for the points, effectively turning them into circles.
  radii: [rerun.components.Radius];

  /// Optional colors for the points.
  colors: [rerun.components.Color];

  // --- Optional ---

  /// Optional text labels for the points.
  labels: [rerun.components.Text];

  /// Optional choice of whether the text labels should be shown by default.
  show_labels: rerun.components.ShowLabels;
}

This PR will have to introduce the DVec2D datatype, identical to the Vec2D but with double precision floats.

For the scope of this PR, the recommended/optional components should be included only so long as they are actually supported by the view. If they are not, then it's fine to drop them—we can add them in a subsequent PR.

In the future, we will further add a Altitude recommended component to carry the height information. How we define the kind of altitude we support (ground height, ellipsoid, amsl, whatnot) is yet to be defined. We currently lean towards having that setting as a view property, but that's for another day to decide.

Motivation for this decision:

  • Using Points2D is problematic precision-wise. f32 means ~1.7m real world accuracy. GeoPoints has f64.
  • Splitting the latlon part from the (future) Altitude component clarifies that these numbers dont have the same units (angles for latlon, likely meters for Altitude).
  • More generally, we will try to adhere to the standard GIS data model going forward (in particular the GeoArrow model). The proposed GeoPoints archetype fits the MultiPoint case (by virtue of our components always being batch), and it's likely that MultiLineString and MultiPolygon will eventually follow.
  • Having a distinct archetype from Points2D also has the advantage to disambiguate things for the heuristics.

abey79 avatar Oct 21 '24 19:10 abey79

For the scope of this PR, the recommended/optional components should be included only so long as they are actually supported by the view. If they are not, then it's fine to drop them—we can add them in a subsequent PR.

we can support text labels. However, shouldn't you be able to change their fonts, sizes, and colors?

tfoldi avatar Oct 22 '24 06:10 tfoldi

For the scope of this PR, the recommended/optional components should be included only so long as they are actually supported by the view. If they are not, then it's fine to drop them—we can add them in a subsequent PR.

we can support text labels. However, shouldn't you be able to change their fonts, sizes, and colors?

No, I don't think this is required for this PR (and the short term future tbh). IWe don't support styling of labels in other views either.

abey79 avatar Oct 22 '24 11:10 abey79

Let's make sure we reference https://epsg.io/4326 in the GeoPoint archetype and LatLon component.

abey79 avatar Oct 22 '24 12:10 abey79

Hi, maybe this is a little bit premature, but I would very much like to use these functionalities soon. Do you have any estimates on when there's going to be an official release with these changes?

samorr avatar Oct 25 '24 16:10 samorr

Hi, maybe this is a little bit premature, but I would very much like to use these functionalities soon. Do you have any estimates on when there's going to be an official release with these changes?

We intend for that to happen relatively soon (couple of weeks ish), but no promises! There should however be at least a development build available sometime next week.

abey79 avatar Oct 25 '24 16:10 abey79

@samorr the latest development build should have this already now! :) https://github.com/rerun-io/rerun/releases/tag/prerelease

Wumpf avatar Oct 27 '24 12:10 Wumpf

@samorr the latest development build should have this already now! :)

https://github.com/rerun-io/rerun/releases/tag/prerelease

Thanks! I will use it already tomorrow! 😁

samorr avatar Oct 27 '24 18:10 samorr