diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..48001867 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## [0.1.0] - 2023-10-17 + +- Initial public release. +- Initial support for `ScatterplotLayer`, `PathLayer`, and `SolidPolygonLayer`. diff --git a/DEVELOP.md b/DEVELOP.md index f76411ef..3456b4c5 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -72,8 +72,4 @@ The documentation website is generated with `mkdocs` and [`mkdocs-material`](htt poetry run mkdocs serve ``` -and you can publish the docs to Github Pages with - -``` -poetry run mkdocs gh-deploy -``` +Publishing documentation happens automatically via CI when a PR is merged. diff --git a/README.md b/README.md index 75faa596..fb3dbdeb 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,23 @@ Python library for extremely fast geospatial vector data visualization in Jupyte ## Install ``` -pip install --pre lonboard +pip install lonboard ``` +## Get Started + +For the simplest rendering, pass geospatial data into the top-level [`viz` function](https://developmentseed.org/lonboard/api/top-level/#lonboard.viz.viz). + +```py +import geopandas as gpd +from lonboard import viz + +gdf = gpd.GeoDataFrame(...) +viz(gdf) +``` + +Under the hood, this delegates to a `ScatterplotLayer`, `PathLayer`, or `SolidPolygonLayer`. Refer to the [documentation](https://developmentseed.org/lonboard/) and [examples](https://developmentseed.org/lonboard/examples/internet-speeds/) for more control over rendering. + ## Documentation Refer to the documentation at [developmentseed.org/lonboard](https://developmentseed.org/lonboard/). diff --git a/lonboard/serialization.py b/lonboard/serialization.py index 2e6ff67e..141e1895 100644 --- a/lonboard/serialization.py +++ b/lonboard/serialization.py @@ -11,7 +11,7 @@ DEFAULT_PARQUET_COMPRESSION_LEVEL = 7 DEFAULT_PARQUET_CHUNK_SIZE = 2**16 # Target chunk size for Arrow (uncompressed) per Parquet chunk -DEFAULT_ARROW_CHUNK_BYTES_SIZE = 10 * 1024 * 1024 # 10MB +DEFAULT_ARROW_CHUNK_BYTES_SIZE = 5 * 1024 * 1024 # 5MB def serialize_table_to_parquet( diff --git a/lonboard/traits.py b/lonboard/traits.py index 4b198555..d82ce6fd 100644 --- a/lonboard/traits.py +++ b/lonboard/traits.py @@ -74,7 +74,7 @@ class ColorAccessor(traitlets.TraitType): _description_ """ - default_value = (255, 255, 255) + default_value = (0, 0, 0) info_text = ( "a tuple or list representing an RGB(A) color or numpy ndarray or " "pyarrow FixedSizeList representing an array of RGB(A) colors" diff --git a/lonboard/viz.py b/lonboard/viz.py index dd1654ac..ce925bab 100644 --- a/lonboard/viz.py +++ b/lonboard/viz.py @@ -10,12 +10,13 @@ import pyarrow as pa import pyarrow.compute as pc import shapely.geometry +import shapely.geometry.base from numpy.typing import NDArray from lonboard.constants import EPSG_4326, EXTENSION_NAME, OGC_84 from lonboard.geoarrow.extension_types import construct_geometry_array from lonboard.geoarrow.geopandas_interop import geopandas_to_geoarrow -from lonboard.layer import BaseLayer, PathLayer, ScatterplotLayer, SolidPolygonLayer +from lonboard.layer import PathLayer, ScatterplotLayer, SolidPolygonLayer if TYPE_CHECKING: import geopandas as gpd @@ -116,8 +117,9 @@ def viz( raise ValueError -# TODO: check CRS in geopandas methods -def _viz_geopandas_geodataframe(data: gpd.GeoDataFrame, **kwargs) -> BaseLayer: +def _viz_geopandas_geodataframe( + data: gpd.GeoDataFrame, **kwargs +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: if data.crs and data.crs not in [EPSG_4326, OGC_84]: warnings.warn("GeoDataFrame being reprojected to EPSG:4326") data = data.to_crs(OGC_84) @@ -126,7 +128,9 @@ def _viz_geopandas_geodataframe(data: gpd.GeoDataFrame, **kwargs) -> BaseLayer: return _viz_geoarrow_table(table, **kwargs) -def _viz_geopandas_geoseries(data: gpd.GeoSeries, **kwargs) -> BaseLayer: +def _viz_geopandas_geoseries( + data: gpd.GeoSeries, **kwargs +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: import geopandas as gpd if data.crs and data.crs not in [EPSG_4326, OGC_84]: @@ -140,11 +144,13 @@ def _viz_geopandas_geoseries(data: gpd.GeoSeries, **kwargs) -> BaseLayer: def _viz_shapely_scalar( data: shapely.geometry.base.BaseGeometry, **kwargs -) -> BaseLayer: +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: return _viz_shapely_array(np.array([data]), **kwargs) -def _viz_shapely_array(data: NDArray[np.object_], **kwargs) -> BaseLayer: +def _viz_shapely_array( + data: NDArray[np.object_], **kwargs +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: # TODO: pass include_z? field, geom_arr = construct_geometry_array(data) schema = pa.schema([field]) @@ -152,7 +158,9 @@ def _viz_shapely_array(data: NDArray[np.object_], **kwargs) -> BaseLayer: return _viz_geoarrow_table(table, **kwargs) -def _viz_geo_interface(data: dict, **kwargs) -> BaseLayer: +def _viz_geo_interface( + data: dict, **kwargs +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: if data["type"] in [ "Point", "LineString", @@ -193,21 +201,23 @@ def _viz_geo_interface(data: dict, **kwargs) -> BaseLayer: raise ValueError(f"type '{geo_interface_type}' not supported.") -def _viz_geoarrow_table(table: pa.Table, **kwargs) -> BaseLayer: +def _viz_geoarrow_table( + table: pa.Table, **kwargs +) -> Union[ScatterplotLayer, PathLayer, SolidPolygonLayer]: geometry_ext_type = table.schema.field("geometry").metadata.get( b"ARROW:extension:name" ) if geometry_ext_type in [EXTENSION_NAME.POINT, EXTENSION_NAME.MULTIPOINT]: - return ScatterplotLayer(table, **kwargs) + return ScatterplotLayer(table=table, **kwargs) elif geometry_ext_type in [ EXTENSION_NAME.LINESTRING, EXTENSION_NAME.MULTILINESTRING, ]: - return PathLayer(table, **kwargs) + return PathLayer(table=table, **kwargs) elif geometry_ext_type in [EXTENSION_NAME.POLYGON, EXTENSION_NAME.MULTIPOLYGON]: - return SolidPolygonLayer(table, **kwargs) + return SolidPolygonLayer(table=table, **kwargs) raise ValueError(f"Unsupported extension type: '{geometry_ext_type}'.") diff --git a/package-lock.json b/package-lock.json index 3ca4ff09..1c0f10d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@deck.gl/core": "^8.9.30", "@deck.gl/layers": "^8.9.30", "@deck.gl/react": "^8.9.30", - "@geoarrow/deck.gl-layers": "^0.1.0-beta.5", + "@geoarrow/deck.gl-layers": "^0.1.0", "apache-arrow": "^13.0.0", "maplibre-gl": "^3.5.0", "parquet-wasm": "0.5.0-alpha.1", diff --git a/package.json b/package.json index dbd479a9..3ba5fdda 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "@deck.gl/core": "^8.9.30", "@deck.gl/layers": "^8.9.30", "@deck.gl/react": "^8.9.30", - "@geoarrow/deck.gl-layers": "^0.1.0-beta.5", + "@geoarrow/deck.gl-layers": "^0.1.0", "apache-arrow": "^13.0.0", "maplibre-gl": "^3.5.0", "parquet-wasm": "0.5.0-alpha.1", diff --git a/pyproject.toml b/pyproject.toml index d1e73b05..0081cf21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "lonboard" -version = "0.1.0-beta.7" +version = "0.1.0" description = "Extremely fast geospatial data visualization in Python." authors = ["Kyle Barron "] license = "MIT"