6.3 GeoPackage and SpatiaLite
The modern SQLite-based replacement for shapefile — one file, many layers, real SQL.
Key takeaways
- GeoPackage is a single-file container for vector, raster, and attribute data — an OGC standard built on SQLite.
- SpatiaLite adds full spatial SQL (like PostGIS) to SQLite — excellent for local analysis.
- Together they're the "modern desktop GIS" storage pattern.
Introduction
Shapefile worked for 30 years, but we've learned its limits. GeoPackage (OGC, 2014) is its thoughtful successor — a single SQLite file containing multiple layers, rich attribute types, and spatial metadata, ratified as the official OGC standard. SpatiaLite (2008, predecessor in spirit) adds spatial SQL functions on top of SQLite so you can run PostGIS-style queries without a server. Both formats store your data in a disk file you can email or copy.
Why GeoPackage
A GeoPackage (.gpkg) is:
- A single file — no more shape/dbf/shx/prj/cpg confusion.
- SQLite-based — any SQLite tool can open it.
- Multiple layers — vector, raster, attribute-only tables in one container.
- OGC standard — every major GIS reads and writes it.
- Supports all simple feature geometry types.
- Arbitrary field names, types, and lengths.
- Embedded CRS metadata per layer.
- Scales into tens of GB without the 2 GB shapefile ceiling.
Reading in Python:
import geopandas as gpdWriting multiple layers:
1parks.to_file('atlas_data.gpkg', layer='parks', driver='GPKG')
2schools.to_file('atlas_data.gpkg', layer='schools', driver='GPKG')The GeoPackage data model
A GeoPackage has reserved tables:
gpkg_contents— registry of all layers.gpkg_spatial_ref_sys— CRS definitions.gpkg_geometry_columns— geometry column metadata per layer.gpkg_tile_matrix_set/gpkg_tile_matrix— for raster tile pyramids.
Your data sits in regular SQLite tables with one geometry column storing features as GeoPackage Binary (derived from WKB).
SpatiaLite
SpatiaLite extends SQLite with:
- Full vector spatial types (Point, LineString, Polygon, Multi-*).
- ~400 spatial functions (ST_Buffer, ST_Intersects, ST_DWithin, ...).
- Spatial indexes (R*Tree).
- Topology (the Topo-GEO extension).
Think "PostGIS without a server, in a single file". It's perfect for local analysis, lightweight web services, and edge deployment.
GeoPackage vs SpatiaLite
They're different but overlap:
- GeoPackage is a storage format (standard, minimal functionality).
- SpatiaLite is a spatial extension to SQLite (rich SQL, less standard).
You can store a GeoPackage-compliant schema in a SpatiaLite-extended database, giving you both standard exchange and rich SQL. Many tools handle both.
Spatial SQL in SpatiaLite
1-- Parks within 500 m of schools
2SELECT p.name, s.name AS school
3FROM parks p
4JOIN schools s ON ST_DWithin(p.geom, s.geom, 500)
5ORDER BY ST_Distance(p.geom, s.geom);1-- Buffer then dissolve
2SELECT ST_Union(ST_Buffer(geom, 100))
3FROM coastline;1-- Count points per polygon
2SELECT d.id, d.name, COUNT(p.id) AS n_trees
3FROM districts d
4LEFT JOIN trees p ON ST_Within(p.geom, d.geom)
5GROUP BY d.id;Module 8 covers spatial SQL in depth.
Raster tiles in GeoPackage
Beyond vectors, GeoPackage supports raster tile pyramids — the same slippy-map structure as web tiles, stored inside the SQLite file. Useful for:
- Offline field GIS (a region's basemap in one file).
- Bundling imagery with vectors.
- Serving tiles from the database directly.
Editing
GeoPackage supports concurrent reads but single-writer locking (SQLite limitation). For multi-user editing, move to PostGIS. For solo or small-team edits, GeoPackage is excellent.
Performance
- Reads — fast; SQLite is well-optimised.
- Writes — slower than pure binary formats (shapefile) but usually acceptable.
- Queries — the R-tree spatial index keeps point-in-polygon etc. at sub-second for millions of features.
Run VACUUM after heavy edits to reclaim space and rebuild indexes.
Tooling
- QGIS — first-class GeoPackage support; default save format in modern versions.
- GDAL/OGR — full read/write via
ogr2ogr. sqlite3CLI — direct SQL access.- DB Browser for SQLite — GUI to inspect schemas and data.
- PyGeoPackage, python-geopackage — lighter-weight Python libraries.
For review and sharing, a GeoPackage exported to GeoJSON or a smaller derived layer can be brought into Atlas. This is a useful pattern after local analysis: keep the full multi-layer GeoPackage as your working file, then publish the result layer as a browser-friendly map for teammates.
When to prefer GeoPackage
- Any time you'd reach for a shapefile. Seriously.
- Local analysis across multiple related layers.
- Offline data bundles (field apps, mobile).
- Interchange when the recipient uses a modern GIS.
When to prefer something else
- Very large data (>50 GB) — PostGIS or GeoParquet.
- Concurrent multi-writer — PostGIS.
- Web consumption in the browser — GeoJSON or FlatGeobuf.
- Cloud-native streaming — FlatGeobuf, PMTiles, or COG.
Self-check exercises
1. What's the single biggest advantage of GeoPackage over shapefile?
One file instead of several. No more "did I send the .prj?" It also removes shapefile's 10-character field limit, 2 GB size cap, and one-geometry-type-per-file restriction — any one of those can be a blocker.
2. You need spatial joins across a million features on a laptop. PostGIS overkill; shapefile can't. What's the sweet spot?
A GeoPackage opened with SpatiaLite extensions. You get PostGIS-style ST_Join, ST_DWithin, and spatial indexes in a single file with no server. QGIS and Python's sqlite3 + spatialite both handle this smoothly.
3. How do you store parks, schools, and a road network in one file?
As separate layers in the same GeoPackage: parks.to_file('city.gpkg', layer='parks'); schools.to_file('city.gpkg', layer='schools'); roads.to_file('city.gpkg', layer='roads'). Each layer has its own schema and CRS. Shapefile can't do this.
Summary
- GeoPackage is the modern shapefile replacement — one file, many layers, rich types, OGC standard.
- SpatiaLite turns SQLite into a mini-PostGIS for local analysis.
- Together they cover most desktop GIS storage and analysis needs without a database server.
Further reading
- OGC — GeoPackage Encoding Standard 1.4.
- SpatiaLite documentation — function reference.
- QGIS Documentation — Working with GeoPackage.
- "GeoPackage: the default for shared geographic data" — GitHub repositories and migration guides.