2023-04-28

PostGEESE? Die Spatial-Erweiterung von DuckDB

Max Gabrielsson

Geospatiale Daten werden in modernen Anwendungen und Data-Engineering-Workflows immer wichtiger – von standortbasierten Diensten bis zur Umweltüberwachung.

Es gibt viele gute, spezialisierte Werkzeuge für geospatiale Daten. Geospatiale Fähigkeiten direkt in DuckDB zu integrieren hat trotzdem mehrere Vorteile. Zum einen können Sie geospatiale Daten zusammen mit regulären, unstrukturierten oder Zeitreihendaten über DuckDBs reiches Typsystem und Erweiterungen wie JSON und ICU verarbeiten, transformieren und joinen. Zum anderen lassen sich räumliche Abfragen mit geometrischen Prädikaten und Relationen überraschend gut in SQL ausdrücken – SQL dreht sich ja um Relationen. Dazu kommen DuckDBs weitere Stärken: transaktionale Semantik, hochperformante mehrfädige vektorisierte Ausführung und Verarbeitung größerer Datenmengen als der Speicher.

Deshalb freuen wir uns, dass DuckDB jetzt eine Spatial-Erweiterung mit vielen Features hat, die sich einfach aus der DuckDB-CLI und anderen Clients installieren lässt. Einfach ausführen:

INSTALL spatial;
LOAD spatial;

Und schon kann es losgehen!

Nein, GeoDuck nennen wir es auch nicht, das wäre einfach nur eklig.

Was steckt drin?

Kern der Erweiterung ist ein Typ GEOMETRY nach dem Geometriemodell „Simple Features“ und dazugehörige Funktionen wie ST_Area und ST_Intersects. Außerdem gibt es Methoden zum Lesen und Schreiben geospatialer Formate und zur Umrechnung zwischen Koordinatenreferenzsystemen (Details weiter unten). Volle Konformität mit OGC Simple Feature Access und SQL/MM wollen wir noch nicht zusagen; wer geospatiale Funktionen in anderen Datenbanksystemen wie PostGIS oder SpatiaLite kennt, sollte sich aber sofort zurechtfinden.

Die meisten implementierten Funktionen stützen sich auf das Trio grundlegender geospatialer Bibliotheken: GEOS, GDAL und PROJ – für Algorithmen, Formatumwandlungen und Transformationen von Koordinatenreferenzsystemen. Insbesondere nutzen wir GDAL für Tabellen- und Copy-Funktionen, mit denen sich Tabellen aus über 50 geospatialen Formaten importieren und exportieren lassen (bisher!), darunter die gängigsten wie Shapefiles, GeoJSON, GeoPackage, KML, GML, WKT, WKB usw.

Überzeugen Sie sich selbst:

