Skip to content

Commit

Permalink
feat(geospatial): accept geopandas GDFs in memtable
Browse files Browse the repository at this point in the history
  • Loading branch information
gforsyth committed Nov 13, 2024
1 parent 49b404a commit d68a293
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
13 changes: 13 additions & 0 deletions ibis/backends/tests/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,19 @@ def test_memtable_column_naming_mismatch(con, monkeypatch, df, columns):
ibis.memtable(df, columns=columns)


@pytest.mark.notyet(
["mssql", "mysql", "exasol", "impala"], reason="various syntax errors reported"
)
def test_memtable_from_geopandas_dataframe(con, data_dir):
gpd = pytest.importorskip("geopandas")
gdf = gpd.read_file(data_dir / "geojson" / "zones.geojson")[:5]

# Read in memtable
t = ibis.memtable(gdf)
# Execute a few rows to force ingestion
res = con.to_pandas(t.limit(2).select("geometry"))


@pytest.mark.notimpl(["oracle", "exasol"], raises=com.OperationNotDefinedError)
@pytest.mark.notimpl(["druid"], raises=AssertionError)
@pytest.mark.notyet(
Expand Down
17 changes: 17 additions & 0 deletions ibis/expr/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,23 @@ def _memtable_from_polars_dataframe(
).to_expr()


@_memtable.register("geopandas.geodataframe.GeoDataFrame")
def _memtable_from_geopandas_geodataframe(
data: geopandas.geodataframe.GeoDataFrame,
*,
name: str | None = None,
schema: SchemaLike | None = None,
columns: Iterable[str] | None = None,
):
# The Pandas data proxy and the `to_arrow` method on it can't handle
# geopandas geometry columns. But if we first make the geometry columns WKB,
# then the geo column gets treated (correctly) as just a binary blob, and
# DuckDB can cast it to a proper geometry column after import.
wkb_df = data.to_wkb()

return _memtable(wkb_df, name=name, schema=schema, columns=columns)


def _deferred_method_call(expr, method_name, **kwargs):
method = operator.methodcaller(method_name, **kwargs)
if isinstance(expr, str):
Expand Down

0 comments on commit d68a293

Please sign in to comment.