Skip to content
  • Posts
  • Join the Spatial Lab
  • Learn Modern GIS
  • Sponsor
  • Coaching
  • Podcast

Get the newsletter

Join 71,000+ geospatial experts growing their skills and careers. Get updates on the most cutting edge updates in modern GIS and geospatial every week.

Edit Content
  • LinkedIn
  • YouTube
Tutorial

Convert a Shapefile to GeoParquet (Python, DuckDB, Sedona)

October 28, 2026 Matt Forrest No comments yet
Convert a Shapefile to GeoParquet (Python, DuckDB, Sedona)

I took a real Shapefile with almost 1.1 million polygons and converted it to GeoParquet three different ways. The file went from over 1.4 GB of source data down to 246 MB, opened cleanly in QGIS, and ran spatial queries in seconds instead of minutes.

The dataset was the New York City building footprints. Every building across the five boroughs. That is not a small file, and the Shapefile format was never built to carry it. If your work still lives in Shapefiles or other older formats, this guide shows you how to convert a Shapefile to GeoParquet and why the move is worth making.

The format change is not even the interesting part. What matters is what GeoParquet lets you do after the conversion. I will cover that at the end.

What Is GeoParquet?

Parquet is a columnar file format built for analytical systems and big data queries. GeoParquet adds a geometry column to that format, so you get one file that holds your attributes and your spatial data together.

Three things make GeoParquet fast:

  • Compression. The file size drops sharply compared to a Shapefile or GeoJSON because of how Parquet packs data.
  • Columnar storage. Your data is stored in columns, not rows. If your query needs 3 columns out of 10, the engine ignores 70% of the data right away.
  • Metadata and row groups. The file metadata holds the bounding box, so an engine can decide whether a file even falls inside your spatial query before reading it. Inside the file, row groups carry their own metadata, so the engine can skip whole chunks of rows that do not matter for the query.

Together, those features let a query engine prune data efficiently, read less from disk, and return results faster.

GeoParquet now has first-party support in QGIS 4, which was just released. You can drag and drop a GeoParquet file like any other layer. No third-party plugin needed. ArcGIS can read it too.

Shapefile vs GeoParquet

Shapefiles are not the worst thing in the world. They were an ingenious way to split geospatial data when GIS first needed it. The format separates the geometry (.shp), the attribute database (.dbf), and the projection (.prj) into different files, so a renderer only has to read the part it needs. That separation was smart design.

The problem is scale. A Shapefile is not one file. It is at least four files that you have to zip together to share, and if any one of them goes missing, the whole thing breaks.

Feature Shapefile GeoParquet
Number of files 4+ files, zipped together 1 file
Size limit 2 GB cap No practical cap
Attribute name length 10 characters max Full-length column names
Storage layout Row-based Columnar
Compression Limited Strong
Built for Desktop rendering Analytical queries at scale
Query pruning None Bounding box + row group metadata

For small datasets like neighborhood boundaries or a subset of roads, Shapefiles work fine. For a million building footprints, they fall over. The NYC building data was so large I had to download it as GeoJSON and convert it to a Shapefile just to set up this demo, and even then GeoJSON has its own limit because it packs everything into one uncompressed file.

The Tools You Will Use

Four technologies show up in this workflow, and they all sit on top of one engine.

  • GDAL (Geospatial Data Abstraction Library) is the translation layer that turns one format into another. I call it the Rosetta Stone of geospatial data. You use it even when you do not know you are using it, because QGIS, GeoPandas, and DuckDB all rely on it under the hood.
  • GeoPandas is a Python library that reads spatial data into a DataFrame, a temporary data object you can work with in memory.
  • DuckDB is an analytics engine with a spatial extension. It runs SQL on in-memory and Parquet-backed data and scales to large volumes.
  • Apache Sedona (Sedona DB) is a query layer focused purely on spatial work. It reads GeoParquet efficiently and handles projections better than the alternatives.

A note on installation. GeoPandas can hit dependency issues with pip because it needs Shapely, PyProj, and Pyogrio, which leans on GDAL. DuckDB avoids most of that because its spatial extension bundles GDAL for you. On a Mac I install GDAL with Homebrew (brew install gdal). On Windows, OSGeo4W is a solid package for getting GDAL in place.

