From 74694106cfae65ace2d7da9cd1e4775730c03ad8 Mon Sep 17 00:00:00 2001 From: guilhem-dvr Date: Thu, 1 Feb 2024 01:38:08 +0100 Subject: [PATCH 1/3] feat(python): expose kepler & pydeck optional dependencies in extras --- python/sedona/maps/SedonaKepler.py | 8 +++++++- python/sedona/maps/SedonaPyDeck.py | 20 +++++++++++++++++++- python/sedona/spark/__init__.py | 9 +-------- python/setup.py | 6 +++++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/python/sedona/maps/SedonaKepler.py b/python/sedona/maps/SedonaKepler.py index 21f7542618..a8cf7b5f0b 100644 --- a/python/sedona/maps/SedonaKepler.py +++ b/python/sedona/maps/SedonaKepler.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from keplergl import KeplerGl from sedona.maps.SedonaMapUtils import SedonaMapUtils @@ -30,6 +29,13 @@ def create_map(cls, df=None, name="unnamed", config=None): dataframe, if a df is passed with no name, a default name of 'unnamed' is set for it. param config: [Optional] A map config to be applied to the rendered map :return: A map object """ + + try: + from keplergl import KeplerGl + except ImportError: + msg = "Install sedona[kepler-map] to convert sedona dataframes to kepler maps." + raise ImportError(msg) from None + kepler_map = KeplerGl() if df is not None: SedonaKepler.add_df(kepler_map, df, name) diff --git a/python/sedona/maps/SedonaPyDeck.py b/python/sedona/maps/SedonaPyDeck.py index 154b8a4cd4..b6062e67b4 100644 --- a/python/sedona/maps/SedonaPyDeck.py +++ b/python/sedona/maps/SedonaPyDeck.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -import pydeck as pdk +from types import ModuleType from sedona.maps.SedonaMapUtils import SedonaMapUtils @@ -37,6 +37,7 @@ def create_choropleth_map(cls, df, fill_color=None, plot_col=None, initial_view_ :param map_provider: :return: A pydeck Map object with choropleth layer added: """ + pdk = _try_import_pydeck() if initial_view_state is None: gdf = SedonaPyDeck._prepare_df_(df, add_coords=True) @@ -79,6 +80,8 @@ def create_geometry_map(cls, df, fill_color="[85, 183, 177, 255]", line_color="[ :param map_provider: optional map_provider of the pydeck map :return: A pydeck map with a GeoJsonLayer map added """ + pdk = _try_import_pydeck() + geometry_col = SedonaMapUtils.__get_geometry_col__(df) gdf = SedonaPyDeck._prepare_df_(df, geometry_col=geometry_col) geom_type = gdf[geometry_col][0].geom_type @@ -116,6 +119,8 @@ def create_scatterplot_map(cls, df, fill_color="[255, 140, 0]", radius_col=1, ra :param map_provider: optional map_provider to be added to the pydeck map :return: A pydeck map object with a scatterplot layer added """ + pdk = _try_import_pydeck() + gdf = SedonaPyDeck._prepare_df_(df, add_coords=True) layer = pdk.Layer( "ScatterplotLayer", @@ -152,6 +157,7 @@ def create_heatmap(cls, df, color_range=None, weight=1, aggregation="SUM", initi :param map_provider: Optional map_provider for the pydeck map :return: A pydeck map with a heatmap layer added """ + pdk = _try_import_pydeck() gdf = SedonaPyDeck._prepare_df_(df, add_coords=True) @@ -239,6 +245,7 @@ def _create_coord_column_(cls, gdf, geometry_col, add_points=False): @classmethod def _create_fat_layer_(cls, gdf, fill_color, line_color, elevation_col): + pdk = _try_import_pydeck() layer = pdk.Layer( 'GeoJsonLayer', # `type` positional argument is here data=gdf, @@ -254,3 +261,14 @@ def _create_fat_layer_(cls, gdf, fill_color, line_color, elevation_col): ) return layer + + +def _try_import_pydeck() -> ModuleType: + try: + import pydeck as pdk + + except ImportError: + msg = "Install sedona[pydeck-map] to convert sedona dataframes to pydeck maps." + raise ImportError(msg) from None + + return pdk diff --git a/python/sedona/spark/__init__.py b/python/sedona/spark/__init__.py index 73c4b2d4a4..c55f67a116 100644 --- a/python/sedona/spark/__init__.py +++ b/python/sedona/spark/__init__.py @@ -41,11 +41,4 @@ from sedona.register import SedonaRegistrator from sedona.spark.SedonaContext import SedonaContext from sedona.raster_utils.SedonaUtils import SedonaUtils -try: - from sedona.maps.SedonaKepler import SedonaKepler -except: - print('Skipping SedonaKepler import, verify if keplergl is installed') -try: - from sedona.maps.SedonaPyDeck import SedonaPyDeck -except: - print('Skipping SedonaPyDeck import, verify if pydeck is installed') +from sedona.maps import SedonaKepler, SedonaPyDeck diff --git a/python/setup.py b/python/setup.py index a6bc7b2c93..1d07cf32d9 100644 --- a/python/setup.py +++ b/python/setup.py @@ -53,7 +53,11 @@ long_description_content_type="text/markdown", python_requires='>=3.6', install_requires=['attrs', "shapely>=1.7.0"], - extras_require={"spark": ['pyspark>=2.3.0']}, + extras_require={ + "spark": ["pyspark>=2.3.0"], + "pydeck-map": ["pandas<=1.3.5", "geopandas<=0.10.2", "pydeck==0.8.0"], + "kepler-map": ["pandas<=1.3.5", "geopandas<=0.10.2", "keplergl==0.3.2"], + }, project_urls={ 'Documentation': 'https://sedona.apache.org', 'Source code': 'https://github.com/apache/sedona', From 0451f3b7411a28806af03969ed76154a28adef15 Mon Sep 17 00:00:00 2001 From: guilhem-dvr Date: Thu, 1 Feb 2024 02:23:11 +0100 Subject: [PATCH 2/3] feat(python): add `all` extras option --- python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/setup.py b/python/setup.py index 1d07cf32d9..7576957d0d 100644 --- a/python/setup.py +++ b/python/setup.py @@ -57,6 +57,7 @@ "spark": ["pyspark>=2.3.0"], "pydeck-map": ["pandas<=1.3.5", "geopandas<=0.10.2", "pydeck==0.8.0"], "kepler-map": ["pandas<=1.3.5", "geopandas<=0.10.2", "keplergl==0.3.2"], + "all": ["pyspark>=2.3.0", "pandas<=1.3.5", "geopandas<=0.10.2","pydeck==0.8.0", "keplergl==0.3.2"], }, project_urls={ 'Documentation': 'https://sedona.apache.org', From fc458be9a566a60147fef3fba9914c1e0046673c Mon Sep 17 00:00:00 2001 From: guilhem-dvr Date: Thu, 1 Feb 2024 02:36:50 +0100 Subject: [PATCH 3/3] docs: update sql tutorial with new map extras --- docs/tutorial/sql.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/tutorial/sql.md b/docs/tutorial/sql.md index 61f315a3f2..4e97d7f12b 100644 --- a/docs/tutorial/sql.md +++ b/docs/tutorial/sql.md @@ -580,11 +580,9 @@ Spatial query results can be visualized in a Jupyter lab/notebook environment us SedonaPyDeck exposes APIs to create interactive map visualizations using [pydeck](https://pydeck.gl/index.html#) based on [deck.gl](https://deck.gl/) !!!Note - To use SedonaPyDeck, GeoPandas and PyDeck must be installed. We recommend the following installation commands: + To use SedonaPyDeck, install sedona with the `pydeck-map` extra: ``` - pip install 'pandas<=1.3.5' - pip install 'geopandas<=0.10.2' - pip install pydeck==0.8.0 + pip install sedona[pydeck-map] ``` The following tutorial showcases the various maps that can be created using SedonaPyDeck, the datasets used to create these maps are publicly available. @@ -658,11 +656,9 @@ Spatial query results can be visualized in a Jupyter lab/notebook environment us SedonaKepler exposes APIs to create interactive and customizable map visualizations using [KeplerGl](https://kepler.gl/). !!!Note - To use SedonaKepler, GeoPandas and KeplerGL must be installed. We recommend the following installation commands: + To use SedonaKepler, install sedona with the `kepler-map` extra: ``` - pip install 'pandas<=1.3.5' - pip install 'geopandas<=0.10.2' - pip install keplergl==0.3.2 + pip install sedona[kepler-map] ``` This tutorial showcases how simple it is to instantly visualize geospatial data using SedonaKepler.