/spatial
Answer questions about spatial data using DuckDB. Use when the user mentions locations, coordinates, lat/lng, distances, maps, addresses, "near", "within", "closest", geographic names, or spatial file formats (GeoJSON, Shapefile, GeoPackage, GPX, GeoParquet). Also triggers when
$ npx -y skills add duckdb/duckdb-skills --skill spatial --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/spatial
Context preview
The summary Claude sees to decide when to auto-load this skill.
Answer questions about spatial data using DuckDB. Use when the user mentions locations, coordinates, lat/lng, distances, maps, addresses, "near", "within", "closest", geographic names, or spatial file formats (GeoJSON, Shapefile, GeoPackage, GPX, GeoParquet). Also triggers when
SKILL.md
spatial.SKILL.mdname: spatial
description: >
Answer questions about spatial data using DuckDB. Use when the user mentions locations,
coordinates, lat/lng, distances, maps, addresses, "near", "within", "closest", geographic
names, or spatial file formats (GeoJSON, Shapefile, GeoPackage, GPX, GeoParquet). Also
triggers when the user wants to find places, buildings, or roads — Overture Maps provides
free global data on S3 with zero API keys. Handles spatial joins, distance calculations,
containment checks, density analysis, and format conversions for geographic data.
argument-hint: <question or file> [additional context]
allowed-tools: Bash
You are answering spatial questions using DuckDB's spatial extension and, when needed, Overture Maps as a free global data source.
Question or file: `$0` Additional context: `${1:-}`
Step 1 — Understand what the user needs
Classify the question:
| Pattern | Data source | Key functions | |---------|-------------|---------------| | "Find X near Y" (no user file) | Overture Maps on S3 | `ST_Distance_Spheroid`, bbox filtering | | "How far between A and B" | Geocode or user data | `ST_Distance_Spheroid` | | "Which points fall inside polygons" | User files | `ST_Contains` | | "Analyze this GeoJSON/Shapefile/GPX" | User file | `ST_Read`, measurement functions | | "Show density/hotspots" | User or Overture data | H3 hex binning | | "Convert to GeoJSON/GeoPackage" | User file | `COPY TO (FORMAT GDAL)` | | "Count buildings/roads in area" | Overture Maps | bbox filtering + aggregation |
If the question involves real-world places, POIs, buildings, roads, or boundaries and the user hasn't provided a file, use **Overture Maps** — read `references/overture.md` for S3 paths and schema.
For spatial function syntax, read `references/functions.md`.
Step 2 — Write and run the query
Always start with:
LOAD spatial;
SET geometry_always_xy = true;
Add extensions as needed:
- Overture/remote data: `LOAD httpfs; CREATE SECRET (TYPE S3, PROVIDER config, REGION 'us-west-2');`
- H3 hex binning: `INSTALL h3 FROM community; LOAD h3;`
Key principles
**bbox filtering first** — When querying Overture, always filter on `bbox.xmin/xmax/ymin/ymax` before any spatial function. This uses Parquet predicate pushdown and avoids downloading the full dataset.
**Always set `geometry_always_xy = true`** — This ensures all spatial functions interpret coordinates as longitude, latitude (the standard for Overture, GeoJSON, and most data sources). Without it, spheroid functions assume latitude first and return wrong results.
**Use spheroid functions for real-world distances** — `ST_Distance_Spheroid` returns meters on the WGS84 ellipsoid. Plain `ST_Distance` uses planar coordinates and gives meaningless results for lat/lng. **Important:** spheroid functions (`ST_Distance_Spheroid`, `ST_Area_Spheroid`, etc.) require `POINT_2D` inputs, not generic `GEOMETRY`. Overture geometry columns are typed `GEOMETRY('OGC:CRS84')` and cannot be cast directly. Extract coordinates first:
ST_Point(ST_X(geometry), ST_Y(geometry))::POINT_2D
**CSV with lat/lng needs conversion** — `ST_Point(longitude, latitude)` (longitude first). This is the most common gotcha.
Run the query in a single bash call:
duckdb -c "
LOAD spatial;
<ADDITIONAL_SETUP>
<YOUR_QUERY>
"
Step 3 — Present results
- For tabular results: show the data directly
- For spatial results: consider exporting to GeoJSON for visualization (`COPY TO 'result.geojson' WITH (FORMAT GDAL, DRIVER 'GeoJSON')`)
- For distance/area results: use human-readable units (km for large distances, m for small)
- For density/hotspot results: describe the pattern and offer to export for visualization
If the query fails:
- **`duckdb: command not found`** → delegate to `/duckdb-skills:install-duckdb`
- **Missing extension** → `INSTALL spatial; LOAD spatial;` or `INSTALL h3 FROM community; LOAD h3;`
- **S3 access denied** → suggest checking AWS credentials
- **No results with Overture** → widen the bbox, check the category spelling, or try a broader search
Read more
name: spatial description: > Answer questions about spatial data using DuckDB. Use when the user mentions locations, coordinates, lat/lng, distances, maps, addresses, "near", "within", "closest", geographic names, or spatial file formats (GeoJSON, Shapefile, GeoPackage, GPX, GeoParquet). Also triggers when the user wants to find places, buildings, or roads — Overture Maps provides free global data on S3 with zero API keys. Handles spatial joins, distance calculations, containment checks, density analysis, and format conversions for geographic data. argument-hint: <question or file> [additional context] allowed-tools: Bash
You are answering spatial questions using DuckDB's spatial extension and, when needed, Overture Maps as a free global data source.
Question or file: `$0` Additional context: `${1:-}`
Step 1 — Understand what the user needs
Classify the question:
| Pattern | Data source | Key functions | |---------|-------------|---------------| | "Find X near Y" (no user file) | Overture Maps on S3 | `ST_Distance_Spheroid`, bbox filtering | | "How far between A and B" | Geocode or user data | `ST_Distance_Spheroid` | | "Which points fall inside polygons" | User files | `ST_Contains` | | "Analyze this GeoJSON/Shapefile/GPX" | User file | `ST_Read`, measurement functions | | "Show density/hotspots" | User or Overture data | H3 hex binning | | "Convert to GeoJSON/GeoPackage" | User file | `COPY TO (FORMAT GDAL)` | | "Count buildings/roads in area" | Overture Maps | bbox filtering + aggregation |
If the question involves real-world places, POIs, buildings, roads, or boundaries and the user hasn't provided a file, use **Overture Maps** — read `references/overture.md` for S3 paths and schema.
For spatial function syntax, read `references/functions.md`.
Step 2 — Write and run the query
Always start with:
LOAD spatial; SET geometry_always_xy = true;
Add extensions as needed:
- Overture/remote data: `LOAD httpfs; CREATE SECRET (TYPE S3, PROVIDER config, REGION 'us-west-2');`
- H3 hex binning: `INSTALL h3 FROM community; LOAD h3;`
Key principles
**bbox filtering first** — When querying Overture, always filter on `bbox.xmin/xmax/ymin/ymax` before any spatial function. This uses Parquet predicate pushdown and avoids downloading the full dataset.
**Always set `geometry_always_xy = true`** — This ensures all spatial functions interpret coordinates as longitude, latitude (the standard for Overture, GeoJSON, and most data sources). Without it, spheroid functions assume latitude first and return wrong results.
**Use spheroid functions for real-world distances** — `ST_Distance_Spheroid` returns meters on the WGS84 ellipsoid. Plain `ST_Distance` uses planar coordinates and gives meaningless results for lat/lng. **Important:** spheroid functions (`ST_Distance_Spheroid`, `ST_Area_Spheroid`, etc.) require `POINT_2D` inputs, not generic `GEOMETRY`. Overture geometry columns are typed `GEOMETRY('OGC:CRS84')` and cannot be cast directly. Extract coordinates first:
ST_Point(ST_X(geometry), ST_Y(geometry))::POINT_2D
**CSV with lat/lng needs conversion** — `ST_Point(longitude, latitude)` (longitude first). This is the most common gotcha.
Run the query in a single bash call:
duckdb -c " LOAD spatial; <ADDITIONAL_SETUP> <YOUR_QUERY> "
Step 3 — Present results
- For tabular results: show the data directly
- For spatial results: consider exporting to GeoJSON for visualization (`COPY TO 'result.geojson' WITH (FORMAT GDAL, DRIVER 'GeoJSON')`)
- For distance/area results: use human-readable units (km for large distances, m for small)
- For density/hotspot results: describe the pattern and offer to export for visualization
If the query fails:
- **`duckdb: command not found`** → delegate to `/duckdb-skills:install-duckdb`
- **Missing extension** → `INSTALL spatial; LOAD spatial;` or `INSTALL h3 FROM community; LOAD h3;`
- **S3 access denied** → suggest checking AWS credentials
- **No results with Overture** → widen the bbox, check the category spelling, or try a broader search
A Claude Code plugin that adds DuckDB-powered skills for data exploration and session memory.
Repo: duckdb/duckdb-skills
Other skills on duckdb-skills.
- /attach-db
Attach a DuckDB database file for use with /duckdb-skills:query. Explores the schema (tables, columns, row counts) and writes a SQL state file so subsequent queries can restore this session automatically via duckdb -init.
Open skill - /convert-file
Convert any data file to another format: CSV, Parquet, JSON, Excel, GeoJSON, and more. Use when the user says "convert to parquet", "save as xlsx", "export as JSON", "make this a CSV", "turn into parquet", or any variation of format-to-format conversion for data files. Also
Open skill - /duckdb-docs
Search DuckDB and DuckLake documentation and blog posts. Returns relevant doc chunks for a question or keyword using full-text search against a locally cached index.
Open skill - /install-duckdb
Install or update DuckDB extensions. Each argument is either a plain extension name (installs from core) or name@repo (e.g. magic@community). Pass --update to update extensions instead of installing.
Open skill - /query
Run SQL queries against the attached DuckDB database or ad-hoc against files. Accepts raw SQL or natural language questions. Uses DuckDB Friendly SQL idioms.
Open skill - /read-file
Read any data file (CSV, JSON, Parquet, Avro, Excel, spatial, SQLite) or remote URL (S3, HTTPS). Use when user references a data file, asks "what's in this file", or wants to preview/profile a dataset. Not for source code.
Open skill

