From 3c0f7678fbf7604d0c8e3961e925585ce7e3d2ac Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 17 Oct 2023 18:16:38 -0400 Subject: [PATCH] Improved api docs (#128) --- docs/api/layers/path-layer.md | 11 ++ docs/api/layers/scatterplot-layer.md | 11 ++ docs/api/layers/solid-polygon-layer.md | 19 ++++ docs/api/traits.md | 5 + docs/api/{top-level.md => viz.md} | 8 +- docs/layers/path-layer.md | 93 --------------- docs/layers/scatterplot-layer.md | 152 ------------------------- docs/layers/solid-polygon-layer.md | 98 ---------------- lonboard/layer.py | 132 ++++++++++++++++++++- lonboard/traits.py | 41 +++++-- mkdocs.yml | 30 ++--- 11 files changed, 223 insertions(+), 377 deletions(-) create mode 100644 docs/api/layers/path-layer.md create mode 100644 docs/api/layers/scatterplot-layer.md create mode 100644 docs/api/layers/solid-polygon-layer.md create mode 100644 docs/api/traits.md rename docs/api/{top-level.md => viz.md} (58%) delete mode 100644 docs/layers/path-layer.md delete mode 100644 docs/layers/scatterplot-layer.md delete mode 100644 docs/layers/solid-polygon-layer.md diff --git a/docs/api/layers/path-layer.md b/docs/api/layers/path-layer.md new file mode 100644 index 00000000..8ef441ee --- /dev/null +++ b/docs/api/layers/path-layer.md @@ -0,0 +1,11 @@ +# PathLayer + +The `PathLayer` renders lists of coordinate points as extruded polylines with mitering. + +![](../../assets/path-layer-roads.jpg) + +> Screenshot from North America roads example + +::: lonboard.PathLayer + options: + show_bases: false diff --git a/docs/api/layers/scatterplot-layer.md b/docs/api/layers/scatterplot-layer.md new file mode 100644 index 00000000..29ecb54f --- /dev/null +++ b/docs/api/layers/scatterplot-layer.md @@ -0,0 +1,11 @@ +# ScatterplotLayer + +The `ScatterplotLayer` renders circles at given coordinates. + +![](../../assets/scatterplot-layer-network-speeds.jpg) + +> Screenshot from Ookla example. + +::: lonboard.ScatterplotLayer + options: + show_bases: false diff --git a/docs/api/layers/solid-polygon-layer.md b/docs/api/layers/solid-polygon-layer.md new file mode 100644 index 00000000..5353298f --- /dev/null +++ b/docs/api/layers/solid-polygon-layer.md @@ -0,0 +1,19 @@ +# SolidPolygonLayer + +The `SolidPolygonLayer` renders filled and/or extruded polygons. + +```py +import geopandas as gpd +from lonboard import SolidPolygonLayer + +# A GeoDataFrame with Polygon geometries +gdf = gpd.GeoDataFrame() +layer = SolidPolygonLayer.from_geopandas( + gdf, + get_fill_color=[255, 0, 0], +) +``` + +::: lonboard.SolidPolygonLayer + options: + show_bases: false diff --git a/docs/api/traits.md b/docs/api/traits.md new file mode 100644 index 00000000..24f0eccb --- /dev/null +++ b/docs/api/traits.md @@ -0,0 +1,5 @@ +# lonboard.traits + +::: lonboard.traits.ColorAccessor + +::: lonboard.traits.FloatAccessor diff --git a/docs/api/top-level.md b/docs/api/viz.md similarity index 58% rename from docs/api/top-level.md rename to docs/api/viz.md index a027ad78..5ea6713a 100644 --- a/docs/api/top-level.md +++ b/docs/api/viz.md @@ -2,12 +2,8 @@ The top-level namespace accessible after `import lonboard`. +Layers are also accessible in the top-level namespace, but are documented in the `layers/` folder. + ::: lonboard.viz.viz options: show_root_full_path: false - -::: lonboard.ScatterplotLayer - -::: lonboard.PathLayer - -::: lonboard.SolidPolygonLayer diff --git a/docs/layers/path-layer.md b/docs/layers/path-layer.md deleted file mode 100644 index afb0a1d0..00000000 --- a/docs/layers/path-layer.md +++ /dev/null @@ -1,93 +0,0 @@ -# PathLayer - -The `PathLayer` renders lists of coordinate points as extruded polylines with mitering. - -![](../assets/path-layer-roads.jpg) - -> Screenshot from North America roads example - -## Properties - - - -### Render Options - -#### `width_units` - -- Type: `str`, optional -- Default: `'meters'` - -The units of the line width, one of `'meters'`, `'common'`, and `'pixels'`. See [unit system](https://deck.gl/docs/developer-guide/coordinate-systems#supported-units). - -#### `width_scale` - -- Type: `float`, optional -- Default: `1` - -The path width multiplier that multiplied to all paths. - -#### `width_min_pixels` - -- Type: `float`, optional -- Default: `0` - -The minimum path width in pixels. This prop can be used to prevent the path from getting too thin when zoomed out. - -#### `width_max_pixels` - -- Type: `float`, optional -- Default: `None` - -The maximum path width in pixels. This prop can be used to prevent the path from getting too thick when zoomed in. - -#### `cap_rounded` - -- Type: `bool`, optional -- Default: `False` - -Type of caps. If `True`, draw round caps. Otherwise draw square caps. - -#### `joint_rounded` - -- Type: `bool`, optional -- Default: `False` - -Type of joint. If `True`, draw round joints. Otherwise draw miter joints. - -#### `billboard` - -- Type: `bool`, optional -- Default: `False` - -If `True`, extrude the path in screen space (width always faces the camera). -If `False`, the width always faces up. - -#### `miter_limit` - -- Type: `float`, optional -- Default: `4` - -The maximum extent of a joint in ratio to the stroke width. -Only works if `jointRounded` is `False`. - -### Data Accessors - -#### `get_color` - -- Type: Array, optional -- Default `[0, 0, 0, 255]` - -The rgba color of each object, in `r, g, b, [a]`. Each component is in the 0-255 range. - -- If an array is provided, it is used as the color for all objects. -- If a function is provided, it is called on each object to retrieve its color. - -#### `get_width` - -- Type: Number, optional -- Default: `1` - -The width of each path, in units specified by `width_units` (default `'meters'`). - -- If a number is provided, it is used as the width for all paths. -- If a function is provided, it is called on each path to retrieve its width. diff --git a/docs/layers/scatterplot-layer.md b/docs/layers/scatterplot-layer.md deleted file mode 100644 index 2cc3c839..00000000 --- a/docs/layers/scatterplot-layer.md +++ /dev/null @@ -1,152 +0,0 @@ -# ScatterplotLayer - -The `ScatterplotLayer` renders circles at given coordinates. - -![](../assets/scatterplot-layer-network-speeds.jpg) - -> Screenshot from Ookla example. - -```py -import geopandas as gpd -from lonboard import ScatterplotLayer - -# A GeoDataFrame with Point geometries -gdf = gpd.GeoDataFrame() -layer = ScatterplotLayer.from_geopandas( - gdf, - get_fill_color=[255, 0, 0], -) -``` - -## Properties - - - -### Render Options - -#### `radius_units` - -- Type: `str`, optional -- Default: `'meters'` - -The units of the radius, one of `'meters'`, `'common'`, and `'pixels'`. See [unit system](https://deck.gl/docs/developer-guide/coordinate-systems#supported-units). - -#### `radius_scale` - -- Type: `float`, optional -- Default: `1` - -A global radius multiplier for all points. - -#### `line_width_units` - -- Type: `str`, optional -- Default: `'meters'` - -The units of the line width, one of `'meters'`, `'common'`, and `'pixels'`. See [unit system](https://deck.gl/docs/developer-guide/coordinate-systems#supported-units). - -#### `line_width_scale` - -- Type: `float`, optional -- Default: `1` - -A global line width multiplier for all points. - -#### `stroked` - -- Type: `bool`, optional -- Default: `False` - -Draw the outline of points. - -#### `filled` - -- Type: `bool`, optional -- Default: `True` - -Draw the filled area of points. - -#### `radius_min_pixels` - -- Type: `float`, optional -- Default: `0` - -The minimum radius in pixels. This can be used to prevent the circle from getting too small when zoomed out. - -#### `radius_max_pixels` - -- Type: `float`, optional -- Default: `None` - -The maximum radius in pixels. This can be used to prevent the circle from getting too big when zoomed in. - -#### `line_width_min_pixels` - -- Type: `float`, optional -- Default: `0` - -The minimum line width in pixels. This can be used to prevent the stroke from getting too thin when zoomed out. - -#### `line_width_max_pixels` - -- Type: `float`, optional -- Default: `None` - -The maximum line width in pixels. This can be used to prevent the stroke from getting too thick when zoomed in. - -#### `billboard` - -- Type: `bool`, optional -- Default: `False` - -If `True`, rendered circles always face the camera. If `False` circles face up (i.e. are parallel with the ground plane). - -#### `antialiasing` - -- Type: `bool`, optional -- Default: `True` - -If `True`, circles are rendered with smoothed edges. If `False`, circles are rendered with rough edges. Antialiasing can cause artifacts on edges of overlapping circles. - -### Data Accessors - -#### `get_radius` - -- Type: (Number, optional) -- Default: `1` - -The radius of each object, in units specified by `radius_units` (default `'meters'`). - -- If a number is provided, it is used as the radius for all objects. -- If a function is provided, it is called on each object to retrieve its radius. - -#### `get_fill_color` - -- Type: (Array, optional) -- Default: `[0, 0, 0, 255]` - -The rgba color is in the format of `[r, g, b, [a]]`. Each channel is a number between 0-255 and `a` is 255 if not supplied. - -- If an array is provided, it is used as the filled color for all objects. -- If a function is provided, it is called on each object to retrieve its color. - -#### `get_line_color` - -- Type: (Array, optional) -- Default: `[0, 0, 0, 255]` - -The rgba color is in the format of `[r, g, b, [a]]`. Each channel is a number between 0-255 and `a` is 255 if not supplied. - -- If an array is provided, it is used as the outline color for all objects. -- If a function is provided, it is called on each object to retrieve its color. - -#### `get_line_width` - -- Type: (Number, optional) -- Default: `1` - -The width of the outline of each object, in units specified by `line_width_units` (default `'meters'`). - -- If a number is provided, it is used as the outline width for all objects. -- If a function is provided, it is called on each object to retrieve its outline width. -- If not provided, it falls back to `stroke_width`. diff --git a/docs/layers/solid-polygon-layer.md b/docs/layers/solid-polygon-layer.md deleted file mode 100644 index 59aef579..00000000 --- a/docs/layers/solid-polygon-layer.md +++ /dev/null @@ -1,98 +0,0 @@ -# SolidPolygonLayer - -The `SolidPolygonLayer` renders filled and/or extruded polygons. - -```py -import geopandas as gpd -from lonboard import SolidPolygonLayer - -# A GeoDataFrame with Polygon geometries -gdf = gpd.GeoDataFrame() -layer = SolidPolygonLayer.from_geopandas( - gdf, - get_fill_color=[255, 0, 0], -) -``` - -## Properties - - - -### Render Options - -#### `filled` - -- Type: `bool`, optional -- Default: `True` - -Whether to fill the polygons (based on the color provided by the -`get_fill_color` accessor). - -#### `extruded` - -- Type: `bool`, optional -- Default: `False` - -Whether to extrude the polygons (based on the elevations provided by the -`get_elevation` accessor'). If set to `False`, all polygons will be flat, this -generates less geometry and is faster than simply returning `0` from `get_elevation`. - -#### `wireframe` - -- Type: `bool`, optional -- Default: `False` - -Whether to generate a line wireframe of the polygon. The outline will have -"horizontal" lines closing the top and bottom polygons and a vertical line -(a "strut") for each vertex on the polygon. - -#### `elevation_scale` - -- Type: `float`, optional -- Default: `1` - -Elevation multiplier. The final elevation is calculated by - `elevation_scale * get_elevation(d)`. `elevation_scale` is a handy property to scale -all elevation without updating the data. - -**Remarks:** - -- These lines are rendered with `GL.LINE` and will thus always be 1 pixel wide. -- Wireframe and solid extrusions are exclusive, you'll need to create two layers - with the same data if you want a combined rendering effect. - -### Data Accessors - -#### `get_fill_color` - -- Type: (Array, optional) -- Default: `[0, 0, 0, 255]` - -The rgba color is in the format of `[r, g, b, [a]]`. Each channel is a number between 0-255 and `a` is 255 if not supplied. - -- If an array is provided, it is used as the fill color for all polygons. -- If a function is provided, it is called on each polygon to retrieve its fill color. - -#### `get_line_color` - -- Type: (Array, optional) -- Default: `[0, 0, 0, 255]` - -The rgba color is in the format of `[r, g, b, [a]]`. Each channel is a number between 0-255 and `a` is 255 if not supplied. -Only applies if `extruded=True`. - -- If an array is provided, it is used as the stroke color for all polygons. -- If a function is provided, it is called on each object to retrieve its stroke color. - -#### `get_elevation` - -- Type: (Number, optional) -- Default: `1000` - -The elevation to extrude each polygon with. -If a cartographic projection mode is used, height will be interpreted as meters, -otherwise will be in unit coordinates. -Only applies if `extruded=True`. - -- If a number is provided, it is used as the elevation for all polygons. -- If a function is provided, it is called on each object to retrieve its elevation. diff --git a/lonboard/layer.py b/lonboard/layer.py index 73734b63..0d9c8b3f 100644 --- a/lonboard/layer.py +++ b/lonboard/layer.py @@ -36,7 +36,22 @@ class BaseLayer(AnyWidget): class ScatterplotLayer(BaseLayer): - """The `ScatterplotLayer` renders circles at given coordinates.""" + """The `ScatterplotLayer` renders circles at given coordinates. + + **Example:** + + ```py + import geopandas as gpd + from lonboard import ScatterplotLayer + + # A GeoDataFrame with Point geometries + gdf = gpd.GeoDataFrame() + layer = ScatterplotLayer.from_geopandas( + gdf, + get_fill_color=[255, 0, 0], + ) + ``` + """ _esm = bundler_output_dir / "scatterplot-layer.js" _layer_type = traitlets.Unicode("scatterplot").tag(sync=True) @@ -156,9 +171,54 @@ class ScatterplotLayer(BaseLayer): """ get_radius = FloatAccessor() + """ + The radius of each object, in units specified by `radius_units` (default + `'meters'`). + + - Type: [FloatAccessor][lonboard.traits.FloatAccessor], optional + - If a number is provided, it is used as the radius for all objects. + - If an array is provided, each value in the array will be used as the radius + for the object at the same row index. + - Default: `1`. + """ + get_fill_color = ColorAccessor() + """ + The filled color of each object in the format of `[r, g, b, [a]]`. Each channel is a + number between 0-255 and `a` is 255 if not supplied. + + - Type: [ColorAccessor][lonboard.traits.ColorAccessor], optional + - If a single `list` or `tuple` is provided, it is used as the filled color for + all objects. + - If a numpy or pyarrow array is provided, each value in the array will be used + as the filled color for the object at the same row index. + - Default: `[0, 0, 0, 255]`. + """ + get_line_color = ColorAccessor() + """ + The outline color of each object in the format of `[r, g, b, [a]]`. Each channel is + a number between 0-255 and `a` is 255 if not supplied. + + - Type: [ColorAccessor][lonboard.traits.ColorAccessor], optional + - If a single `list` or `tuple` is provided, it is used as the outline color + for all objects. + - If a numpy or pyarrow array is provided, each value in the array will be used + as the outline color for the object at the same row index. + - Default: `[0, 0, 0, 255]`. + """ + get_line_width = FloatAccessor() + """ + The width of the outline of each object, in units specified by `line_width_units` + (default `'meters'`). + + - Type: [FloatAccessor][lonboard.traits.FloatAccessor], optional + - If a number is provided, it is used as the outline width for all objects. + - If an array is provided, each value in the array will be used as the outline + width for the object at the same row index. + - Default: `1`. + """ @classmethod def from_geopandas(cls, gdf: gpd.GeoDataFrame, **kwargs) -> ScatterplotLayer: @@ -230,6 +290,11 @@ def _validate_get_line_width_length(self, proposal): class PathLayer(BaseLayer): + """ + The `PathLayer` renders lists of coordinate points as extruded polylines with + mitering. + """ + _esm = bundler_output_dir / "path-layer.js" _layer_type = traitlets.Unicode("path").tag(sync=True) _initial_view_state = traitlets.Dict().tag(sync=True) @@ -301,7 +366,6 @@ class PathLayer(BaseLayer): The maximum extent of a joint in ratio to the stroke width. Only works if `jointRounded` is `False`. - - Type: `float`, optional - Default: `4` """ @@ -316,7 +380,28 @@ class PathLayer(BaseLayer): """ get_color = ColorAccessor() + """ + The color of each path in the format of `[r, g, b, [a]]`. Each channel is a number + between 0-255 and `a` is 255 if not supplied. + + - Type: [ColorAccessor][lonboard.traits.ColorAccessor], optional + - If a single `list` or `tuple` is provided, it is used as the color for all + paths. + - If a numpy or pyarrow array is provided, each value in the array will be used + as the color for the path at the same row index. + - Default: `[0, 0, 0, 255]`. + """ + get_width = FloatAccessor() + """ + The width of each path, in units specified by `width_units` (default `'meters'`). + + - Type: [FloatAccessor][lonboard.traits.FloatAccessor], optional + - If a number is provided, it is used as the width for all paths. + - If an array is provided, each value in the array will be used as the width for + the path at the same row index. + - Default: `1`. + """ @classmethod def from_geopandas(cls, gdf: gpd.GeoDataFrame, **kwargs) -> PathLayer: @@ -364,6 +449,10 @@ def _validate_get_width_length(self, proposal): class SolidPolygonLayer(BaseLayer): + """ + The `SolidPolygonLayer` renders filled and/or extruded polygons. + """ + _esm = bundler_output_dir / "solid-polygon-layer.js" _layer_type = traitlets.Unicode("solid-polygon").tag(sync=True) _initial_view_state = traitlets.Dict().tag(sync=True) @@ -418,12 +507,49 @@ class SolidPolygonLayer(BaseLayer): - These lines are rendered with `GL.LINE` and will thus always be 1 pixel wide. - Wireframe and solid extrusions are exclusive, you'll need to create two layers - with the same data if you want a combined rendering effect. + with the same data if you want a combined rendering effect. """ get_elevation = FloatAccessor() + """ + The elevation to extrude each polygon with, in meters. + + Only applies if `extruded=True`. + + - Type: [FloatAccessor][lonboard.traits.FloatAccessor], optional + - If a number is provided, it is used as the width for all polygons. + - If an array is provided, each value in the array will be used as the width for + the polygon at the same row index. + - Default: `1000`. + """ + get_fill_color = ColorAccessor() + """ + The fill color of each polygon in the format of `[r, g, b, [a]]`. Each channel is a + number between 0-255 and `a` is 255 if not supplied. + + - Type: [ColorAccessor][lonboard.traits.ColorAccessor], optional + - If a single `list` or `tuple` is provided, it is used as the fill color for + all polygons. + - If a numpy or pyarrow array is provided, each value in the array will be used + as the fill color for the polygon at the same row index. + - Default: `[0, 0, 0, 255]`. + """ + get_line_color = ColorAccessor() + """ + The line color of each polygon in the format of `[r, g, b, [a]]`. Each channel is a + number between 0-255 and `a` is 255 if not supplied. + + Only applies if `extruded=True`. + + - Type: [ColorAccessor][lonboard.traits.ColorAccessor], optional + - If a single `list` or `tuple` is provided, it is used as the line color for + all polygons. + - If a numpy or pyarrow array is provided, each value in the array will be used + as the line color for the polygon at the same row index. + - Default: `[0, 0, 0, 255]`. + """ @classmethod def from_geopandas(cls, gdf: gpd.GeoDataFrame, **kwargs) -> SolidPolygonLayer: diff --git a/lonboard/traits.py b/lonboard/traits.py index d82ce6fd..4914705b 100644 --- a/lonboard/traits.py +++ b/lonboard/traits.py @@ -63,15 +63,23 @@ def validate(self, obj: Self, value: Any): class ColorAccessor(traitlets.TraitType): - """A representation of a deck.gl color accessor - - Represents either a single, scalar color with three or four values or an array - - Args: - traitlets: _description_ - - Returns: - _description_ + """A representation of a deck.gl color accessor. + + Various input is allowed: + + - A `list` or `tuple` with three or four integers, ranging between 0 and 255 + (inclusive). This will be used as the color for all objects. + - A numpy `ndarray` with two dimensions and data type [`np.uint8`][numpy.uint8]. The + size of the second dimension must be `3` or `4`, and will correspond to either RGB + or RGBA colors. + - A pyarrow [`FixedSizeListArray`][pyarrow.FixedSizeListArray] or + [`ChunkedArray`][pyarrow.ChunkedArray] containing `FixedSizeListArray`s. The inner + size of the fixed size list must be `3` or `4` and its child must have type + `uint8`. + + You can use helpers in the `lonboard.colormap` module (i.e. + [`apply_continuous_cmap`][lonboard.colormap.apply_continuous_cmap]) to simplify + constructing numpy arrays for color values. """ default_value = (0, 0, 0) @@ -159,9 +167,18 @@ def validate( class FloatAccessor(traitlets.TraitType): - """A representation of a deck.gl float accessor - - Represents either a single, scalar float value or an array of float values + """A representation of a deck.gl float accessor. + + Various input is allowed: + + - An `int` or `float`. This will be used as the value for all objects. + - A numpy `ndarray` with a numeric data type. This will be casted to an array of + data type [`np.float32`][numpy.float32]. Each value in the array will be used as + the value for the object at the same row index. + - A pyarrow [`FloatArray`][pyarrow.FloatArray], [`DoubleArray`][pyarrow.DoubleArray] + or [`ChunkedArray`][pyarrow.ChunkedArray] containing either a `FloatArray` or + `DoubleArray`. Each value in the array will be used as the value for the object at + the same row index. """ default_value = float(0) diff --git a/mkdocs.yml b/mkdocs.yml index 2fd1e0c4..829bacb0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,13 +20,14 @@ nav: - Example Notebooks: - examples/internet-speeds.ipynb - examples/north-america-roads.ipynb - - Layers: - - ScatterplotLayer: layers/scatterplot-layer.md - - PathLayer: layers/path-layer.md - - SolidPolygonLayer: layers/solid-polygon-layer.md - API Reference: - - api/top-level.md + - api/viz.md + - Layers: + - api/layers/scatterplot-layer.md + - api/layers/path-layer.md + - api/layers/solid-polygon-layer.md - api/colormap.md + - api/traits.md # - Caveats: caveats.md - Performance: performance.md - Alternatives: alternatives.md @@ -73,6 +74,7 @@ plugins: - social - mkdocs-jupyter: include_source: True + ignore: ["**/.ipynb_checkpoints/*.ipynb"] - mkdocstrings: enable_inventory: true handlers: @@ -85,30 +87,32 @@ plugins: docstring_section_style: list separate_signature: true show_signature_annotations: true + line_length: 80 import: - - https://scitools.org.uk/cartopy/docs/latest/objects.inv + - https://arrow.apache.org/docs/objects.inv - https://contextily.readthedocs.io/en/stable/objects.inv + - https://docs.python.org/3/objects.inv - https://fiona.readthedocs.io/en/stable/objects.inv - - https://python-visualization.github.io/folium/latest/objects.inv - https://geopandas.org/en/stable/objects.inv - - https://residentmario.github.io/geoplot/objects.inv - https://geopy.readthedocs.io/en/stable/objects.inv - - https://pysal.org/libpysal/objects.inv - - https://pysal.org/mapclassify/objects.inv - https://matplotlib.org/stable/objects.inv - https://numpy.org/doc/stable/objects.inv - https://pandas.pydata.org/pandas-docs/stable/objects.inv - https://pola-rs.github.io/polars/py-polars/html/objects.inv - - https://arrow.apache.org/docs/objects.inv - https://pyepsg.readthedocs.io/en/stable/objects.inv - https://pygeos.readthedocs.io/en/latest/objects.inv - https://pyogrio.readthedocs.io/en/stable/objects.inv - https://pyproj4.github.io/pyproj/stable/objects.inv - - https://docs.python.org/3/objects.inv - - https://rtree.readthedocs.io/en/stable/objects.inv + - https://pysal.org/libpysal/objects.inv + - https://pysal.org/mapclassify/objects.inv + - https://python-visualization.github.io/folium/latest/objects.inv - https://rasterio.readthedocs.io/en/stable/objects.inv + - https://residentmario.github.io/geoplot/objects.inv + - https://rtree.readthedocs.io/en/stable/objects.inv + - https://scitools.org.uk/cartopy/docs/latest/objects.inv - https://shapely.readthedocs.io/en/stable/objects.inv + - https://traitlets.readthedocs.io/en/stable/objects.inv - https://xyzservices.readthedocs.io/en/stable/objects.inv