top of page
GeoWGS84AI_Logo_edited.jpg

Fiona in Python: A Technical Guide to Reading and Writing Geospatial Data

  • Jun 8
  • 4 min read

Updated: Jun 11

In today's world, geospatial data processing is an essential aspect of many different areas of data engineering, including GIS analysis, environmental modeling, urban planning, logistics efficiency, and location intelligence. Although there are many libraries available in Python to manage spatial data sets, one of the most effective and user-friendly is Fiona, which is used to read and write vector geospatial data.


Fiona is built upon the GDAL and OGR Ecosystem, which provides a Pythonic interface that makes it easy to work with many different geospatial data file types, including Shapefiles, GeoJSON, GeoPackage, KML, etc. Fiona abstracts much of the complexity of working with the lower-level GDAL bindings while still providing high-quality performance and compatibility.


Fiona in Python
Fiona in Python

What Is Fiona?


Fiona is a free library for the reading and writing of vector geospatial data in Python.

Fiona provides a high-level interface to the OGR component of the GDAL (Geospatial Data Abstraction Library), allowing developers to work with geographic data sets using common Python data types.


Key capabilities include:


Most of the major internet GIS applications or websites use vector data formats (ie, Shapefiles), and therefore, many of the major open source GIS software use Fiona to support their vector data needs:


  • Read vector geospatial files.

  • Write and update geospatial datasets.

  • Manage Coordinate Reference Systems (CRS)

  • Validate schema

  • Process geospatial geometries

  • Integrate with GeoPandas and Shapely

  • Support for dozens of GIS file formats


Fiona is designed for vector data and, unlike other GIS-related libraries, such as Rasterio (a raster-based library), will focus on vector data operations.


Fiona in Python: A Technical Guide to Reading and Writing Geospatial Data

Installing Fiona


Using pip

pip install fiona

Using Conda

conda install -c conda-forge fiona

Conda installation is generally more reliable because it handles GDAL dependencies automatically.

Verify installation:

import fiona

print(fiona.__version__)

Understanding Fiona's Data Model


Fiona represents geospatial data as collections of features.

A feature contains:

  • Geometry

  • Properties (attributes)

  • Feature ID

Example:

{
    "id": "1",
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": (-73.9857, 40.7484)
    },
    "properties": {
        "name": "Empire State Building"
    }
}

This structure closely follows the GeoJSON specification.


Reading Geospatial Data with Fiona


Opening a Dataset

import fiona

with fiona.open("cities.shp") as src:
    print(len(src))

The open() method returns a collection object.


Iterating Through Features

with Fiona.open("cities.shp") as src:
    for feature in src:
        print(feature)

Output:

{
    'id': '0',
    'geometry': {...},
    'properties': {...}
}

Fiona loads features lazily, making it memory efficient for large datasets.


Accessing Geometry Data


Extract coordinates from a feature:

with Fiona.open("cities.shp") as src:
    for feature in src:
        coords = feature["geometry"]["coordinates"]
        print(coords)

For Point geometries:

longitude, latitude = coords

Accessing Attribute Data


Feature attributes are stored in the properties dictionary.

with Fiona.open("cities.shp") as src:
    for feature in src:
        city_name = feature["properties"]["city"]
        population = feature["properties"]["population"]

        print(city_name, population)

This structure makes integration with Python workflows straightforward.


Working with Coordinate Reference Systems (CRS)


CRS information is critical in geospatial analysis.

Retrieve CRS:

with Fiona.open("cities.shp") as src:
    print(src.crs)

Example:

EPSG:4326

Retrieve detailed CRS:

print(src.crs_wkt)

Understanding CRS ensures spatial accuracy and proper coordinate transformations.


Writing Geospatial Data


Defining a Schema


Before creating a new dataset:

schema = {
    "geometry": "Point",
    "properties": {
        "name": "str",
        "population": "int"
    }
}

Creating a New Shapefile

import fiona

with Fiona.open(
    "output.shp",
    mode="w",
    driver="ESRI Shapefile",
    schema=schema,
    crs="EPSG:4326"
) as dst:

    dst.write({
        "geometry": {
            "type": "Point",
            "coordinates": (-74.0, 40.7)
        },
        "properties": {
            "name": "New York",
            "population": 8500000
        }
    })

Writing Multiple Features


features = [
    {
        "geometry": {
            "type": "Point",
            "coordinates": (-74.0, 40.7)
        },
        "properties": {
            "name": "New York",
            "population": 8500000
        }
    },
    {
        "geometry": {
            "type": "Point",
            "coordinates": (-118.2, 34.0)
        },
        "properties": {
            "name": "Los Angeles",
            "population": 3900000
        }
    }
]

with Fiona.open(
    "cities.shp",
    "w",
    driver="ESRI Shapefile",
    schema=schema,
    crs="EPSG:4326"
) as dst:
    dst.writerecords(features)

Using write records () is significantly faster for bulk inserts.


Reading and Writing GeoJSON


GeoJSON is widely used in web GIS applications.


Reading GeoJSON

with Fiona.open("data.geojson") as src:
    for feature in src:
        print(feature)

Creating GeoJSON

with Fiona.open(
    "output.geojson",
    "w",
    driver="GeoJSON",
    schema=schema,
    crs="EPSG:4326"
) as dst:
    dst.writerecords(features)

Filtering Features


Attribute filtering:

with Fiona.open("cities.shp") as src:
    large_cities = [
        feature
        for feature in src
        if feature["properties"]["population"] > 1000000
    ]

Useful for preprocessing datasets before analytics workflows.


Integrating Fiona with Shapely


Fiona handles I/O while Shapely performs geometry operations.

from shapely.geometry import shape

with Fiona.open("roads.shp") as src:
    for feature in src:
        geom = shape(feature["geometry"])

        print(geom.length)

Common Shapely operations include:

  • Buffering

  • Intersection

  • Union

  • Simplification

  • Distance calculations


Integrating Fiona with GeoPandas


Convert Fiona features into a GeoDataFrame.

import geopandas as gpd

gdf = gpd.read_file("cities.shp")

GeoPandas internally uses Fiona for many file operations.

Benefits include:

  • Spatial joins

  • Geometric transformations

  • Visualization

  • DataFrame-style analysis


Fiona remains one of the most powerful and developer-friendly Python libraries for vector geospatial data processing. By providing a clean abstraction over GDAL/OGR, it enables engineers, GIS analysts, and data scientists to efficiently read, write, validate, and manage spatial datasets without the complexity of low-level GIS APIs.


Whether you're building enterprise GIS systems, geospatial ETL pipelines, location intelligence platforms, or advanced spatial analytics workflows, Fiona offers a reliable foundation for handling vector data at scale. When combined with Shapely and GeoPandas, it becomes an essential component of a modern Python geospatial technology stack.


To learn more about Fiona and its geospatial capabilities, click here.


For more information or any questions regarding Fiona, please don't hesitate to contact us at


USA (HQ): (720) 702–4849


(A GeoWGS84 Corp Company)




 
 
 

Comments


bottom of page