diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index cdd9347e7980..611a6da980eb 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -88,15 +88,14 @@ Of course, this will only take us so far. In the future we plan on caching queri Here is an overview of the crates included in the project: - - - - - + + + + + - + +Geospatial points with positions expressed in EPSG:4326 altitude and longitude, and optional colors and radii. + +**Note**: Geospatial entities are experimental. + +## Components + +**Required**: [`LatLon`](../components/lat_lon.md) + +**Recommended**: [`Radius`](../components/radius.md), [`Color`](../components/color.md) + +## Shown in +* [MapView](../views/map_view.md) +* [DataframeView](../views/dataframe_view.md) + +## API reference links + * 🌊 [C++ API docs for `GeoPoints`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1GeoPoints.html?speculative-link) + * 🐍 [Python API docs for `GeoPoints`](https://ref.rerun.io/docs/python/stable/common/archetypes?speculative-link#rerun.archetypes.GeoPoints) + * 🦀 [Rust API docs for `GeoPoints`](https://docs.rs/rerun/latest/rerun/archetypes/struct.GeoPoints.html?speculative-link) + diff --git a/docs/content/reference/types/components.md b/docs/content/reference/types/components.md index 2132eb2acd2a..798724396464 100644 --- a/docs/content/reference/types/components.md +++ b/docs/content/reference/types/components.md @@ -35,6 +35,7 @@ on [Entities and Components](../../concepts/entity-component.md). * [`ImageFormat`](components/image_format.md): The metadata describing the contents of a [`components.ImageBuffer`](https://rerun.io/docs/reference/types/components/image_buffer). * [`ImagePlaneDistance`](components/image_plane_distance.md): The distance from the camera origin to the image plane when the projection is shown in a 3D viewer. * [`KeypointId`](components/keypoint_id.md): A 16-bit ID representing a type of semantic keypoint within a class. +* [`LatLon`](components/lat_lon.md): A geographical position expressed in EPSG:4326 latitude and longitude. * [`LineStrip2D`](components/line_strip2d.md): A line strip in 2D space. * [`LineStrip3D`](components/line_strip3d.md): A line strip in 3D space. * [`MagnificationFilter`](components/magnification_filter.md): Filter used when magnifying an image/texture such that a single pixel/texel is displayed as multiple pixels on screen. diff --git a/docs/content/reference/types/components/.gitattributes b/docs/content/reference/types/components/.gitattributes index c07d94eee94f..a3e8630da4a9 100644 --- a/docs/content/reference/types/components/.gitattributes +++ b/docs/content/reference/types/components/.gitattributes @@ -23,6 +23,7 @@ image_buffer.md linguist-generated=true image_format.md linguist-generated=true image_plane_distance.md linguist-generated=true keypoint_id.md linguist-generated=true +lat_lon.md linguist-generated=true line_strip2d.md linguist-generated=true line_strip3d.md linguist-generated=true magnification_filter.md linguist-generated=true diff --git a/docs/content/reference/types/components/color.md b/docs/content/reference/types/components/color.md index c5703e66ea2f..7fc08869822d 100644 --- a/docs/content/reference/types/components/color.md +++ b/docs/content/reference/types/components/color.md @@ -26,6 +26,7 @@ byte is `R` and the least significant byte is `A`. * [`Boxes2D`](../archetypes/boxes2d.md) * [`Boxes3D`](../archetypes/boxes3d.md) * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) +* [`GeoPoints`](../archetypes/geo_points.md?speculative-link) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Mesh3D`](../archetypes/mesh3d.md) diff --git a/docs/content/reference/types/components/lat_lon.md b/docs/content/reference/types/components/lat_lon.md new file mode 100644 index 000000000000..5dfd2835a7da --- /dev/null +++ b/docs/content/reference/types/components/lat_lon.md @@ -0,0 +1,20 @@ +--- +title: "LatLon" +--- + + +A geographical position expressed in EPSG:4326 latitude and longitude. + +## Fields + +* lat_lon: [`DVec2D`](../datatypes/dvec2d.md) + +## API reference links + * 🌊 [C++ API docs for `LatLon`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1LatLon.html?speculative-link) + * 🐍 [Python API docs for `LatLon`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.LatLon) + * 🦀 [Rust API docs for `LatLon`](https://docs.rs/rerun/latest/rerun/components/struct.LatLon.html?speculative-link) + + +## Used by + +* [`GeoPoints`](../archetypes/geo_points.md?speculative-link) diff --git a/docs/content/reference/types/components/radius.md b/docs/content/reference/types/components/radius.md index e180c8d5a312..b3d4c91f59f5 100644 --- a/docs/content/reference/types/components/radius.md +++ b/docs/content/reference/types/components/radius.md @@ -29,6 +29,7 @@ The Viewer's UI scaling defaults to the OS scaling which typically is 100% for f * [`Boxes2D`](../archetypes/boxes2d.md) * [`Boxes3D`](../archetypes/boxes3d.md) * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) +* [`GeoPoints`](../archetypes/geo_points.md?speculative-link) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Points2D`](../archetypes/points2d.md) diff --git a/docs/content/reference/types/datatypes.md b/docs/content/reference/types/datatypes.md index c5b333ee7fb4..bb33cebb6c34 100644 --- a/docs/content/reference/types/datatypes.md +++ b/docs/content/reference/types/datatypes.md @@ -16,6 +16,7 @@ Data types are the lowest layer of the data model hierarchy. They are re-usable * [`ClassDescriptionMapElem`](datatypes/class_description_map_elem.md): A helper type for mapping [`datatypes.ClassId`](https://rerun.io/docs/reference/types/datatypes/class_id)s to class descriptions. * [`ClassId`](datatypes/class_id.md): A 16-bit ID representing a type of semantic class. * [`ColorModel`](datatypes/color_model.md): Specified what color components are present in an [`archetypes.Image`](https://rerun.io/docs/reference/types/archetypes/image). +* [`DVec2D`](datatypes/dvec2d.md): A double-precision vector in 2D space. * [`EntityPath`](datatypes/entity_path.md): A path to an entity in the `ChunkStore`. * [`Float32`](datatypes/float32.md): A single-precision 32-bit IEEE 754 floating point number. * [`Float64`](datatypes/float64.md): A double-precision 64-bit IEEE 754 floating point number. diff --git a/docs/content/reference/types/datatypes/.gitattributes b/docs/content/reference/types/datatypes/.gitattributes index 0998d55ed838..408958b8fb1c 100644 --- a/docs/content/reference/types/datatypes/.gitattributes +++ b/docs/content/reference/types/datatypes/.gitattributes @@ -10,6 +10,7 @@ class_description.md linguist-generated=true class_description_map_elem.md linguist-generated=true class_id.md linguist-generated=true color_model.md linguist-generated=true +dvec2d.md linguist-generated=true entity_path.md linguist-generated=true float32.md linguist-generated=true float64.md linguist-generated=true diff --git a/docs/content/reference/types/datatypes/dvec2d.md b/docs/content/reference/types/datatypes/dvec2d.md new file mode 100644 index 000000000000..f39668b29bdf --- /dev/null +++ b/docs/content/reference/types/datatypes/dvec2d.md @@ -0,0 +1,20 @@ +--- +title: "DVec2D" +--- + + +A double-precision vector in 2D space. + +## Fields + +* xy: 2x `f64` + +## API reference links + * 🌊 [C++ API docs for `DVec2D`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1DVec2D.html?speculative-link) + * 🐍 [Python API docs for `DVec2D`](https://ref.rerun.io/docs/python/stable/common/datatypes?speculative-link#rerun.datatypes.DVec2D) + * 🦀 [Rust API docs for `DVec2D`](https://docs.rs/rerun/latest/rerun/datatypes/struct.DVec2D.html?speculative-link) + + +## Used by + +* [`LatLon`](../components/lat_lon.md?speculative-link) diff --git a/docs/content/reference/types/views.md b/docs/content/reference/types/views.md index 8d7b8e11948c..3593e261a958 100644 --- a/docs/content/reference/types/views.md +++ b/docs/content/reference/types/views.md @@ -9,6 +9,7 @@ Views are the panels shown in the viewer's viewport and the primary means of ins * [`BarChartView`](views/bar_chart_view.md): A bar chart view. * [`DataframeView`](views/dataframe_view.md): A view to display any data in a tabular form. +* [`MapView`](views/map_view.md): A 2D map view to display geospatial primitives. * [`Spatial2DView`](views/spatial2d_view.md): For viewing spatial 2D data. * [`Spatial3DView`](views/spatial3d_view.md): For viewing spatial 3D data. * [`TensorView`](views/tensor_view.md): A view on a tensor of any dimensionality. diff --git a/docs/content/reference/types/views/.gitattributes b/docs/content/reference/types/views/.gitattributes index ee86a2002ccb..bf43e7d7a6a8 100644 --- a/docs/content/reference/types/views/.gitattributes +++ b/docs/content/reference/types/views/.gitattributes @@ -3,6 +3,7 @@ .gitattributes linguist-generated=true bar_chart_view.md linguist-generated=true dataframe_view.md linguist-generated=true +map_view.md linguist-generated=true spatial2d_view.md linguist-generated=true spatial3d_view.md linguist-generated=true tensor_view.md linguist-generated=true diff --git a/docs/content/reference/types/views/map_view.md b/docs/content/reference/types/views/map_view.md new file mode 100644 index 000000000000..730d94cbd175 --- /dev/null +++ b/docs/content/reference/types/views/map_view.md @@ -0,0 +1,28 @@ +--- +title: "MapView" +--- + + +A 2D map view to display geospatial primitives. + +## Properties + +### `zoom` +Configures the zoom level of the map view. +### `background` +Configuration for the background map of the map view. + +## API reference links + * 🐍 [Python API docs for `MapView`](https://ref.rerun.io/docs/python/stable/common/blueprint_views?speculative-link#rerun.blueprint.views.MapView) + +## Example + +### Use a blueprint to create a map view. + +snippet: views/map + + +## Visualized archetypes + +* [`GeoPoints`](../archetypes/geo_points.md) + diff --git a/docs/snippets/all/views/map.py b/docs/snippets/all/views/map.py new file mode 100644 index 000000000000..64fa46a4f48c --- /dev/null +++ b/docs/snippets/all/views/map.py @@ -0,0 +1,22 @@ +"""Use a blueprint to show a map.""" + +import rerun as rr +import rerun.blueprint as rrb + +rr.init("rerun_example_map_view", spawn=True) + +rr.log("points", rr.GeoPoints([[47.6344, 19.1397], [47.6334, 19.1399]])) + +# Create a map view to display the chart. +# TODO(#7903): cleanup the blueprint API for the map view +blueprint = rrb.Blueprint( + rrb.MapView( + origin="points", + name="MapView", + zoom=rrb.archetypes.MapZoom(16.0), + background=rrb.archetypes.MapBackground(rrb.components.MapProvider.OpenStreetMap), + ), + collapse_panels=True, +) + +rr.send_blueprint(blueprint) diff --git a/rerun_cpp/src/rerun/archetypes.hpp b/rerun_cpp/src/rerun/archetypes.hpp index 4922c62f6956..12b9bc511b9a 100644 --- a/rerun_cpp/src/rerun/archetypes.hpp +++ b/rerun_cpp/src/rerun/archetypes.hpp @@ -15,6 +15,7 @@ #include "archetypes/disconnected_space.hpp" #include "archetypes/ellipsoids3d.hpp" #include "archetypes/encoded_image.hpp" +#include "archetypes/geo_points.hpp" #include "archetypes/image.hpp" #include "archetypes/instance_poses3d.hpp" #include "archetypes/line_strips2d.hpp" diff --git a/rerun_cpp/src/rerun/archetypes/.gitattributes b/rerun_cpp/src/rerun/archetypes/.gitattributes index 0151357a4f60..c95d5b78136f 100644 --- a/rerun_cpp/src/rerun/archetypes/.gitattributes +++ b/rerun_cpp/src/rerun/archetypes/.gitattributes @@ -27,6 +27,8 @@ ellipsoids3d.cpp linguist-generated=true ellipsoids3d.hpp linguist-generated=true encoded_image.cpp linguist-generated=true encoded_image.hpp linguist-generated=true +geo_points.cpp linguist-generated=true +geo_points.hpp linguist-generated=true image.cpp linguist-generated=true image.hpp linguist-generated=true instance_poses3d.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/archetypes/geo_points.cpp b/rerun_cpp/src/rerun/archetypes/geo_points.cpp new file mode 100644 index 000000000000..dfd990f5e8a8 --- /dev/null +++ b/rerun_cpp/src/rerun/archetypes/geo_points.cpp @@ -0,0 +1,43 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs". + +#include "geo_points.hpp" + +#include "../collection_adapter_builtins.hpp" + +namespace rerun::archetypes {} + +namespace rerun { + + Result> AsComponents::serialize( + const archetypes::GeoPoints& archetype + ) { + using namespace archetypes; + std::vector cells; + cells.reserve(4); + + { + auto result = ComponentBatch::from_loggable(archetype.positions); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.radii.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.radii.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.colors.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.colors.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + { + auto indicator = GeoPoints::IndicatorComponent(); + auto result = ComponentBatch::from_loggable(indicator); + RR_RETURN_NOT_OK(result.error); + cells.emplace_back(std::move(result.value)); + } + + return cells; + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/archetypes/geo_points.hpp b/rerun_cpp/src/rerun/archetypes/geo_points.hpp new file mode 100644 index 000000000000..4f58ca761083 --- /dev/null +++ b/rerun_cpp/src/rerun/archetypes/geo_points.hpp @@ -0,0 +1,77 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs". + +#pragma once + +#include "../collection.hpp" +#include "../compiler_utils.hpp" +#include "../component_batch.hpp" +#include "../components/color.hpp" +#include "../components/lat_lon.hpp" +#include "../components/radius.hpp" +#include "../indicator_component.hpp" +#include "../result.hpp" + +#include +#include +#include +#include + +namespace rerun::archetypes { + /// **Archetype**: Geospatial points with positions expressed in EPSG:4326 altitude and longitude, and optional colors and radii. + /// + /// **Note**: Geospatial entities are experimental. + struct GeoPoints { + /// The EPSG:4326 coordinates for the points. + Collection positions; + + /// Optional radii for the points, effectively turning them into circles. + std::optional> radii; + + /// Optional colors for the points. + std::optional> colors; + + public: + static constexpr const char IndicatorComponentName[] = + "rerun.components.GeoPointsIndicator"; + + /// Indicator component, used to identify the archetype when converting to a list of components. + using IndicatorComponent = rerun::components::IndicatorComponent; + + public: + GeoPoints() = default; + GeoPoints(GeoPoints&& other) = default; + + explicit GeoPoints(Collection _positions) + : positions(std::move(_positions)) {} + + /// Optional radii for the points, effectively turning them into circles. + GeoPoints with_radii(Collection _radii) && { + radii = std::move(_radii); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// Optional colors for the points. + GeoPoints with_colors(Collection _colors) && { + colors = std::move(_colors); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + }; + +} // namespace rerun::archetypes + +namespace rerun { + /// \private + template + struct AsComponents; + + /// \private + template <> + struct AsComponents { + /// Serialize all set component batches. + static Result> serialize(const archetypes::GeoPoints& archetype + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/archetypes.hpp b/rerun_cpp/src/rerun/blueprint/archetypes.hpp index eae71f6b2164..2fd779424b1f 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes.hpp @@ -5,6 +5,8 @@ #include "blueprint/archetypes/background.hpp" #include "blueprint/archetypes/container_blueprint.hpp" #include "blueprint/archetypes/dataframe_query.hpp" +#include "blueprint/archetypes/map_background.hpp" +#include "blueprint/archetypes/map_zoom.hpp" #include "blueprint/archetypes/panel_blueprint.hpp" #include "blueprint/archetypes/plot_legend.hpp" #include "blueprint/archetypes/scalar_axis.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes b/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes index 40240eeaa29b..26e1a60b89a6 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes @@ -7,6 +7,10 @@ container_blueprint.cpp linguist-generated=true container_blueprint.hpp linguist-generated=true dataframe_query.cpp linguist-generated=true dataframe_query.hpp linguist-generated=true +map_background.cpp linguist-generated=true +map_background.hpp linguist-generated=true +map_zoom.cpp linguist-generated=true +map_zoom.hpp linguist-generated=true panel_blueprint.cpp linguist-generated=true panel_blueprint.hpp linguist-generated=true plot_legend.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp new file mode 100644 index 000000000000..dab7d3dbbd1c --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp @@ -0,0 +1,34 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs". + +#include "map_background.hpp" + +#include "../../collection_adapter_builtins.hpp" + +namespace rerun::blueprint::archetypes {} + +namespace rerun { + + Result> + AsComponents::serialize( + const blueprint::archetypes::MapBackground& archetype + ) { + using namespace blueprint::archetypes; + std::vector cells; + cells.reserve(2); + + { + auto result = ComponentBatch::from_loggable(archetype.provider); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + { + auto indicator = MapBackground::IndicatorComponent(); + auto result = ComponentBatch::from_loggable(indicator); + RR_RETURN_NOT_OK(result.error); + cells.emplace_back(std::move(result.value)); + } + + return cells; + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp new file mode 100644 index 000000000000..3d63b252107f --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp @@ -0,0 +1,54 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs". + +#pragma once + +#include "../../blueprint/components/map_provider.hpp" +#include "../../collection.hpp" +#include "../../component_batch.hpp" +#include "../../indicator_component.hpp" +#include "../../result.hpp" + +#include +#include +#include + +namespace rerun::blueprint::archetypes { + /// **Archetype**: Configuration for the background map of the map view. + struct MapBackground { + /// Map provider and style to use. + /// + /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + rerun::blueprint::components::MapProvider provider; + + public: + static constexpr const char IndicatorComponentName[] = + "rerun.blueprint.components.MapBackgroundIndicator"; + + /// Indicator component, used to identify the archetype when converting to a list of components. + using IndicatorComponent = rerun::components::IndicatorComponent; + + public: + MapBackground() = default; + MapBackground(MapBackground&& other) = default; + + explicit MapBackground(rerun::blueprint::components::MapProvider _provider) + : provider(std::move(_provider)) {} + }; + +} // namespace rerun::blueprint::archetypes + +namespace rerun { + /// \private + template + struct AsComponents; + + /// \private + template <> + struct AsComponents { + /// Serialize all set component batches. + static Result> serialize( + const blueprint::archetypes::MapBackground& archetype + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp new file mode 100644 index 000000000000..a4f7f16d4798 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp @@ -0,0 +1,33 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs". + +#include "map_zoom.hpp" + +#include "../../collection_adapter_builtins.hpp" + +namespace rerun::blueprint::archetypes {} + +namespace rerun { + + Result> AsComponents::serialize( + const blueprint::archetypes::MapZoom& archetype + ) { + using namespace blueprint::archetypes; + std::vector cells; + cells.reserve(2); + + { + auto result = ComponentBatch::from_loggable(archetype.zoom); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + { + auto indicator = MapZoom::IndicatorComponent(); + auto result = ComponentBatch::from_loggable(indicator); + RR_RETURN_NOT_OK(result.error); + cells.emplace_back(std::move(result.value)); + } + + return cells; + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp new file mode 100644 index 000000000000..4c4b3a65901a --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp @@ -0,0 +1,53 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs". + +#pragma once + +#include "../../blueprint/components/zoom_level.hpp" +#include "../../collection.hpp" +#include "../../component_batch.hpp" +#include "../../indicator_component.hpp" +#include "../../result.hpp" + +#include +#include +#include + +namespace rerun::blueprint::archetypes { + /// **Archetype**: Configuration of the map view zoom level. + struct MapZoom { + /// Zoom level for the map. + /// + /// Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). + rerun::blueprint::components::ZoomLevel zoom; + + public: + static constexpr const char IndicatorComponentName[] = + "rerun.blueprint.components.MapZoomIndicator"; + + /// Indicator component, used to identify the archetype when converting to a list of components. + using IndicatorComponent = rerun::components::IndicatorComponent; + + public: + MapZoom() = default; + MapZoom(MapZoom&& other) = default; + + explicit MapZoom(rerun::blueprint::components::ZoomLevel _zoom) : zoom(std::move(_zoom)) {} + }; + +} // namespace rerun::blueprint::archetypes + +namespace rerun { + /// \private + template + struct AsComponents; + + /// \private + template <> + struct AsComponents { + /// Serialize all set component batches. + static Result> serialize( + const blueprint::archetypes::MapZoom& archetype + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index 7f08ea1cf13d..9499183c3571 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -18,6 +18,7 @@ #include "blueprint/components/included_space_view.hpp" #include "blueprint/components/interactive.hpp" #include "blueprint/components/lock_range_during_zoom.hpp" +#include "blueprint/components/map_provider.hpp" #include "blueprint/components/panel_state.hpp" #include "blueprint/components/query_expression.hpp" #include "blueprint/components/root_container.hpp" @@ -34,3 +35,4 @@ #include "blueprint/components/visible_time_range.hpp" #include "blueprint/components/visual_bounds2d.hpp" #include "blueprint/components/visualizer_overrides.hpp" +#include "blueprint/components/zoom_level.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/components/.gitattributes b/rerun_cpp/src/rerun/blueprint/components/.gitattributes index 6e54a8293f6e..8bf0eaf38c0e 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -20,6 +20,8 @@ included_content.hpp linguist-generated=true included_space_view.hpp linguist-generated=true interactive.hpp linguist-generated=true lock_range_during_zoom.hpp linguist-generated=true +map_provider.cpp linguist-generated=true +map_provider.hpp linguist-generated=true panel_state.cpp linguist-generated=true panel_state.hpp linguist-generated=true query_expression.hpp linguist-generated=true @@ -38,3 +40,4 @@ visible.hpp linguist-generated=true visible_time_range.hpp linguist-generated=true visual_bounds2d.hpp linguist-generated=true visualizer_overrides.hpp linguist-generated=true +zoom_level.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/map_provider.cpp b/rerun_cpp/src/rerun/blueprint/components/map_provider.cpp new file mode 100644 index 000000000000..318b228ae589 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/map_provider.cpp @@ -0,0 +1,58 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/components/map_provider.fbs". + +#include "map_provider.hpp" + +#include +#include + +namespace rerun { + const std::shared_ptr& + Loggable::arrow_datatype() { + static const auto datatype = arrow::uint8(); + return datatype; + } + + Result> Loggable::to_arrow( + const blueprint::components::MapProvider* instances, size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + )); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error Loggable::fill_arrow_array_builder( + arrow::UInt8Builder* builder, const blueprint::components::MapProvider* elements, + size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + ARROW_RETURN_NOT_OK(builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + const auto variant = elements[elem_idx]; + ARROW_RETURN_NOT_OK(builder->Append(static_cast(variant))); + } + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/map_provider.hpp b/rerun_cpp/src/rerun/blueprint/components/map_provider.hpp new file mode 100644 index 000000000000..dae74d04929f --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/map_provider.hpp @@ -0,0 +1,69 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/components/map_provider.fbs". + +#pragma once + +#include "../../result.hpp" + +#include +#include + +namespace arrow { + /// \private + template + class NumericBuilder; + + class Array; + class DataType; + class UInt8Type; + using UInt8Builder = NumericBuilder; +} // namespace arrow + +namespace rerun::blueprint::components { + /// **Component**: Name of the map provider to be used in Map views. + enum class MapProvider : uint8_t { + + /// `OpenStreetMap` is the default map provider. + OpenStreetMap = 1, + + /// Mapbox Streets is a minimalistic map designed by Mapbox. + /// + /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + MapboxStreets = 2, + + /// Mapbox Dark is a dark-themed map designed by Mapbox. + /// + /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + MapboxDark = 3, + + /// Mapbox Satellite is a satellite map designed by Mapbox. + /// + /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + MapboxSatellite = 4, + }; +} // namespace rerun::blueprint::components + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.MapProvider"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::blueprint:: components::MapProvider` into an arrow array. + static Result> to_arrow( + const blueprint::components::MapProvider* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::UInt8Builder* builder, const blueprint::components::MapProvider* elements, + size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/zoom_level.hpp b/rerun_cpp/src/rerun/blueprint/components/zoom_level.hpp new file mode 100644 index 000000000000..a6e32f86bf52 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/zoom_level.hpp @@ -0,0 +1,74 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/blueprint/components/zoom_level.fbs". + +#pragma once + +#include "../../datatypes/float32.hpp" +#include "../../result.hpp" + +#include +#include + +namespace rerun::blueprint::components { + /// **Component**: A zoom level determines how much of the world is visible on a map. + struct ZoomLevel { + /// Zoom level: 0 being the lowest zoom level (fully zoomed out) and 22 being the highest (fully zoomed in). + rerun::datatypes::Float32 zoom; + + public: + ZoomLevel() = default; + + ZoomLevel(rerun::datatypes::Float32 zoom_) : zoom(zoom_) {} + + ZoomLevel& operator=(rerun::datatypes::Float32 zoom_) { + zoom = zoom_; + return *this; + } + + ZoomLevel(float value_) : zoom(value_) {} + + ZoomLevel& operator=(float value_) { + zoom = value_; + return *this; + } + + /// Cast to the underlying Float32 datatype + operator rerun::datatypes::Float32() const { + return zoom; + } + }; +} // namespace rerun::blueprint::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::ZoomLevel)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.ZoomLevel"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::blueprint:: components::ZoomLevel` into an arrow array. + static Result> to_arrow( + const blueprint::components::ZoomLevel* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->zoom, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/components.hpp b/rerun_cpp/src/rerun/components.hpp index e11d74969590..4451d0a4b038 100644 --- a/rerun_cpp/src/rerun/components.hpp +++ b/rerun_cpp/src/rerun/components.hpp @@ -24,6 +24,7 @@ #include "components/image_format.hpp" #include "components/image_plane_distance.hpp" #include "components/keypoint_id.hpp" +#include "components/lat_lon.hpp" #include "components/line_strip2d.hpp" #include "components/line_strip3d.hpp" #include "components/magnification_filter.hpp" diff --git a/rerun_cpp/src/rerun/components/.gitattributes b/rerun_cpp/src/rerun/components/.gitattributes index a63cd0bb87b8..0973ed640da4 100644 --- a/rerun_cpp/src/rerun/components/.gitattributes +++ b/rerun_cpp/src/rerun/components/.gitattributes @@ -27,6 +27,7 @@ image_buffer.hpp linguist-generated=true image_format.hpp linguist-generated=true image_plane_distance.hpp linguist-generated=true keypoint_id.hpp linguist-generated=true +lat_lon.hpp linguist-generated=true line_strip2d.cpp linguist-generated=true line_strip2d.hpp linguist-generated=true line_strip3d.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/components/lat_lon.hpp b/rerun_cpp/src/rerun/components/lat_lon.hpp new file mode 100644 index 000000000000..c17a4be43c97 --- /dev/null +++ b/rerun_cpp/src/rerun/components/lat_lon.hpp @@ -0,0 +1,88 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/components/latlon.fbs". + +#pragma once + +#include "../datatypes/dvec2d.hpp" +#include "../result.hpp" + +#include +#include +#include + +namespace rerun::components { + /// **Component**: A geographical position expressed in EPSG:4326 latitude and longitude. + struct LatLon { + rerun::datatypes::DVec2D lat_lon; + + public: // START of extensions from lat_lon_ext.cpp: + /// Construct LatLon from x/y values. + LatLon(double lat, double lon) : lat_lon{lat, lon} {} + + double latitude() const { + return lat_lon.x(); + } + + double longitude() const { + return lat_lon.y(); + } + + // END of extensions from lat_lon_ext.cpp, start of generated code: + + public: + LatLon() = default; + + LatLon(rerun::datatypes::DVec2D lat_lon_) : lat_lon(lat_lon_) {} + + LatLon& operator=(rerun::datatypes::DVec2D lat_lon_) { + lat_lon = lat_lon_; + return *this; + } + + LatLon(std::array xy_) : lat_lon(xy_) {} + + LatLon& operator=(std::array xy_) { + lat_lon = xy_; + return *this; + } + + /// Cast to the underlying DVec2D datatype + operator rerun::datatypes::DVec2D() const { + return lat_lon; + } + }; +} // namespace rerun::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::DVec2D) == sizeof(components::LatLon)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.components.LatLon"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::components::LatLon` into an arrow array. + static Result> to_arrow( + const components::LatLon* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->lat_lon, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/components/lat_lon_ext.cpp b/rerun_cpp/src/rerun/components/lat_lon_ext.cpp new file mode 100644 index 000000000000..3938ebfc0175 --- /dev/null +++ b/rerun_cpp/src/rerun/components/lat_lon_ext.cpp @@ -0,0 +1,31 @@ +#include "lat_lon.hpp" + +// Uncomment for better auto-complete while editing the extension. +// #define EDIT_EXTENSION + +namespace rerun { + namespace components { + +#ifdef EDIT_EXTENSION + struct LatLonExt { + double lat_lon[2]; +#define LatLon LatLonExt + + // + + /// Construct LatLon from x/y values. + LatLon(double lat, double lon) : lat_lon{lat, lon} {} + + double latitude() const { + return lat_lon.x(); + } + + double longitude() const { + return lat_lon.y(); + } + + // + }; +#endif + } // namespace components +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes.hpp b/rerun_cpp/src/rerun/datatypes.hpp index 9cd8ab48bdd2..e1ebcff3a151 100644 --- a/rerun_cpp/src/rerun/datatypes.hpp +++ b/rerun_cpp/src/rerun/datatypes.hpp @@ -11,6 +11,7 @@ #include "datatypes/class_description_map_elem.hpp" #include "datatypes/class_id.hpp" #include "datatypes/color_model.hpp" +#include "datatypes/dvec2d.hpp" #include "datatypes/entity_path.hpp" #include "datatypes/float32.hpp" #include "datatypes/float64.hpp" diff --git a/rerun_cpp/src/rerun/datatypes/.gitattributes b/rerun_cpp/src/rerun/datatypes/.gitattributes index 315de38d7a47..133573f66723 100644 --- a/rerun_cpp/src/rerun/datatypes/.gitattributes +++ b/rerun_cpp/src/rerun/datatypes/.gitattributes @@ -19,6 +19,8 @@ class_id.cpp linguist-generated=true class_id.hpp linguist-generated=true color_model.cpp linguist-generated=true color_model.hpp linguist-generated=true +dvec2d.cpp linguist-generated=true +dvec2d.hpp linguist-generated=true entity_path.cpp linguist-generated=true entity_path.hpp linguist-generated=true float32.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/datatypes/dvec2d.cpp b/rerun_cpp/src/rerun/datatypes/dvec2d.cpp new file mode 100644 index 000000000000..ff9e24900863 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/dvec2d.cpp @@ -0,0 +1,63 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/datatypes/dvec2d.fbs". + +#include "dvec2d.hpp" + +#include +#include + +namespace rerun::datatypes {} + +namespace rerun { + const std::shared_ptr& Loggable::arrow_datatype() { + static const auto datatype = + arrow::fixed_size_list(arrow::field("item", arrow::float64(), false), 2); + return datatype; + } + + Result> Loggable::to_arrow( + const datatypes::DVec2D* instances, size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + )); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error Loggable::fill_arrow_array_builder( + arrow::FixedSizeListBuilder* builder, const datatypes::DVec2D* elements, size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + auto value_builder = static_cast(builder->value_builder()); + + ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements))); + static_assert(sizeof(elements[0].xy) == sizeof(elements[0])); + ARROW_RETURN_NOT_OK(value_builder->AppendValues( + elements[0].xy.data(), + static_cast(num_elements * 2), + nullptr + )); + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/dvec2d.hpp b/rerun_cpp/src/rerun/datatypes/dvec2d.hpp new file mode 100644 index 000000000000..881c78112749 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/dvec2d.hpp @@ -0,0 +1,75 @@ +// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/store/re_types/definitions/rerun/datatypes/dvec2d.fbs". + +#pragma once + +#include "../result.hpp" + +#include +#include +#include + +namespace arrow { + class Array; + class DataType; + class FixedSizeListBuilder; +} // namespace arrow + +namespace rerun::datatypes { + /// **Datatype**: A double-precision vector in 2D space. + struct DVec2D { + std::array xy; + + public: // START of extensions from dvec2d_ext.cpp: + /// Construct DVec2D from x/y values. + DVec2D(double x, double y) : xy{x, y} {} + + /// Construct DVec2D from x/y double pointer. + explicit DVec2D(const double* xy_) : xy{xy_[0], xy_[1]} {} + + double x() const { + return xy[0]; + } + + double y() const { + return xy[1]; + } + + // END of extensions from dvec2d_ext.cpp, start of generated code: + + public: + DVec2D() = default; + + DVec2D(std::array xy_) : xy(xy_) {} + + DVec2D& operator=(std::array xy_) { + xy = xy_; + return *this; + } + }; +} // namespace rerun::datatypes + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.datatypes.DVec2D"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::datatypes::DVec2D` into an arrow array. + static Result> to_arrow( + const datatypes::DVec2D* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::FixedSizeListBuilder* builder, const datatypes::DVec2D* elements, + size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/dvec2d_ext.cpp b/rerun_cpp/src/rerun/datatypes/dvec2d_ext.cpp new file mode 100644 index 000000000000..aec931e932d5 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/dvec2d_ext.cpp @@ -0,0 +1,34 @@ +#include "dvec2d.hpp" + +// Uncomment for better auto-complete while editing the extension. +// #define EDIT_EXTENSION + +namespace rerun { + namespace datatypes { + +#ifdef EDIT_EXTENSION + struct DVec2DExt { + double xy[2]; +#define DVec2D DVec2DExt + + // + + /// Construct DVec2D from x/y values. + DVec2D(double x, double y) : xy{x, y} {} + + /// Construct DVec2D from x/y double pointer. + explicit DVec2D(const double* xy_) : xy{xy_[0], xy_[1]} {} + + double x() const { + return xy[0]; + } + + double y() const { + return xy[1]; + } + + // + }; +#endif + } // namespace datatypes +} // namespace rerun diff --git a/rerun_py/docs/gen_common_index.py b/rerun_py/docs/gen_common_index.py index 2056f52e673c..8462277bb0d3 100755 --- a/rerun_py/docs/gen_common_index.py +++ b/rerun_py/docs/gen_common_index.py @@ -207,6 +207,13 @@ class Section: ], gen_page=False, ), + Section( + title="Geospatial Archetypes", + class_list=[ + "archetypes.GeoPoints", + ], + gen_page=False, + ), Section( title="Tensors", class_list=["archetypes.Tensor"], diff --git a/rerun_py/rerun_sdk/rerun/__init__.py b/rerun_py/rerun_sdk/rerun/__init__.py index 42df3f2fc339..ef36706e1059 100644 --- a/rerun_py/rerun_sdk/rerun/__init__.py +++ b/rerun_py/rerun_sdk/rerun/__init__.py @@ -64,6 +64,7 @@ DisconnectedSpace as DisconnectedSpace, Ellipsoids3D as Ellipsoids3D, EncodedImage as EncodedImage, + GeoPoints as GeoPoints, Image as Image, InstancePoses3D as InstancePoses3D, LineStrips2D as LineStrips2D, diff --git a/rerun_py/rerun_sdk/rerun/archetypes/.gitattributes b/rerun_py/rerun_sdk/rerun/archetypes/.gitattributes index b57110b5036e..1e2fbcfe9406 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/archetypes/.gitattributes @@ -15,6 +15,7 @@ depth_image.py linguist-generated=true disconnected_space.py linguist-generated=true ellipsoids3d.py linguist-generated=true encoded_image.py linguist-generated=true +geo_points.py linguist-generated=true image.py linguist-generated=true instance_poses3d.py linguist-generated=true line_strips2d.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/archetypes/__init__.py b/rerun_py/rerun_sdk/rerun/archetypes/__init__.py index 8ba5d3fcdee3..bb31399d85ff 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/__init__.py @@ -15,6 +15,7 @@ from .disconnected_space import DisconnectedSpace from .ellipsoids3d import Ellipsoids3D from .encoded_image import EncodedImage +from .geo_points import GeoPoints from .image import Image from .instance_poses3d import InstancePoses3D from .line_strips2d import LineStrips2D @@ -48,6 +49,7 @@ "DisconnectedSpace", "Ellipsoids3D", "EncodedImage", + "GeoPoints", "Image", "InstancePoses3D", "LineStrips2D", diff --git a/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py b/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py new file mode 100644 index 000000000000..3cec4449b52b --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py @@ -0,0 +1,104 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs". + +# You can extend this class by creating a "GeoPointsExt" class in "geo_points_ext.py". + +from __future__ import annotations + +from typing import Any + +from attrs import define, field + +from .. import components, datatypes +from .._baseclasses import ( + Archetype, +) +from ..error_utils import catch_and_log_exceptions + +__all__ = ["GeoPoints"] + + +@define(str=False, repr=False, init=False) +class GeoPoints(Archetype): + """ + **Archetype**: Geospatial points with positions expressed in EPSG:4326 altitude and longitude, and optional colors and radii. + + **Note**: Geospatial entities are experimental. + """ + + def __init__( + self: Any, + positions: datatypes.DVec2DArrayLike, + *, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + ): + """ + Create a new instance of the GeoPoints archetype. + + Parameters + ---------- + positions: + The EPSG:4326 coordinates for the points. + radii: + Optional radii for the points, effectively turning them into circles. + colors: + Optional colors for the points. + + The colors are interpreted as RGB or RGBA in sRGB gamma-space, + As either 0-1 floats or 0-255 integers, with separate alpha. + + """ + + # You can define your own __init__ function as a member of GeoPointsExt in geo_points_ext.py + with catch_and_log_exceptions(context=self.__class__.__name__): + self.__attrs_init__(positions=positions, radii=radii, colors=colors) + return + self.__attrs_clear__() + + def __attrs_clear__(self) -> None: + """Convenience method for calling `__attrs_init__` with all `None`s.""" + self.__attrs_init__( + positions=None, # type: ignore[arg-type] + radii=None, # type: ignore[arg-type] + colors=None, # type: ignore[arg-type] + ) + + @classmethod + def _clear(cls) -> GeoPoints: + """Produce an empty GeoPoints, bypassing `__init__`.""" + inst = cls.__new__(cls) + inst.__attrs_clear__() + return inst + + positions: components.LatLonBatch = field( + metadata={"component": "required"}, + converter=components.LatLonBatch._required, # type: ignore[misc] + ) + # The EPSG:4326 coordinates for the points. + # + # (Docstring intentionally commented out to hide this field from the docs) + + radii: components.RadiusBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=components.RadiusBatch._optional, # type: ignore[misc] + ) + # Optional radii for the points, effectively turning them into circles. + # + # (Docstring intentionally commented out to hide this field from the docs) + + colors: components.ColorBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=components.ColorBatch._optional, # type: ignore[misc] + ) + # Optional colors for the points. + # + # The colors are interpreted as RGB or RGBA in sRGB gamma-space, + # As either 0-1 floats or 0-255 integers, with separate alpha. + # + # (Docstring intentionally commented out to hide this field from the docs) + + __str__ = Archetype.__str__ + __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/__init__.py index 0da791c5fb26..3ba51bcc058f 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/__init__.py @@ -52,6 +52,7 @@ from .views import ( BarChartView as BarChartView, DataframeView as DataframeView, + MapView as MapView, Spatial2DView as Spatial2DView, Spatial3DView as Spatial3DView, TensorView as TensorView, diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes index 1db9a825f2e9..bb528bfbaf9a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes @@ -5,6 +5,8 @@ __init__.py linguist-generated=true background.py linguist-generated=true container_blueprint.py linguist-generated=true dataframe_query.py linguist-generated=true +map_background.py linguist-generated=true +map_zoom.py linguist-generated=true panel_blueprint.py linguist-generated=true plot_legend.py linguist-generated=true scalar_axis.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py index 423f025dc7aa..018ec6c34d5e 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py @@ -5,6 +5,8 @@ from .background import Background from .container_blueprint import ContainerBlueprint from .dataframe_query import DataframeQuery +from .map_background import MapBackground +from .map_zoom import MapZoom from .panel_blueprint import PanelBlueprint from .plot_legend import PlotLegend from .scalar_axis import ScalarAxis @@ -21,6 +23,8 @@ "Background", "ContainerBlueprint", "DataframeQuery", + "MapBackground", + "MapZoom", "PanelBlueprint", "PlotLegend", "ScalarAxis", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py new file mode 100644 index 000000000000..bd32323fc481 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py @@ -0,0 +1,68 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs". + +# You can extend this class by creating a "MapBackgroundExt" class in "map_background_ext.py". + +from __future__ import annotations + +from typing import Any + +from attrs import define, field + +from ..._baseclasses import ( + Archetype, +) +from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions + +__all__ = ["MapBackground"] + + +@define(str=False, repr=False, init=False) +class MapBackground(Archetype): + """**Archetype**: Configuration for the background map of the map view.""" + + def __init__(self: Any, provider: blueprint_components.MapProviderLike): + """ + Create a new instance of the MapBackground archetype. + + Parameters + ---------- + provider: + Map provider and style to use. + + **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + + """ + + # You can define your own __init__ function as a member of MapBackgroundExt in map_background_ext.py + with catch_and_log_exceptions(context=self.__class__.__name__): + self.__attrs_init__(provider=provider) + return + self.__attrs_clear__() + + def __attrs_clear__(self) -> None: + """Convenience method for calling `__attrs_init__` with all `None`s.""" + self.__attrs_init__( + provider=None, # type: ignore[arg-type] + ) + + @classmethod + def _clear(cls) -> MapBackground: + """Produce an empty MapBackground, bypassing `__init__`.""" + inst = cls.__new__(cls) + inst.__attrs_clear__() + return inst + + provider: blueprint_components.MapProviderBatch = field( + metadata={"component": "required"}, + converter=blueprint_components.MapProviderBatch._required, # type: ignore[misc] + ) + # Map provider and style to use. + # + # **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + # + # (Docstring intentionally commented out to hide this field from the docs) + + __str__ = Archetype.__str__ + __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py new file mode 100644 index 000000000000..60f518bd77b8 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py @@ -0,0 +1,69 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs". + +# You can extend this class by creating a "MapZoomExt" class in "map_zoom_ext.py". + +from __future__ import annotations + +from typing import Any + +from attrs import define, field + +from ... import datatypes +from ..._baseclasses import ( + Archetype, +) +from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions + +__all__ = ["MapZoom"] + + +@define(str=False, repr=False, init=False) +class MapZoom(Archetype): + """**Archetype**: Configuration of the map view zoom level.""" + + def __init__(self: Any, zoom: datatypes.Float32Like): + """ + Create a new instance of the MapZoom archetype. + + Parameters + ---------- + zoom: + Zoom level for the map. + + Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). + + """ + + # You can define your own __init__ function as a member of MapZoomExt in map_zoom_ext.py + with catch_and_log_exceptions(context=self.__class__.__name__): + self.__attrs_init__(zoom=zoom) + return + self.__attrs_clear__() + + def __attrs_clear__(self) -> None: + """Convenience method for calling `__attrs_init__` with all `None`s.""" + self.__attrs_init__( + zoom=None, # type: ignore[arg-type] + ) + + @classmethod + def _clear(cls) -> MapZoom: + """Produce an empty MapZoom, bypassing `__init__`.""" + inst = cls.__new__(cls) + inst.__attrs_clear__() + return inst + + zoom: blueprint_components.ZoomLevelBatch = field( + metadata={"component": "required"}, + converter=blueprint_components.ZoomLevelBatch._required, # type: ignore[misc] + ) + # Zoom level for the map. + # + # Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). + # + # (Docstring intentionally commented out to hide this field from the docs) + + __str__ = Archetype.__str__ + __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes index 44c616a62b0a..d169ad0ec28c 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -18,6 +18,7 @@ included_content.py linguist-generated=true included_space_view.py linguist-generated=true interactive.py linguist-generated=true lock_range_during_zoom.py linguist-generated=true +map_provider.py linguist-generated=true panel_state.py linguist-generated=true query_expression.py linguist-generated=true root_container.py linguist-generated=true @@ -34,3 +35,4 @@ visible.py linguist-generated=true visible_time_range.py linguist-generated=true visual_bounds2d.py linguist-generated=true visualizer_overrides.py linguist-generated=true +zoom_level.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py index 7ed14ed9c1f8..1f82d7bb448a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -34,6 +34,7 @@ from .included_space_view import IncludedSpaceView, IncludedSpaceViewBatch, IncludedSpaceViewType from .interactive import Interactive, InteractiveBatch, InteractiveType from .lock_range_during_zoom import LockRangeDuringZoom, LockRangeDuringZoomBatch, LockRangeDuringZoomType +from .map_provider import MapProvider, MapProviderArrayLike, MapProviderBatch, MapProviderLike, MapProviderType from .panel_state import PanelState, PanelStateArrayLike, PanelStateBatch, PanelStateLike, PanelStateType from .query_expression import QueryExpression, QueryExpressionBatch, QueryExpressionType from .root_container import RootContainer, RootContainerBatch, RootContainerType @@ -58,6 +59,7 @@ from .visible_time_range import VisibleTimeRange, VisibleTimeRangeBatch, VisibleTimeRangeType from .visual_bounds2d import VisualBounds2D, VisualBounds2DBatch, VisualBounds2DType from .visualizer_overrides import VisualizerOverrides, VisualizerOverridesBatch, VisualizerOverridesType +from .zoom_level import ZoomLevel, ZoomLevelBatch, ZoomLevelType __all__ = [ "ActiveTab", @@ -114,6 +116,11 @@ "LockRangeDuringZoom", "LockRangeDuringZoomBatch", "LockRangeDuringZoomType", + "MapProvider", + "MapProviderArrayLike", + "MapProviderBatch", + "MapProviderLike", + "MapProviderType", "PanelState", "PanelStateArrayLike", "PanelStateBatch", @@ -166,4 +173,7 @@ "VisualizerOverrides", "VisualizerOverridesBatch", "VisualizerOverridesType", + "ZoomLevel", + "ZoomLevelBatch", + "ZoomLevelType", ] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/map_provider.py b/rerun_py/rerun_sdk/rerun/blueprint/components/map_provider.py new file mode 100644 index 000000000000..30fe170506cd --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/map_provider.py @@ -0,0 +1,106 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/blueprint/components/map_provider.fbs". + +# You can extend this class by creating a "MapProviderExt" class in "map_provider_ext.py". + +from __future__ import annotations + +from typing import Literal, Sequence, Union + +import pyarrow as pa + +from ..._baseclasses import ( + BaseBatch, + BaseExtensionType, + ComponentBatchMixin, +) + +__all__ = ["MapProvider", "MapProviderArrayLike", "MapProviderBatch", "MapProviderLike", "MapProviderType"] + + +from enum import Enum + + +class MapProvider(Enum): + """**Component**: Name of the map provider to be used in Map views.""" + + OpenStreetMap = 1 + """`OpenStreetMap` is the default map provider.""" + + MapboxStreets = 2 + """ + Mapbox Streets is a minimalistic map designed by Mapbox. + + **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + """ + + MapboxDark = 3 + """ + Mapbox Dark is a dark-themed map designed by Mapbox. + + **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + """ + + MapboxSatellite = 4 + """ + Mapbox Satellite is a satellite map designed by Mapbox. + + **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + """ + + @classmethod + def auto(cls, val: str | int | MapProvider) -> MapProvider: + """Best-effort converter, including a case-insensitive string matcher.""" + if isinstance(val, MapProvider): + return val + if isinstance(val, int): + return cls(val) + try: + return cls[val] + except KeyError: + val_lower = val.lower() + for variant in cls: + if variant.name.lower() == val_lower: + return variant + raise ValueError(f"Cannot convert {val} to {cls.__name__}") + + def __str__(self) -> str: + """Returns the variant name.""" + return self.name + + +MapProviderLike = Union[ + MapProvider, + Literal[ + "MapboxDark", + "MapboxSatellite", + "MapboxStreets", + "OpenStreetMap", + "mapboxdark", + "mapboxsatellite", + "mapboxstreets", + "openstreetmap", + ], + int, +] +MapProviderArrayLike = Union[MapProviderLike, Sequence[MapProviderLike]] + + +class MapProviderType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.components.MapProvider" + + def __init__(self) -> None: + pa.ExtensionType.__init__(self, pa.uint8(), self._TYPE_NAME) + + +class MapProviderBatch(BaseBatch[MapProviderArrayLike], ComponentBatchMixin): + _ARROW_TYPE = MapProviderType() + + @staticmethod + def _native_to_pa_array(data: MapProviderArrayLike, data_type: pa.DataType) -> pa.Array: + if isinstance(data, (MapProvider, int, str)): + data = [data] + + pa_data = [MapProvider.auto(v).value if v is not None else None for v in data] # type: ignore[redundant-expr] + + return pa.array(pa_data, type=data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/zoom_level.py b/rerun_py/rerun_sdk/rerun/blueprint/components/zoom_level.py new file mode 100644 index 000000000000..ad6f066c0d18 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/zoom_level.py @@ -0,0 +1,36 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/blueprint/components/zoom_level.fbs". + +# You can extend this class by creating a "ZoomLevelExt" class in "zoom_level_ext.py". + +from __future__ import annotations + +from ... import datatypes +from ..._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["ZoomLevel", "ZoomLevelBatch", "ZoomLevelType"] + + +class ZoomLevel(datatypes.Float32, ComponentMixin): + """**Component**: A zoom level determines how much of the world is visible on a map.""" + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of ZoomLevelExt in zoom_level_ext.py + + # Note: there are no fields here because ZoomLevel delegates to datatypes.Float32 + pass + + +class ZoomLevelType(datatypes.Float32Type): + _TYPE_NAME: str = "rerun.blueprint.components.ZoomLevel" + + +class ZoomLevelBatch(datatypes.Float32Batch, ComponentBatchMixin): + _ARROW_TYPE = ZoomLevelType() + + +# This is patched in late to avoid circular dependencies. +ZoomLevel._BATCH_TYPE = ZoomLevelBatch # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/views/.gitattributes index 75df45e0a870..b95c2652ca07 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/views/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/.gitattributes @@ -4,6 +4,7 @@ __init__.py linguist-generated=true bar_chart_view.py linguist-generated=true dataframe_view.py linguist-generated=true +map_view.py linguist-generated=true spatial2d_view.py linguist-generated=true spatial3d_view.py linguist-generated=true tensor_view.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/views/__init__.py index c2aee9b89942..992739f85bd3 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/views/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/__init__.py @@ -4,6 +4,7 @@ from .bar_chart_view import BarChartView from .dataframe_view import DataframeView +from .map_view import MapView from .spatial2d_view import Spatial2DView from .spatial3d_view import Spatial3DView from .tensor_view import TensorView @@ -14,6 +15,7 @@ __all__ = [ "BarChartView", "DataframeView", + "MapView", "Spatial2DView", "Spatial3DView", "TensorView", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/map_view.py b/rerun_py/rerun_sdk/rerun/blueprint/views/map_view.py new file mode 100644 index 000000000000..19ec551472d6 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/map_view.py @@ -0,0 +1,118 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/blueprint/views/map.fbs". + +from __future__ import annotations + +from typing import Union + +__all__ = ["MapView"] + + +from ... import datatypes +from ..._baseclasses import AsComponents, ComponentBatchLike +from ...datatypes import EntityPathLike, Utf8Like +from .. import archetypes as blueprint_archetypes +from ..api import SpaceView, SpaceViewContentsLike + + +class MapView(SpaceView): + """ + **View**: A 2D map view to display geospatial primitives. + + Example + ------- + ### Use a blueprint to create a map view.: + ```python + import rerun as rr + import rerun.blueprint as rrb + + rr.init("rerun_example_map_view", spawn=True) + + rr.log("points", rr.GeoPoints([[47.6344, 19.1397], [47.6334, 19.1399]])) + + # Create a map view to display the chart. + # TODO(#7903): cleanup the blueprint API for the map view + blueprint = rrb.Blueprint( + rrb.MapView( + origin="points", + name="MapView", + zoom=rrb.archetypes.MapZoom(16.0), + background=rrb.archetypes.MapBackground(rrb.components.MapProvider.OpenStreetMap), + ), + collapse_panels=True, + ) + + rr.send_blueprint(blueprint) + ``` + + """ + + def __init__( + self, + *, + origin: EntityPathLike = "/", + contents: SpaceViewContentsLike = "$origin/**", + name: Utf8Like | None = None, + visible: datatypes.BoolLike | None = None, + defaults: list[Union[AsComponents, ComponentBatchLike]] = [], + overrides: dict[EntityPathLike, list[ComponentBatchLike]] = {}, + zoom: blueprint_archetypes.MapZoom | None = None, + background: blueprint_archetypes.MapBackground | None = None, + ) -> None: + """ + Construct a blueprint for a new MapView view. + + Parameters + ---------- + origin: + The `EntityPath` to use as the origin of this view. + All other entities will be transformed to be displayed relative to this origin. + contents: + The contents of the view specified as a query expression. + This is either a single expression, or a list of multiple expressions. + See [rerun.blueprint.archetypes.SpaceViewContents][]. + name: + The display name of the view. + visible: + Whether this view is visible. + + Defaults to true if not specified. + defaults: + List of default components or component batches to add to the space view. When an archetype + in the view is missing a component included in this set, the value of default will be used + instead of the normal fallback for the visualizer. + overrides: + Dictionary of overrides to apply to the space view. The key is the path to the entity where the override + should be applied. The value is a list of component or component batches to apply to the entity. + + Important note: the path must be a fully qualified entity path starting at the root. The override paths + do not yet support `$origin` relative paths or glob expressions. + This will be addressed in . + zoom: + Configures the zoom level of the map view. + background: + Configuration for the background map of the map view. + + """ + + properties: dict[str, AsComponents] = {} + if zoom is not None: + if not isinstance(zoom, blueprint_archetypes.MapZoom): + zoom = blueprint_archetypes.MapZoom(zoom) + properties["MapZoom"] = zoom + + if background is not None: + if not isinstance(background, blueprint_archetypes.MapBackground): + background = blueprint_archetypes.MapBackground(background) + properties["MapBackground"] = background + + super().__init__( + class_identifier="Map", + origin=origin, + contents=contents, + name=name, + visible=visible, + properties=properties, + defaults=defaults, + overrides=overrides, + ) diff --git a/rerun_py/rerun_sdk/rerun/components/.gitattributes b/rerun_py/rerun_sdk/rerun/components/.gitattributes index 6541e94fa6eb..19b08d9c70aa 100644 --- a/rerun_py/rerun_sdk/rerun/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/components/.gitattributes @@ -24,6 +24,7 @@ image_buffer.py linguist-generated=true image_format.py linguist-generated=true image_plane_distance.py linguist-generated=true keypoint_id.py linguist-generated=true +lat_lon.py linguist-generated=true line_strip2d.py linguist-generated=true line_strip3d.py linguist-generated=true magnification_filter.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/components/__init__.py b/rerun_py/rerun_sdk/rerun/components/__init__.py index 7fa9bf8b8c02..89bf4caad67c 100644 --- a/rerun_py/rerun_sdk/rerun/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/components/__init__.py @@ -36,6 +36,7 @@ from .image_format import ImageFormat, ImageFormatBatch, ImageFormatType from .image_plane_distance import ImagePlaneDistance, ImagePlaneDistanceBatch, ImagePlaneDistanceType from .keypoint_id import KeypointId, KeypointIdBatch, KeypointIdType +from .lat_lon import LatLon, LatLonBatch, LatLonType from .line_strip2d import LineStrip2D, LineStrip2DArrayLike, LineStrip2DBatch, LineStrip2DLike, LineStrip2DType from .line_strip3d import LineStrip3D, LineStrip3DArrayLike, LineStrip3DBatch, LineStrip3DLike, LineStrip3DType from .magnification_filter import ( @@ -169,6 +170,9 @@ "KeypointId", "KeypointIdBatch", "KeypointIdType", + "LatLon", + "LatLonBatch", + "LatLonType", "LineStrip2D", "LineStrip2DArrayLike", "LineStrip2DBatch", diff --git a/rerun_py/rerun_sdk/rerun/components/lat_lon.py b/rerun_py/rerun_sdk/rerun/components/lat_lon.py new file mode 100644 index 000000000000..2777c2737dea --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/components/lat_lon.py @@ -0,0 +1,36 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/components/latlon.fbs". + +# You can extend this class by creating a "LatLonExt" class in "lat_lon_ext.py". + +from __future__ import annotations + +from .. import datatypes +from .._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["LatLon", "LatLonBatch", "LatLonType"] + + +class LatLon(datatypes.DVec2D, ComponentMixin): + """**Component**: A geographical position expressed in EPSG:4326 latitude and longitude.""" + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of LatLonExt in lat_lon_ext.py + + # Note: there are no fields here because LatLon delegates to datatypes.DVec2D + pass + + +class LatLonType(datatypes.DVec2DType): + _TYPE_NAME: str = "rerun.components.LatLon" + + +class LatLonBatch(datatypes.DVec2DBatch, ComponentBatchMixin): + _ARROW_TYPE = LatLonType() + + +# This is patched in late to avoid circular dependencies. +LatLon._BATCH_TYPE = LatLonBatch # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes index 4181907f6192..8f23c5dee36a 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes @@ -11,6 +11,7 @@ class_description.py linguist-generated=true class_description_map_elem.py linguist-generated=true class_id.py linguist-generated=true color_model.py linguist-generated=true +dvec2d.py linguist-generated=true entity_path.py linguist-generated=true float32.py linguist-generated=true float64.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py index 3521f94f07d9..ada89d7b2531 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py @@ -35,6 +35,7 @@ ) from .class_id import ClassId, ClassIdArrayLike, ClassIdBatch, ClassIdLike, ClassIdType from .color_model import ColorModel, ColorModelArrayLike, ColorModelBatch, ColorModelLike, ColorModelType +from .dvec2d import DVec2D, DVec2DArrayLike, DVec2DBatch, DVec2DLike, DVec2DType from .entity_path import EntityPath, EntityPathArrayLike, EntityPathBatch, EntityPathLike, EntityPathType from .float32 import Float32, Float32ArrayLike, Float32Batch, Float32Like, Float32Type from .float64 import Float64, Float64ArrayLike, Float64Batch, Float64Like, Float64Type @@ -166,6 +167,11 @@ "ColorModelBatch", "ColorModelLike", "ColorModelType", + "DVec2D", + "DVec2DArrayLike", + "DVec2DBatch", + "DVec2DLike", + "DVec2DType", "EntityPath", "EntityPathArrayLike", "EntityPathBatch", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/dvec2d.py b/rerun_py/rerun_sdk/rerun/datatypes/dvec2d.py new file mode 100644 index 000000000000..07a41155af50 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/datatypes/dvec2d.py @@ -0,0 +1,68 @@ +# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/store/re_types/definitions/rerun/datatypes/dvec2d.fbs". + +# You can extend this class by creating a "DVec2DExt" class in "dvec2d_ext.py". + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Sequence, Union + +import numpy as np +import numpy.typing as npt +import pyarrow as pa +from attrs import define, field + +from .._baseclasses import ( + BaseBatch, + BaseExtensionType, +) +from .._converters import ( + to_np_float64, +) +from .dvec2d_ext import DVec2DExt + +__all__ = ["DVec2D", "DVec2DArrayLike", "DVec2DBatch", "DVec2DLike", "DVec2DType"] + + +@define(init=False) +class DVec2D(DVec2DExt): + """**Datatype**: A double-precision vector in 2D space.""" + + def __init__(self: Any, xy: DVec2DLike): + """Create a new instance of the DVec2D datatype.""" + + # You can define your own __init__ function as a member of DVec2DExt in dvec2d_ext.py + self.__attrs_init__(xy=xy) + + xy: npt.NDArray[np.float64] = field(converter=to_np_float64) + + def __array__(self, dtype: npt.DTypeLike = None) -> npt.NDArray[Any]: + # You can define your own __array__ function as a member of DVec2DExt in dvec2d_ext.py + return np.asarray(self.xy, dtype=dtype) + + +if TYPE_CHECKING: + DVec2DLike = Union[DVec2D, npt.NDArray[Any], npt.ArrayLike, Sequence[float]] +else: + DVec2DLike = Any + +DVec2DArrayLike = Union[ + DVec2D, Sequence[DVec2DLike], npt.NDArray[Any], npt.ArrayLike, Sequence[Sequence[float]], Sequence[float] +] + + +class DVec2DType(BaseExtensionType): + _TYPE_NAME: str = "rerun.datatypes.DVec2D" + + def __init__(self) -> None: + pa.ExtensionType.__init__( + self, pa.list_(pa.field("item", pa.float64(), nullable=False, metadata={}), 2), self._TYPE_NAME + ) + + +class DVec2DBatch(BaseBatch[DVec2DArrayLike]): + _ARROW_TYPE = DVec2DType() + + @staticmethod + def _native_to_pa_array(data: DVec2DArrayLike, data_type: pa.DataType) -> pa.Array: + return DVec2DExt.native_to_pa_array_override(data, data_type) diff --git a/rerun_py/rerun_sdk/rerun/datatypes/dvec2d_ext.py b/rerun_py/rerun_sdk/rerun/datatypes/dvec2d_ext.py new file mode 100644 index 000000000000..e92d9cf60e97 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/datatypes/dvec2d_ext.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Sequence + +import numpy as np +import pyarrow as pa + +from .._validators import flat_np_float64_array_from_array_like + +if TYPE_CHECKING: + from . import DVec2DArrayLike + +NUMPY_VERSION = tuple(map(int, np.version.version.split(".")[:2])) + + +class DVec2DExt: + """Extension for [DVec2D][rerun.datatypes.DVec2D].""" + + @staticmethod + def native_to_pa_array_override(data: DVec2DArrayLike, data_type: pa.DataType) -> pa.Array: + # TODO(ab): get rid of this once we drop support for Python 3.8. Make sure to pin numpy>=1.25. + if NUMPY_VERSION < (1, 25): + # Older numpy doesn't seem to support `data` in the form of [Point3D(1, 2), Point3D(3, 4)] + # this happens for python 3.8 (1.25 supports 3.9+) + from . import DVec2D + + if isinstance(data, Sequence): + data = [np.array(p.xy) if isinstance(p, DVec2D) else p for p in data] + + points = flat_np_float64_array_from_array_like(data, 2) + return pa.FixedSizeListArray.from_arrays(points, type=data_type) diff --git a/tests/python/release_checklist/check_all_components_ui.py b/tests/python/release_checklist/check_all_components_ui.py index 9d2f17ad221d..a1db03894aaa 100644 --- a/tests/python/release_checklist/check_all_components_ui.py +++ b/tests/python/release_checklist/check_all_components_ui.py @@ -140,6 +140,7 @@ def alternatives(self) -> list[Any] | None: ), "ImagePlaneDistanceBatch": TestCase(batch=[100.0, 200.0, 300.0]), "KeypointIdBatch": TestCase(batch=[5, 6, 7]), + "LatLonBatch": TestCase(batch=[(0, 1), (2, 3), (4, 5)]), "LineStrip2DBatch": TestCase( batch=[ ((0, 0), (1, 1), (2, 2)),