Skip to main content

Spatial & GeoArrow

SigilYX can read and write YXDB files containing SpatialObj columns. The internal SHP geometry format is decoded to standard ISO Well-Known Binary (WKB), making data compatible with PostGIS, GDAL, Shapely, GeoPandas, and other geospatial tools.

SpatialObj Handling Modes

Every read function that touches spatial data accepts a spatial parameter:

ModeBehavior
"wkb" (default)Decode SHP geometry to ISO WKB
"raw"Keep the raw SHP bytes as-is
import sigilyx as yx

# Default: SHP → WKB conversion
df = yx.read_yxdb("parcels.yxdb")

# Keep raw SHP bytes (expert/debug use)
df = yx.read_yxdb("parcels.yxdb", spatial="raw")

Spatial Metadata

Inspect which columns are spatial and whether a spatial index exists, without reading any row data:

import sigilyx as yx

info = yx.read_spatial_info("parcels.yxdb")
print(info)
# {
# "has_spatial_index": True,
# "spatial_index_pos": 123456,
# "file_id": 21,
# "spatial_columns": ["SpatialObj"]
# }

GeoArrow Output

read_yxdb_geoarrow() returns a PyArrow Table where spatial columns are tagged with ARROW:extension:name = "geoarrow.wkb". This makes the table compatible with GeoArrow-aware tools (lonboard, leafmap, DuckDB Spatial, etc.).

pip install sigilyx[arrow]
import sigilyx as yx

table = yx.read_yxdb_geoarrow("parcels.yxdb")

# Spatial columns now have GeoArrow extension metadata
field = table.schema.field("SpatialObj")
print(field.metadata)
# {b'ARROW:extension:name': b'geoarrow.wkb', ...}

With column projection:

table = yx.read_yxdb_geoarrow("parcels.yxdb", columns=["Id", "SpatialObj"])

GeoPandas Integration

read_yxdb_geo() reads a YXDB file directly into a GeoPandas GeoDataFrame. Spatial columns are decoded from SHP to WKB, then converted to Shapely geometry objects.

pip install geopandas shapely
import sigilyx as yx

gdf = yx.read_yxdb_geo("parcels.yxdb")
print(type(gdf)) # <class 'geopandas.GeoDataFrame'>
gdf.plot()

Column Projection

gdf = yx.read_yxdb_geo("parcels.yxdb", columns=["Id", "Name", "SpatialObj"])

Choosing the Geometry Column

If a file has multiple SpatialObj columns, the first one is used as the active geometry by default. Override with geometry_column:

gdf = yx.read_yxdb_geo("multi_spatial.yxdb", geometry_column="Boundary")

Writing GeoPandas to YXDB

import sigilyx as yx
import geopandas as gpd

gdf = gpd.read_file("parcels.shp")
yx.write_yxdb_geo("parcels.yxdb", gdf)

Auto-detects geometry columns. To force specific columns:

yx.write_yxdb_geo("parcels.yxdb", gdf, spatial_columns=["geometry"])

Low-Level Geometry Conversion

Convert individual geometry values between SHP and WKB formats:

import sigilyx as yx

# SHP → WKB (returns None for null shapes)
wkb = yx.shp_to_wkb(shp_bytes)

# WKB → SHP
shp = yx.wkb_to_shp(wkb_bytes)

These are useful when processing spatial data row by row or building custom pipelines.

Common Patterns

YXDB to GeoJSON

import sigilyx as yx

gdf = yx.read_yxdb_geo("parcels.yxdb")
gdf.to_file("parcels.geojson", driver="GeoJSON")

YXDB to PostGIS

import sigilyx as yx
from sqlalchemy import create_engine

engine = create_engine("postgresql://user:pass@localhost/db")
gdf = yx.read_yxdb_geo("parcels.yxdb")
gdf.to_postgis("parcels", engine, if_exists="replace")

DuckDB Spatial Query via GeoArrow

import sigilyx as yx
import duckdb

table = yx.read_yxdb_geoarrow("parcels.yxdb")

result = duckdb.sql("""
SELECT Id, ST_Area(ST_GeomFromWKB(SpatialObj)) as area
FROM table
ORDER BY area DESC
LIMIT 10
""").arrow()

Shapefile to YXDB

import sigilyx as yx
import geopandas as gpd

gdf = gpd.read_file("boundaries.shp")
yx.write_yxdb_geo("boundaries.yxdb", gdf)