Skip to content

Commit 3f0780d

Browse files
authored
Fix reading from DuckDB with only geometry column (#625)
Follow up for #623 and #622, based on input from #619 (reply in thread)
1 parent 09c0005 commit 3f0780d

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lonboard/_geoarrow/_duckdb.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ def _from_geometry(
9898
crs: Optional[Union[str, pyproj.CRS]] = None,
9999
) -> Table:
100100
other_col_names = [name for i, name in enumerate(rel.columns) if i != geom_col_idx]
101-
non_geo_table = Table.from_arrow(rel.select(*other_col_names).arrow())
101+
if other_col_names:
102+
non_geo_table = Table.from_arrow(rel.select(*other_col_names).arrow())
103+
else:
104+
non_geo_table = None
102105
geom_col_name = rel.columns[geom_col_idx]
103106

104107
# A poor-man's string interpolation check
@@ -142,7 +145,13 @@ def _from_geometry(
142145

143146
metadata = _make_geoarrow_field_metadata(EXTENSION_NAME.WKB, crs)
144147
geom_field = geom_table.schema.field(0).with_metadata(metadata)
145-
return non_geo_table.append_column(geom_field, geom_table.column(0))
148+
if non_geo_table is not None:
149+
return non_geo_table.append_column(geom_field, geom_table.column(0))
150+
else:
151+
# Need to set geospatial metadata onto the Arrow table, because the table
152+
# returned from duckdb has none.
153+
new_schema = geom_table.schema.set(0, geom_field)
154+
return geom_table.with_schema(new_schema)
146155

147156

148157
def _from_geoarrow(

tests/test_duckdb.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ def test_create_table_as_custom_con():
208208

209209

210210
def test_geometry_only_column():
211-
# https://github.com/developmentseed/lonboard/issues/622
212211
con = duckdb.connect()
213212
sql = f"""
214213
INSTALL spatial;
@@ -222,3 +221,20 @@ def test_geometry_only_column():
222221

223222
m = viz(con.table("data"), con=con)
224223
assert isinstance(m.layers[0], ScatterplotLayer)
224+
225+
226+
def test_geometry_only_column_type_geometry():
227+
# For WKB parsing
228+
pytest.importorskip("shapely")
229+
230+
# https://github.com/developmentseed/lonboard/issues/622
231+
con = duckdb.connect()
232+
sql = f"""
233+
INSTALL spatial;
234+
LOAD spatial;
235+
SELECT geom FROM ST_Read("{cities_gdal_path}");
236+
"""
237+
query = con.sql(sql)
238+
239+
# Should create layer without erroring
240+
_layer = ScatterplotLayer.from_duckdb(query, con)

0 commit comments

Comments
 (0)