`SELECT * FROM st_drivers();`
short_name long_name can_create can_copy can_open help_url
ESRI Shapefile ESRI Shapefile true false true https://gdal.org/en/release-3.10/drivers/vector/shapefile.html
MapInfo File MapInfo File true false true https://gdal.org/en/release-3.10/drivers/vector/mitab.html
UK .NTF UK .NTF false false true https://gdal.org/en/release-3.10/drivers/vector/ntf.html
LVBAG Kadaster LV BAG Extract 2.0 false false true https://gdal.org/en/release-3.10/drivers/vector/lvbag.html
S57 IHO S-57 (ENC) true false true https://gdal.org/en/release-3.10/drivers/vector/s57.html
DGN Microstation DGN true false true https://gdal.org/en/release-3.10/drivers/vector/dgn.html
OGR_VRT VRT - Virtual Datasource false false true https://gdal.org/en/release-3.10/drivers/vector/vrt.html
Memory Memory true false true
CSV Comma Separated Value (.csv) true false true https://gdal.org/en/release-3.10/drivers/vector/csv.html
GML Geography Markup Language (GML) true false true https://gdal.org/en/release-3.10/drivers/vector/gml.html
GPX GPX true false true https://gdal.org/en/release-3.10/drivers/vector/gpx.html
KML Keyhole Markup Language (KML) true false true https://gdal.org/en/release-3.10/drivers/vector/kml.html
GeoJSON GeoJSON true false true https://gdal.org/en/release-3.10/drivers/vector/geojson.html
GeoJSONSeq GeoJSON Sequence true false true https://gdal.org/en/release-3.10/drivers/vector/geojsonseq.html
ESRIJSON ESRIJSON false false true https://gdal.org/en/release-3.10/drivers/vector/esrijson.html
TopoJSON TopoJSON false false true https://gdal.org/en/release-3.10/drivers/vector/topojson.html
OGR_GMT GMT ASCII Vectors (.gmt) true false true https://gdal.org/en/release-3.10/drivers/vector/gmt.html
GPKG GeoPackage true true true https://gdal.org/en/release-3.10/drivers/vector/gpkg.html
SQLite SQLite / Spatialite true false true https://gdal.org/en/release-3.10/drivers/vector/sqlite.html
WAsP WAsP .map format true false true https://gdal.org/en/release-3.10/drivers/vector/wasp.html
OpenFileGDB ESRI FileGDB true false true https://gdal.org/en/release-3.10/drivers/vector/openfilegdb.html
DXF AutoCAD DXF true false true https://gdal.org/en/release-3.10/drivers/vector/dxf.html
CAD AutoCAD Driver false false true https://gdal.org/en/release-3.10/drivers/vector/cad.html
FlatGeobuf FlatGeobuf true false true https://gdal.org/en/release-3.10/drivers/vector/flatgeobuf.html
Geoconcept Geoconcept true false true
GeoRSS GeoRSS true false true https://gdal.org/en/release-3.10/drivers/vector/georss.html
VFK Czech Cadastral Exchange Data Format false false true https://gdal.org/en/release-3.10/drivers/vector/vfk.html
PGDUMP PostgreSQL SQL dump true false false https://gdal.org/en/release-3.10/drivers/vector/pgdump.html
OSM OpenStreetMap XML and PBF false false true https://gdal.org/en/release-3.10/drivers/vector/osm.html
GPSBabel GPSBabel true false true https://gdal.org/en/release-3.10/drivers/vector/gpsbabel.html
WFS OGC WFS (Web Feature Service) false false true https://gdal.org/en/release-3.10/drivers/vector/wfs.html
OAPIF OGC API - Features false false true https://gdal.org/en/release-3.10/drivers/vector/oapif.html
EDIGEO French EDIGEO exchange format false false true https://gdal.org/en/release-3.10/drivers/vector/edigeo.html
SVG Scalable Vector Graphics false false true https://gdal.org/en/release-3.10/drivers/vector/svg.html
ODS Open Document/ LibreOffice / OpenOffice Spreadsheet true false true https://gdal.org/en/release-3.10/drivers/vector/ods.html
XLSX MS Office Open XML spreadsheet true false true https://gdal.org/en/release-3.10/drivers/vector/xlsx.html
Elasticsearch Elastic Search true false true https://gdal.org/en/release-3.10/drivers/vector/elasticsearch.html
Carto Carto true false true https://gdal.org/en/release-3.10/drivers/vector/carto.html
AmigoCloud AmigoCloud true false true https://gdal.org/en/release-3.10/drivers/vector/amigocloud.html
SXF Storage and eXchange Format false false true https://gdal.org/en/release-3.10/drivers/vector/sxf.html
Selafin Selafin true false true https://gdal.org/en/release-3.10/drivers/vector/selafin.html
JML OpenJUMP JML true false true https://gdal.org/en/release-3.10/drivers/vector/jml.html
PLSCENES Planet Labs Scenes API false false true https://gdal.org/en/release-3.10/drivers/vector/plscenes.html
CSW OGC CSW (Catalog Service for the Web) false false true https://gdal.org/en/release-3.10/drivers/vector/csw.html
VDV VDV-451/VDV-452/INTREST Data Format true false true https://gdal.org/en/release-3.10/drivers/vector/vdv.html
MVT Mapbox Vector Tiles true false true https://gdal.org/en/release-3.10/drivers/vector/mvt.html
NGW NextGIS Web true true true https://gdal.org/en/release-3.10/drivers/vector/ngw.html
MapML MapML true false true https://gdal.org/en/release-3.10/drivers/vector/mapml.html
TIGER U.S. Census TIGER/Line false false true https://gdal.org/en/release-3.10/drivers/vector/tiger.html
AVCBin Arc/Info Binary Coverage false false true https://gdal.org/en/release-3.10/drivers/vector/avcbin.html
AVCE00 Arc/Info E00 (ASCII) Coverage false false true https://gdal.org/en/release-3.10/drivers/vector/avce00.html