Method 1: Convert a Shapefile to GeoParquet With Python and GeoPandas

This is the cleanest path. Read the Shapefile into a GeoPandas DataFrame, then write it straight to GeoParquet.

import geopandas as gpd

# Read the Shapefile into a GeoDataFrame
buildings_gpd = gpd.read_file("buildings.shp")

# Inspect the first rows to confirm it loaded correctly
buildings_gpd.head()

# Write it out as GeoParquet
buildings_gpd.to_parquet("buildings.parquet")

That is the whole conversion. Reading the 1.08 million building Shapefile took about 21 seconds. The output GeoParquet file came out to 246 MB, down from over 1.4 GB of source data and a 1 GB GeoJSON. No errors. Drag the .parquet file into QGIS 4 and it loads, pans, and zooms far more smoothly than the original.

Method 2: Convert a Shapefile to GeoParquet With DuckDB

DuckDB lets you do the same conversion in SQL. There are a few more steps because you set up a connection, install the spatial extension, read the Shapefile, create a table, then write it back out.

import duckdb

# Open a DuckDB connection
con = duckdb.connect()

# Install and load the spatial extension
con.execute("INSTALL spatial;")
con.execute("LOAD spatial;")

# Read the Shapefile directly into a DataFrame using ST_Read
con.execute("SELECT * FROM ST_Read('buildings.shp')").df()

# Create a table from the Shapefile, then write it to GeoParquet
con.execute("CREATE TABLE buildings AS SELECT * FROM ST_Read('buildings.shp')")
con.execute("COPY buildings TO 'buildings_duckdb.parquet' (FORMAT PARQUET)")

ST_Read uses GDAL under the hood to read the Shapefile. Because the spatial extension knows the geometry column, DuckDB can write native Parquet directly. The output file is roughly the same size as the GeoPandas version.

The advantage of this route is that the data is in memory as a table the moment you read it, so you can run spatial SQL against it before you ever write a file. For example:

SELECT ST_Area(geom) AS area FROM buildings;

One thing to watch: the NYC data is in EPSG:4326, so an area calculation in degrees returns meaningless numbers until you transform to a projected coordinate system. That transformation adds work, which is where the next tool earns its place.

Method 3: Query GeoParquet With Apache Sedona

Once you have GeoParquet, the real payoff is fast spatial analysis. Apache Sedona reads GeoParquet efficiently and handles coordinate reference systems more cleanly than the others. The smooth path is to read with GeoPandas, hand the DataFrame to Sedona, register a view, and run spatial SQL.

import sedona.db

# Create a Sedona connection
sd = sedona.db.connect()

# Bring the GeoPandas GeoDataFrame into Sedona as a Sedona DataFrame
buildings = sd.create_data_frame(buildings_gpd)

# Register it as a view so you can run SQL against it
buildings.to_view("buildings")

Loading the million-building frame into Sedona took about 2 seconds. Now you can run spatial queries. Calculating area in EPSG:4326 returns the wrong values, so transform to EPSG:2263, the Long Island State Plane projection that New York City is measured in.

result = sd.sql("""
    SELECT ST_Area(ST_Transform(geom, 'EPSG:4326', 'EPSG:2263')) AS area
    FROM buildings
""")
result.show()

That returns the area in feet in the correct projection, and it returns it fast. You can also reshape the output and write it back to GeoParquet. Here I keep the area, compute a centroid, and transform both:

query = sd.sql("""
    SELECT
        ST_Area(ST_Transform(geom, 'EPSG:4326', 'EPSG:2263')) AS area,
        ST_Transform(ST_Centroid(geom), 'EPSG:4326', 'EPSG:2263') AS geometry
    FROM buildings
""")

# Write the result to GeoParquet
query.to_parquet("buildings_sedona.parquet")

The Sedona output came out to 24 MB. Dropping it into QGIS loaded the centroids and areas with no issues.

Which Method Should You Use?

For a one-time conversion or all-desktop work, GeoPandas is the simplest. Read in, write out, done.

DuckDB is a strong choice when you want to run SQL against the data during the conversion, or when you need to write out partitioned files.

For heavy spatial logic on large data, push the work into Sedona. GeoPandas reads the Shapefile in cleanly, then Sedona handles the querying, transformations, and final output. Keep your file-reading logic in GeoPandas and your querying logic in Sedona, and the results scale well.

