From 40dbb6b8a89f189f4307d84895c95356cddf3169 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 24 Jan 2024 17:14:26 -0500 Subject: [PATCH] update docs --- .../layer-extensions/data-filter-extension.md | 6 + docs/api/layer-extensions/index.md | 9 + lonboard/experimental/layer_extension.py | 199 +++++++++--------- mkdocs.yml | 21 +- 4 files changed, 134 insertions(+), 101 deletions(-) create mode 100644 docs/api/layer-extensions/data-filter-extension.md create mode 100644 docs/api/layer-extensions/index.md diff --git a/docs/api/layer-extensions/data-filter-extension.md b/docs/api/layer-extensions/data-filter-extension.md new file mode 100644 index 00000000..b95eec94 --- /dev/null +++ b/docs/api/layer-extensions/data-filter-extension.md @@ -0,0 +1,6 @@ +# DataFilterExtension + +::: lonboard.experimental.DataFilterExtension + options: + show_bases: false + inherited_members: true diff --git a/docs/api/layer-extensions/index.md b/docs/api/layer-extensions/index.md new file mode 100644 index 00000000..01b60c06 --- /dev/null +++ b/docs/api/layer-extensions/index.md @@ -0,0 +1,9 @@ +# Layer Extensions + +Layer extensions are bonus features that you can optionally add to the core deck.gl layers. + +Layer extensions are in an experimental state. Some things are known to not yet work: + +- Modifying the extensions on a layer by mutating its `extensions` list via `append` or `pop`. It should work, however, by creating a new list and assigning `layer.extensions = new_extensions_list`. + +If you encounter issues, please [create an issue](https://github.com/developmentseed/lonboard/issues/new) with reproducible steps. diff --git a/lonboard/experimental/layer_extension.py b/lonboard/experimental/layer_extension.py index 6ee5b967..865abb72 100644 --- a/lonboard/experimental/layer_extension.py +++ b/lonboard/experimental/layer_extension.py @@ -8,28 +8,21 @@ class BrushingExtension(BaseExtension): """ Adds GPU-based data brushing functionalities to layers. It allows the layer to show/hide objects based on the current pointer position. - """ - _extension_type = traitlets.Unicode("brushing").tag(sync=True) + # Layer Properties - _layer_traits = { - "brushing_enabled": traitlets.Bool(True).tag(sync=True), - "brushing_target": traitlets.Unicode("source", allow_none=True).tag(sync=True), - "brushing_radius": traitlets.Float(allow_none=True, min=0).tag(sync=True), - # TODO: update trait - "get_brushing_target": traitlets.Any(allow_none=True).tag(sync=True), - } + This extension dynamically enables the following properties onto the layer(s) where + it is included: + + ## `brushing_enabled` - # brushing_enabled = traitlets.Bool(True).tag(sync=True) - """ Enable/disable brushing. If brushing is disabled, all objects are rendered. - Type: `bool`, optional - Default: `True` - """ - # brushing_target = traitlets.Unicode("source", allow_none=True).tag(sync=True) - """ + ## `brushing_target` + The position used to filter each object by. - Type: `str`, optional @@ -38,17 +31,28 @@ class BrushingExtension(BaseExtension): - Default: `10000` - """ + ## `brushing_radius` - # brushing_radius = traitlets.Float(allow_none=True, min=0).tag(sync=True) - """ The brushing radius centered at the pointer, in meters. If a data object is within this circle, it is rendered; otherwise it is hidden. - Type: `float`, optional - Default: `10000` + + An example is in the [County-to-County Migration + notebook](https://developmentseed.org/lonboard/latest/examples/migration/). """ + _extension_type = traitlets.Unicode("brushing").tag(sync=True) + + _layer_traits = { + "brushing_enabled": traitlets.Bool(True).tag(sync=True), + "brushing_target": traitlets.Unicode("source", allow_none=True).tag(sync=True), + "brushing_radius": traitlets.Float(allow_none=True, min=0).tag(sync=True), + # TODO: Add trait and support + # "get_brushing_target": traitlets.Any(allow_none=True).tag(sync=True), + } + # TODO: update trait # get_brushing_target = traitlets.Any(allow_none=True).tag(sync=True) """ @@ -60,39 +64,30 @@ class BrushingExtension(BaseExtension): class CollisionFilterExtension(BaseExtension): - """Allows layers to hide overlapping objects.""" + """Allows layers to hide overlapping objects. - _extension_type = traitlets.Unicode("collision-filter").tag(sync=True) + # Layer Properties - _layer_traits = { - "collision_enabled": traitlets.Bool(True).tag(sync=True), - "collision_group": traitlets.Unicode().tag(sync=True), - "get_collision_priority": FloatAccessor(allow_none=True), - } + This extension dynamically enables the following properties onto the layer(s) where + it is included: - # /** - # * Props to override when rendering collision map - # */ - # collisionTestProps?: {}; + ## `collision_enabled` - # collision_enabled = traitlets.Bool(True).tag(sync=True) - """Enable/disable collisions. If collisions are disabled, all objects are rendered. + Enable/disable collisions. If collisions are disabled, all objects are rendered. - Type: `bool`, optional - Default: `True` - """ - # collision_group = traitlets.Unicode().tag(sync=True) - """ + ## `collision_group` + Collision group this layer belongs to. If it is not set, the 'default' collision group is used - - Type: `string`, optional + - Type: `str`, optional - Default: `None` - """ - # get_collision_priority = FloatAccessor(allow_none=True) - """ + ## `get_collision_priority` + Accessor for collision priority. Must return a number in the range -1000 -> 1000. Features with higher values are shown preferentially. @@ -101,82 +96,63 @@ class CollisionFilterExtension(BaseExtension): - If an array is provided, each value in the array will be used as the priority for the object at the same row index. - Default: `0`. + """ + _extension_type = traitlets.Unicode("collision-filter").tag(sync=True) + + _layer_traits = { + "collision_enabled": traitlets.Bool(True).tag(sync=True), + "collision_group": traitlets.Unicode().tag(sync=True), + "get_collision_priority": FloatAccessor(allow_none=True), + } + class DataFilterExtension(BaseExtension): """ Adds GPU-based data filtering functionalities to layers. It allows the layer to show/hide objects based on user-defined properties. - ### Layer Parameters - + # Example + + ```py + from lonboard import Map, ScatterplotLayer + from lonboard.colormap import apply_continuous_cmap + from lonboard.experimental import DataFilterExtension + + gdf = gpd.GeoDataFrame(...) + extension = DataFilterExtension() + layer = ScatterplotLayer.from_geopandas( + gdf, + extensions=[extension], + get_filter_value=gdf["filter_value"], # replace with desired column + filter_range=[0, 5] # replace with desired filter range + ) ``` - get_filter_value = FloatAccessor(None, allow_none=False) - ``` - - Accessor to retrieve the value for each object that it will be filtered by. - - - Type: [FloatAccessor][lonboard.traits.FloatAccessor] - - If a number is provided, it is used as the value for all objects. - - If an array is provided, each value in the array will be used as the value - for the object at the same row index. - """ - - _extension_type = traitlets.Unicode("data-filter").tag(sync=True) - - _layer_traits = { - "filter_enabled": traitlets.Bool(True).tag(sync=True), - "filter_range": traitlets.Tuple( - traitlets.Float(), traitlets.Float(), default_value=(-1, 1) - ).tag(sync=True), - "filter_soft_range": traitlets.Tuple( - traitlets.Float(), traitlets.Float(), default_value=None, allow_none=True - ).tag(sync=True), - "filter_transform_size": traitlets.Bool(True).tag(sync=True), - "filter_transform_color": traitlets.Bool(True).tag(sync=True), - "get_filter_value": FloatAccessor(None, allow_none=False), - } - - # TODO: support filterSize > 1 - # In order to support filterSize > 1, we need to allow the get_filter_value accessor - # to be either a single float or a fixed size list of up to 4 floats. - - # filter_size = traitlets.Int(1).tag(sync=True) - """The size of the filter (number of columns to filter by). - The data filter can show/hide data based on 1-4 numeric properties of each object. + # Layer Properties - - Type: `int`, optional - - Default 1. - """ + ## `filter_enabled` - # TODO: document in constructor and then remove. - # filter_enabled = traitlets.Bool(True).tag(sync=True) - """ Enable/disable the data filter. If the data filter is disabled, all objects are rendered. - Type: `bool`, optional - Default: `True` - """ - # filter_range = traitlets.Tuple( - # traitlets.Float(), traitlets.Float(), default_value=(-1, 1) - # ).tag(sync=True) - """The (min, max) bounds which defines whether an object should be rendered. + ## `filter_range` + + The (min, max) bounds which defines whether an object should be rendered. If an object's filtered value is within the bounds, the object will be rendered; otherwise it will be hidden. - Type: Tuple[float, float], optional - Default: `(-1, 1)` - """ - # filter_soft_range = traitlets.Tuple( - # traitlets.Float(), traitlets.Float(), default_value=None, allow_none=True - # ).tag(sync=True) - """If specified, objects will be faded in/out instead of abruptly shown/hidden. + ## `filter_soft_range` + + If specified, objects will be faded in/out instead of abruptly shown/hidden. When the filtered value is outside of the bounds defined by `filter_soft_range` but still within the bounds defined by `filter_range`, the object will be rendered as @@ -184,22 +160,57 @@ class DataFilterExtension(BaseExtension): - Type: Tuple[float, float], optional - Default: `None` - """ - # filter_transform_size = traitlets.Bool(True).tag(sync=True) - """ + ## `filter_transform_size` + When an object is "faded", manipulate its size so that it appears smaller or thinner. Only works if `filter_soft_range` is specified. - Type: `bool`, optional - Default: `True` - """ - # filter_transform_color = traitlets.Bool(True).tag(sync=True) - """ + ## `filter_transform_color` + When an object is "faded", manipulate its opacity so that it appears more translucent. Only works if `filter_soft_range` is specified. - Type: `bool`, optional - Default: `True` + + ## `get_filter_value` + + Accessor to retrieve the value for each object that it will be filtered by. + + - Type: [FloatAccessor][lonboard.traits.FloatAccessor] + - If a number is provided, it is used as the value for all objects. + - If an array is provided, each value in the array will be used as the value + for the object at the same row index. + """ + + _extension_type = traitlets.Unicode("data-filter").tag(sync=True) + + _layer_traits = { + "filter_enabled": traitlets.Bool(True).tag(sync=True), + "filter_range": traitlets.Tuple( + traitlets.Float(), traitlets.Float(), default_value=(-1, 1) + ).tag(sync=True), + "filter_soft_range": traitlets.Tuple( + traitlets.Float(), traitlets.Float(), default_value=None, allow_none=True + ).tag(sync=True), + "filter_transform_size": traitlets.Bool(True).tag(sync=True), + "filter_transform_color": traitlets.Bool(True).tag(sync=True), + "get_filter_value": FloatAccessor(None, allow_none=False), + } + + # TODO: support filterSize > 1 + # In order to support filterSize > 1, we need to allow the get_filter_value accessor + # to be either a single float or a fixed size list of up to 4 floats. + + # filter_size = traitlets.Int(1).tag(sync=True) + """The size of the filter (number of columns to filter by). + + The data filter can show/hide data based on 1-4 numeric properties of each object. + + - Type: `int`, optional + - Default 1. """ diff --git a/mkdocs.yml b/mkdocs.yml index 6898356a..2db84667 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,13 +46,15 @@ nav: - api/colormap.md - api/traits.md - Experimental: - - Layer Extensions: - - api/layer-extensions/brushing-extension.md - - api/layer-extensions/collision-filter-extension.md - - Layers: - - api/layers/arc-layer.md - - api/layers/text-layer.md - - api/experimental/traits.md + - Layer Extensions: + - api/layer-extensions/index.md + - api/layer-extensions/brushing-extension.md + - api/layer-extensions/collision-filter-extension.md + - api/layer-extensions/data-filter-extension.md + - Layers: + - api/layers/arc-layer.md + - api/layers/text-layer.md + - api/experimental/traits.md # - Caveats: caveats.md - Performance: performance.md @@ -60,6 +62,11 @@ nav: - Alternatives: alternatives.md - "How it works?": how-it-works.md + # - Ecosystem: + # - ecosystem/index.md + # - ecosystem/geopandas.md + # - ecosystem/geoarrow.md + watch: - lonboard - docs