Zunächst haben wir vor allem Breite geschaffen, indem wir bestehende Bibliotheken umhüllen. Künftig wollen wir mehr Kernfunktionen und Algorithmen nativ implementieren, für mehr Leistung und effizientere Speicherverwaltung.

Als ersten Schritt in diese Richtung gibt es eine Reihe nicht-standardisierter, spezialisierter spaltenorientierter DuckDB-nativer Geometrietypen wie POINT_2D, BOX_2D usw. Sie sollen bessere Kompression und schnellere Ausführung bei etwas weniger Flexibilität bieten; die Arbeit daran ist noch stark experimentell.

Beispielnutzung

Das Folgende zeigt, wie Sie mit der Spatial-Erweiterung mehrere geospatiale Formate lesen und exportieren, Geometrien zwischen Koordinatenreferenzsystemen transformieren und mit räumlichen Eigenschafts- und Prädikatfunktionen arbeiten. Das Beispiel ist etwas konstruiert, soll aber die derzeit verfügbaren Möglichkeiten zeigen. Die verwendeten Datensätze liegen im Repository der Spatial-Erweiterung.

Wir importieren die NYC-Taxi-Fahrten im Parquet-Format sowie die dazugehörigen Taxi-Zonen aus einem Shapefile, über die Tabellenfunktion ST_Read der Spatial-Erweiterung. Diese Taxi-Zonen zerlegen NYC in Polygone, die Regionen darstellen, etwa den Newark Airport. Dann legen wir eine Tabelle für die Fahrten und eine für die Zonen an. ST_Read erzeugt eine Tabelle mit einer Spalte wkb_geometry, die die Geometrie als WKB-Blob (Well-Known Binary) enthält; wir wandeln sie mit ST_GeomFromWKB in den Typ GEOMETRY um.

Das mag viel wirken, wenn Sie das geospatiale Ökosystem nicht kennen – zum Einstieg reicht das aber. Kurz: – Shapefile (.shp, .shx, .dbf) ist ein gängiges Format für Geometrie-Vektordaten und Hilfsmetadaten wie Indizes und Attribute. – WKB (Well Known Binary) ist selbst kein Dateiformat, aber eine gängige Binärkodierung von Vektorgeometrie, etwa in GeoParquet. Es gibt mehrere Varianten; uns geht es vorerst um „standard“-WKB. – GEOMETRY ist ein DuckDB-Typ für ein Simple-Features-Geometrieobjekt. Die Standards modellieren Vektorgeometrie als Punkte, Linestrings, Polygone oder Sammlungen davon. Das ist der Kern-Datentyp der Spatial-Erweiterung, den die meisten Funktionen entgegennehmen und zurückgeben.

INSTALL spatial;
LOAD spatial;
CREATE TABLE rides AS
SELECT *
FROM 'yellow_tripdata_2010-01-limit1mil.parquet';
-- Load the NYC taxi zone data from a shapefile using the gdal-based ST_Read function
CREATE TABLE zones AS
SELECT zone, LocationId, borough, geom
FROM ST_Read('taxi_zones/taxi_zones.shx');

Vergleichen wir die Fahrstrecke mit der linearen Distanz zwischen Abhol- und Absetzpunkt, um zu sehen, wie effizient die Taxifahrer sind (oder wie schmutzig die Daten, denn manche Differenzen wirken negativ). Wir transformieren die Koordinaten von „WGS84“ (Kennung EPSG:4326), auch einfach Breite/Länge genannt, ins Koordinatenreferenzsystem „NAD83 / New York Long Island ftUS“ (ESRI:102718) – eine Projektion mit geringer Verzerrung um New York. Die Distanz berechnen wir mit ST_Distance. Hier erhalten wir Fuß, weil wir nach NAD83 gewandelt haben; in Meilen (5280 ft/Meile) umrechnen – die Einheit des Fahrten-Datensatzes – ist einfach, damit der Vergleich stimmt.