The point is to use the right system for each step instead of forcing everything through one tool.

FAQ

What is GeoParquet used for?

GeoParquet stores vector geospatial data in a compressed columnar format built for analytical queries. It is used to convert large datasets out of Shapefiles and GeoJSON, run fast spatial analysis in tools like DuckDB and Apache Sedona, and store data for cloud-native workflows.

Is GeoParquet better than Shapefile?

For large datasets, yes. GeoParquet is one file instead of four, has no 2 GB cap, no 10-character attribute name limit, compresses far better, and prunes data using bounding box and row group metadata. Shapefiles still work fine for small desktop datasets.

Can QGIS open GeoParquet files?

Yes. QGIS 4 added first-party GeoParquet support, so you can drag and drop a .parquet file as a layer with no plugin. ArcGIS can read GeoParquet as well.

How do I convert a Shapefile to Parquet in Python?

Read the Shapefile with geopandas.read_file() and write it with .to_parquet(). That two-line workflow handles the conversion, including the geometry column.

Go Deeper on Cloud-Native Geospatial

This tutorial covers the first hurdle: getting out of the Shapefile world and into modern formats. If you want to learn the architecture behind these tools, when to reach for GDAL, DuckDB, or Sedona, and how to build scalable pipelines, that is what I teach inside the Spatial Lab. You get a roadmap tailored to where you are now, a library of trainings, and live sessions where we work through this in detail.

Join the Spatial Lab: forrest.nyc/go/lab/

  • Apache Sedona
  • duckdb
  • geoparquet
  • Python
Matt Forrest

Post navigation

Previous

Search

Categories

  • Article (29)
  • Essay (1)
  • Podcast (5)
  • Tutorial (7)

Recent posts

  • Convert a Shapefile to GeoParquet (Python, DuckDB, Sedona)
    Convert a Shapefile to GeoParquet (Python, DuckDB, Sedona)
  • I Gave Claude AI Full Control of QGIS: What Happened
    I Gave Claude AI Full Control of QGIS: What Happened
  • AI for GIS: 5 Prompts That Replace Hours of Work
    AI for GIS: 5 Prompts That Replace Hours of Work

Tags

aggregations Apache Airflow Apache Iceberg Apache Sedona ArcGIS bigquery Cloud-Native Geospatial Cloud GIS Cloud Optimized GeoTIFF duckdb Esri geoparquet geospatial gis GISP Modern GIS postgis Python snowflake Spatial SQL sql Wherobots zip codes

Related posts

Article

How to Build a Cloud-Native Spatial Data Lakehouse

July 3, 2025 Matt Forrest Comments Off on How to Build a Cloud-Native Spatial Data Lakehouse

Most spatial workflows today are still running on a foundation of folders, flat files, and fragile scripts. You’ve probably worked with shapefiles stored in six different places, Python notebooks that quietly break when a column changes, and a dozen versions of the same dataset ending in _final_v2_edit.shp. I’ve been there. But spatial data has changed. […]

Article

From Desktop GIS to Cloud: A Beginner’s Roadmap to Modern GIS Tool

March 7, 2025 Matt Forrest Comments Off on From Desktop GIS to Cloud: A Beginner’s Roadmap to Modern GIS Tool

Modern GIS is changing fast. If you’ve been working with QGIS, ArcGIS, or any other desktop GIS tool, you’ve probably hit some limitations—datasets getting too big, processing times slowing down, and collaboration becoming a challenge. The good news? The cloud offers a way forward. But how do you make that transition? How do you go […]

Article

The Top 11 Open GeoParquet Datasets: Making big geospatial data easy

January 18, 2024 Matt Forrest Comments Off on The Top 11 Open GeoParquet Datasets: Making big geospatial data easy

In the dynamic field of geospatial technology, the evolution of data formats plays a pivotal role in shaping how we interact with and interpret spatial information. The advent of GeoParquet has marked a significant milestone, offering a more efficient and accessible way to handle large spatial datasets. This blog post delves into a comprehensive exploration […]

Spatial Lab
  • Join the Spatial Lab community
Policies
  • Privacy Policy
  • Terms & Conditions
Spatial SQL
  • Get the Spatial SQL book today
Join Us

© Matt Forrest 2024. All Rights Reserved.