DuckDB Spatial Extension
repository·v1.5-variegata·Indexed 20 days ago
https://github.com/duckdb/duckdb-spatialA spatial extension for DuckDB providing support for geospatial data formats like ESRI Shapefiles and Parquet. It includes a comprehensive set of scalar, aggregate, macro, and table functions for geometric operations, including coordinate reference system transformations via ST_Transform, spatial joins using ST_Within, and data export to GeoJSONSeq using GDAL.
What's inside duckdb-spatial
- The extension includes an embedded version of the PROJ library. PROJ is used for coordinate transformations between different Coordinate Reference Systems (CRS). Because PROJ is embedded within the extension binary, users do not need to install the PROJ library separately on their system, and this functionality is compatible with WASM environments.
Use the WKB_BLOB type for backward compatibility
v1.5-variegataThe
WKB_BLOBtype is used to represent geometries known to be in Well-Known Binary (WKB) format.Note: This type is deprecated. It is maintained solely for backward compatibility with previous versions of DuckDB Spatial. For new development, you should use the standard geometry types provided by the spatial extension instead of
WKB_BLOB.Understand the Multi-tiered Geometry Type System
v1.5-variegataThe extension provides two distinct ways to handle spatial data, allowing you to choose between flexibility and performance:
GEOMETRYType (Flexible/Standard):- Supports standard subtypes:
POINT,LINESTRING,POLYGON,MULTIPOINT,MULTILINESTRING,MULTIPOLYGON, andGEOMETRYCOLLECTION. - Internally represented as row-wise
BLOBs using a format similar to PostGIS (double-aligned WKB). - Uses the GEOS library for spatial operations.
- Best for columns containing mixed geometry types.
- Supports standard subtypes:
Native 2D Types (High Performance):
- Includes
POINT_2D,LINESTRING_2D,POLYGON_2D, andBOX_2D. - Built on DuckDB
STRUCTandLISTtypes, stored in a columnar fashion. - Optimized for OLAP workloads: leverages DuckDB's per-column statistics and efficient compression.
- Allows spatial operations without de/serialization penalties (though function support is currently limited).
- These types can be implicitly cast to
GEOMETRYto use the full suite of spatial functions, though this incurs a de/serialization cost.
- Includes
Note on WKB: The extension includes a
WKB_BLOBtype, which is an alias forBLOBused to signify that the data contains valid WKB-encoded geometry.Load spatial and parquet extensions
v1.5-variegataTo work with geospatial data formats like Shapefiles and Parquet, you must first load the
spatialandparquetextensions in DuckDB.LOAD spatial; LOAD parquet;Set GDAL Layer Creation Options when exporting data
v1.5-variegataWhen using the
COPYcommand to export data via the GDAL driver, you can specify format-specific options using theLAYER_CREATION_OPTIONSparameter within theWITHclause. This is equivalent to using the-lcoflag in the GDAL command-line interface.For example, when exporting to
GeoJSON, you can enable options likeWRITE_BBOXandRFC7946to control the output structure.COPY (SELECT * from st_read('input.shp')) TO 'output.geojson' WITH (FORMAT GDAL, DRIVER 'GeoJSON', LAYER_CREATION_OPTIONS ('WRITE_BBOX=YES', 'RFC7946=YES'))Optimize spatial queries with PreparedGeosGeometry
v1.5-variegataWhen performing multiple spatial predicate tests against the same geometry, use
get_prepared()to create aPreparedGeosGeometry. This object pre-processes the geometry to significantly speed up subsequent predicate operations likecontains,intersects, andwithin.Workflow
- Call
geom.get_prepared()to create the prepared instance. - Use the prepared instance to run multiple queries against different geometries.
Supported Predicates
PreparedGeosGeometrysupports the same core predicates asGeosGeometry(e.g.,contains,covers,crosses,disjoint,intersects,overlaps,touches,within) but at a higher performance level.// Assuming 'geom' is an existing GeosGeometry PreparedGeosGeometry prepared = geom.get_prepared(); if (prepared.intersects(other_geom)) { // Perform fast intersection check }- Call
Remove repeated points from a linestring
v1.5-variegataUseST_RemoveRepeatedPointsto remove consecutive duplicate points from aLINESTRING_2D. You can optionally provide atolerancevalue.Get the maximum Z coordinate with ST_ZMax
v1.5-variegataThe
ST_ZMaxfunction returns the maximum Z coordinate found within the provided geometry.SELECT ST_ZMax(ST_Point(1, 2, 3));Extract M coordinates from a geometry
v1.5-variegataUse
ST_Mto retrieve the M (measure) coordinate of a point geometry.SELECT ST_M(ST_Point(1, 2, 3, 4))Check spatial relationships (Covers, CoveredBy, Crosses, Disjoint, Equals)
v1.5-variegataStandard spatial predicate functions:
ST_CoveredBy: Returns true ifgeom1is covered bygeom2.ST_Covers: Returns true ifgeom1coversgeom2.ST_Crosses: Returns true ifgeom1crossesgeom2.ST_Disjoint: Returns true if the geometries do not intersect.ST_Equals: Returns true if the geometries are equal.
BOOLEAN ST_CoveredBy (geom1 GEOMETRY, geom2 GEOMETRY) BOOLEAN ST_Covers (geom1 GEOMETRY, geom2 GEOMETRY) BOOLEAN ST_Crosses (geom1 GEOMETRY, geom2 GEOMETRY) BOOLEAN ST_Disjoint (geom1 GEOMETRY, geom2 GEOMETRY) BOOLEAN ST_Equals (geom1 GEOMETRY, geom2 GEOMETRY)Get the minimum Z coordinate with ST_ZMin
v1.5-variegataThe
ST_ZMinfunction returns the minimum Z coordinate found within the provided geometry.SELECT ST_ZMin(ST_Point(1, 2, 3));Calculate perimeter on a spheroid
v1.5-variegataUse
ST_Perimeter_Spheroidto calculate the perimeter in meters using an ellipsoidal model of the Earth.Requirements:
- Input must be in
EPSG:4326(WGS84) with[latitude, longitude]axis order. - Input must be a
POLYGON,MULTIPOLYGON, or aGEOMETRYCOLLECTIONcontaining polygons.
Note: This is highly accurate but is the slowest perimeter calculation method.
- Input must be in