Moment, was haben Koordinatenreferenzsysteme und Projektionen damit zu tun? > Die Erde ist nicht flach, manchmal ist es aber nützlich, so zu tun und Koordinaten auf eine Fläche zu „projizieren“. Die „Parameter“ einer Projektion – wo der „Ursprung“ liegt, in welcher Einheit Koordinaten stehen, wie die Erdform angenähert wird – stecken in einem „Spatial Reference System“ oder „Coordinate Reference System“ (CRS), meist über eine Kurzkennung aus Authority und Code, z. B. „EPSG:4326“ oder „ESRI:102718“. Projektionen sind immer verlustbehaftet; wichtig ist ein CRS, das zum „Gebiet von Interesse“ Ihrer Daten passt. Die Spatial-Erweiterung nutzt die Bibliothek [PROJ](https://proj.org/) für Koordinatenreferenzsysteme und Projektionen.

Fahrten, die kürzer sind als die Luftlinie, sind wahrscheinlich fehlerhaft; mit dieser Abfrage filtern wir schlechte Daten. Die Abfrage nutzt DuckDBs Möglichkeit, auf in demselben Select definierte Spaltenaliase zu verweisen. Ein kleines Beispiel, wie DuckDBs reicher SQL-Dialekt geospatiale Analyse vereinfacht.

CREATE TABLE cleaned_rides AS
SELECT
ST_Point(pickup_latitude, pickup_longitude) AS pickup_point,
ST_Point(dropoff_latitude, dropoff_longitude) AS dropoff_point,
dropoff_datetime::TIMESTAMP - pickup_datetime::TIMESTAMP AS time,
trip_distance,
ST_Distance(
ST_Transform(pickup_point, 'EPSG:4326', 'ESRI:102718'),
ST_Transform(dropoff_point, 'EPSG:4326', 'ESRI:102718')) / 5280
AS aerial_distance,
trip_distance - aerial_distance AS diff
FROM rides
WHERE diff > 0
ORDER BY diff DESC;
`SELECT * FROM rides LIMIT 10;`
vendor_id pickup_datetime dropoff_datetime passenger_count trip_distance pickup_longitude pickup_latitude rate_code store_and_fwd_flag dropoff_longitude dropoff_latitude payment_type fare_amount surcharge mta_tax tip_amount tolls_amount total_amount
VTS 2010-01-01 00:00:17 2010-01-01 00:00:17 3 0.0 -73.87105699999998 40.773522 1 -73.871048 40.773545 CAS 45.0 0.0 0.5 0.0 0.0 45.5
VTS 2010-01-01 00:00:20 2010-01-01 00:00:20 1 0.05 -73.97512999999998 40.789973 1 -73.97498799999998 40.790598 CAS 2.5 0.5 0.5 0.0 0.0 3.5
CMT 2010-01-01 00:00:23 2010-01-01 00:00:25 1 0.0 -73.999431 40.71216 1 0 -73.99915799999998 40.712421 No 2.5 0.5 0.5 0.0 0.0 3.5
CMT 2010-01-01 00:00:33 2010-01-01 00:00:55 1 0.0 -73.97721699999998 40.749633 1 0 -73.97732899999998 40.749629 Cas 2.5 0.5 0.5 0.0 0.0 3.5
VTS 2010-01-01 00:01:00 2010-01-01 00:01:00 1 0.0 -73.942313 40.784332 1 -73.942313 40.784332 Cre 10.0 0.0 0.5 2.0 0.0 12.5
VTS 2010-01-01 00:01:06 2010-01-01 00:01:06 2 0.38 -73.97463 40.756687 1 -73.979872 40.759143 CAS 3.7 0.5 0.5 0.0 0.0 4.7
VTS 2010-01-01 00:01:07 2010-01-01 00:01:07 2 0.23 -73.987358 40.718475 1 -73.98518 40.720468 CAS 2.9 0.5 0.5 0.0 0.0 3.9
CMT 2010-01-01 00:00:02 2010-01-01 00:01:08 1 0.1 -73.992807 40.741418 1 0 -73.995799 40.742596 No 2.9 0.5 0.5 0.0 0.0 3.9
VTS 2010-01-01 00:01:23 2010-01-01 00:01:23 1 0.6099999999999999 -73.98003799999998 40.74306 1 -73.974862 40.750387 CAS 3.7 0.5 0.5 0.0 0.0 4.7
VTS 2010-01-01 00:01:34 2010-01-01 00:01:34 1 0.02 -73.954122 40.801173 1 -73.95431499999998 40.800897 CAS 45.0 0.0 0.5 0.0 0.0 45.5
`SELECT * FROM zones LIMIT 10;`
zone LocationID borough geom
Newark Airport 1 EWR POLYGON (…)
Jamaica Bay 2 Queens MULTIPOLYGON (…)
Allerton/Pelham Gardens 3 Bronx POLYGON (…)
Alphabet City 4 Manhattan POLYGON (…)
Arden Heights 5 Staten Island POLYGON (…)
Arrochar/Fort Wadsworth 6 Staten Island POLYGON (…)
Astoria 7 Queens POLYGON (…)
Astoria Park 8 Queens POLYGON (…)
Auburndale 9 Queens POLYGON (…)
Baisley Park 10 Queens POLYGON (…)

Das ist nicht ganz genau, weil die von uns genutzte Funktion ST_Distance die Erdkrümmung nicht berücksichtigt. Für unsere Zwecke reicht die Näherung. Sphärische und geodätische Distanzberechnungen stehen auf der Roadmap!

Jetzt joinen wir die Taxifahrten mit den Taxi-Zonen, um Start- und Endzone jeder Fahrt zu bekommen. Als Join-Bedingung nutzen wir ST_Within, um zu prüfen, ob ein Abhol- oder Absetzpunkt in einem Taxi-Zonen-Polygon liegt. Wieder müssen wir von WGS84 nach NAD83 transformieren, weil die Zonendaten dieselbe Projektion nutzen. Räumliche Joins wie diese sind das tägliche Brot geospatialer Verarbeitung; Optimierungen (etwa räumliche Indizes) haben wir dafür noch nicht, deshalb nutzen wir im nächsten Schritt nur eine Teilmenge der Daten.

-- Since we don't have spatial indexes yet, use a smaller dataset for the join.
DELETE FROM cleaned_rides WHERE rowid > 5000;
CREATE TABLE joined AS
SELECT
pickup_point,
dropoff_point,
start_zone.zone AS start_zone,
end_zone.zone AS end_zone,
trip_distance,
time,
FROM cleaned_rides
JOIN zones AS start_zone
ON ST_Within(ST_Transform(pickup_point, 'EPSG:4326', 'ESRI:102718'), start_zone.geom)
JOIN zones AS end_zone
ON ST_Within(ST_Transform(dropoff_point, 'EPSG:4326', 'ESRI:102718'), end_zone.geom);
`SELECT * FROM joined USING SAMPLE 10 ROWS;`
pickup_point dropoff_point start_zone end_zone trip_distance time
POINT (40.722223 -73.98385299999998) POINT (40.715507 -73.992438) East Village Lower East Side 10.3 00:19:16
POINT (40.648687 -73.783522) POINT (40.649567 -74.005812) JFK Airport Sunset Park West 23.57 00:28:00
POINT (40.761603 -73.96661299999998) POINT (40.760232 -73.96344499999998) Upper East Side South Sutton Place/Turtle Bay North 17.6 00:27:05
POINT (40.697212 -73.937495) POINT (40.652377 -73.93983299999998) Stuyvesant Heights East Flatbush/Farragut 13.55 00:24:00
POINT (40.721462 -73.993583) POINT (40.774205 -73.90441699999998) Lower East Side Steinway 28.75 01:03:00
POINT (40.716955 -74.004328) POINT (40.754688 -73.991612) TriBeCa/Civic Center Garment District 18.4 00:46:12
POINT (40.740052 -73.994918) POINT (40.75439 -73.98587499999998) Flatiron Garment District 24.2 00:35:25
POINT (40.763017 -73.95949199999998) POINT (40.763615 -73.959182) Lenox Hill East Lenox Hill West 18.4 00:33:46
POINT (40.865663 -73.927458) POINT (40.86537 -73.927352) Washington Heights North Washington Heights North 10.47 00:27:00
POINT (40.738408 -73.980345) POINT (40.696038 -73.955493) Gramercy Bedford 16.4 00:21:47

Die gejointe Tabelle können wir mit der GDAL-Copy-Funktion in eine GeoJSONSeq-Datei exportieren und eine GDAL-Layer-Creation-Option übergeben. GeoJSON unterstützt nur eine GEOMETRY pro Datensatz; mit ST_MakeLine kombinieren wir Abhol- und Absetzpunkt zu einer Liniengeometrie. Das Standard-CRS für GeoJSON ist WGS84, die Koordinatenpaare werden aber als Länge/Breite erwartet, daher drehen wir die Geometrie mit ST_FlipCoordinates.

COPY (
SELECT
ST_MakeLine(pickup_point, dropoff_point)
.ST_FlipCoordinates()
.ST_AsWKB()
AS wkb_geometry,
start_zone,
end_zone,
time::VARCHAR AS trip_time
FROM joined)
TO 'joined.geojsonseq'
WITH (
FORMAT gdal,
DRIVER 'GeoJSONSeq',
LAYER_CREATION_OPTIONS 'WRITE_BBOX=YES'
);
`head -n 10 joined.geojsonseq`
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:52:00" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.789923, 40.643515 ], [ -73.97608, 40.680395 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:35:00" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.776445, 40.645422 ], [ -73.98427, 40.670782 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:45:42" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.776878, 40.645065 ], [ -73.992153, 40.662571 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:36:00" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.788028, 40.641508 ], [ -73.97584, 40.670927 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:47:58" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.781855, 40.644749 ], [ -73.980129, 40.663663 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:32:10" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.787494, 40.641559 ], [ -73.974694, 40.673479 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:36:59" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.790138, 40.643342 ], [ -73.982721, 40.662379 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:32:00" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.786952, 40.641248 ], [ -73.97421, 40.676237 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:33:21" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.783892, 40.648514 ], [ -73.979283, 40.669721 ] ] } }
{ "type": "Feature", "properties": { "start_zone": "JFK Airport", "end_zone": "Park Slope", "trip_time": "00:35:45" }, "geometry": { "type": "LineString", "coordinates": [ [ -73.776643, 40.645272 ], [ -73.978873, 40.66723 ] ] } }

Fertig! Wir haben tabellarische Daten aus Parquet geholt, mit geospatialen Daten aus einem Shapefile kombiniert, die kombinierten Daten bereinigt und analysiert und ins menschenlesbare geospatiale Format geschrieben. Die derzeit unterstützten Funktionen und ihr Umsetzungsstand stehen in der Dokumentation in dieser Tabelle.

Wie geht es weiter?

Bis wir den vollen Funktionsumfang von z. B. PostGIS erreichen, wird es dauern. DuckDBs vektorisiertes Ausführungsmodell und spaltenorientiertes Speicherformat sollten aber eine neue Klasse von Optimierungen für geospatiale Verarbeitung ermöglichen, die wir gerade erst erkunden. Die Leistung räumlicher Joins und Prädikate steht daher weit oben auf der Liste.

Es gibt auch Grenzen unseres Typs GEOMETRY, die wir angehen wollen: keine zusätzlichen Z- und M-Dimensionen und nicht die volle Bandbreite der vom OGC-Standard geforderten Geometrie-Subtypen wie Kurven oder polyedrische Flächen.

Sphärische und ellipsoidische Berechnungen wollen wir bald unterstützen, vielleicht als eigenen Typ GEOGRAPHY.

Wasm-Builds stehen ebenfalls kurz bevor!

Die vollständige Roadmap und den aktuellen Stand finden Sie im GitHub-Repository. Wenn Sie beim Aufbau helfen wollen, melden Sie sich auf GitHub!

Fazit

Die DuckDB-Spatial-Erweiterung ist ein weiterer Schritt, DuckDB zum Schweizer Taschenmesser für Data Engineering und Analytics zu machen. Sie liefert einen flexiblen, vertrauten Typ GEOMETRY, reprojizierbar zwischen Tausenden von Koordinatenreferenzsystemen, plus Import und Export geospatialer Daten aus über 50 Quellen. Alles in einer Erweiterung mit minimalen Laufzeitabhängigkeiten. DuckDB fügt sich so in bestehende GIS-Workflows ein, unabhängig von Format oder Projektion.

Wir sind gespannt, was Sie aus der DuckDB-Spatial-Erweiterung machen. Es ist noch früh, aber wir hoffen, bald mehr teilen zu können! Fragen, Vorschläge, Ideen oder Issues gern auf Discord oder GitHub.