Skip to content

SpatialWorkflowIo/python-geojson-tiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

python-geojson-tiler

python-geojson-tiler is a beginner-friendly Python tool for splitting large GeoJSON datasets into XYZ tiles.

If you have ever searched for "how to serve big GeoJSON", this project is meant to be the simple answer: take one large GeoJSON file, break it into smaller tile-shaped chunks, and serve those files from a normal static web server.

This first version is intentionally simple:

  • It reads a GeoJSON Feature or FeatureCollection
  • It calculates each feature's geographic bounding box
  • It writes every intersecting XYZ tile as z/x/y.geojson
  • It duplicates features into every tile they touch
  • It does not clip geometry to tile edges yet

That trade-off keeps the code easy to understand, easy to test, and easy to extend.

For more geospatial workflow ideas, see Spatial Workflow.

Why use this?

Large GeoJSON files are awkward to ship directly to browsers and map clients. Tiling helps because clients can request only the small pieces they need for the current map view.

This project is useful when you want to:

  • pre-split a GeoJSON file into web-friendly XYZ tile folders
  • serve big GeoJSON from a basic file server or CDN
  • build a simple pipeline without introducing a larger GIS stack yet
  • understand the mechanics of XYZ tiling in plain Python

Quickstart

1) Create and activate a virtual environment

python3 -m venv .venv
source .venv/bin/activate

2) Install the project in editable mode

python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

3) Create a tiny GeoJSON example

cat > sample.geojson <<'EOF'
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {"name": "Berlin"},
      "geometry": {"type": "Point", "coordinates": [13.405, 52.52]}
    },
    {
      "type": "Feature",
      "properties": {"name": "Paris"},
      "geometry": {"type": "Point", "coordinates": [2.3522, 48.8566]}
    }
  ]
}
EOF

4) Tile the file

geojson-tiler sample.geojson tiles --min-zoom 0 --max-zoom 2

5) Inspect the output

find tiles -maxdepth 4 -type f | sort
cat tiles/metadata.json

6) Serve the tile directory locally

cd tiles
python -m http.server 8000

Your files will then be available at paths like:

  • http://localhost:8000/0/0/0.geojson
  • http://localhost:8000/1/1/0.geojson

Command-line usage

geojson-tiler INPUT OUTPUT [--min-zoom MIN] [--max-zoom MAX] [--indent N] [--overwrite] [--quiet]

Arguments

  • INPUT: path to a GeoJSON file containing a Feature or FeatureCollection
  • OUTPUT: directory that will receive XYZ tile folders
  • --min-zoom: first zoom level to generate, default 0
  • --max-zoom: last zoom level to generate, default 0
  • --indent: JSON indentation level for generated files, default 2
  • --overwrite: allow writing into a non-empty output directory
  • --quiet: skip the success summary message
  • --version: print the installed version

Output layout

The generated directory structure looks like this:

tiles/
├── metadata.json
├── 0/
│   └── 0/
│       └── 0.geojson
├── 1/
│   ├── 0/
│   │   ├── 0.geojson
│   │   └── 1.geojson
│   └── 1/
│       ├── 0.geojson
│       └── 1.geojson
└── ...

Each tile file is a valid GeoJSON FeatureCollection.

metadata.json includes:

  • the original source filename
  • total input feature count
  • total tile count written
  • a list of tile addresses and relative file paths

Python API

You can also use the tiler directly from Python:

from geojson_tiler.tiler import tile_geojson
from geojson_tiler.writer import write_tiles

geojson_data = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {"name": "Example"},
            "geometry": {"type": "Point", "coordinates": [13.405, 52.52]},
        }
    ],
}

result = tile_geojson(geojson_data, min_zoom=0, max_zoom=2)
write_tiles(result, "tiles", source_name="example.geojson")

Supported geometry types

This version supports bounding-box tiling for:

  • Point
  • MultiPoint
  • LineString
  • MultiLineString
  • Polygon
  • MultiPolygon
  • GeometryCollection
  • null geometry (skipped)

Important behavior to know

Features are duplicated, not clipped

If a feature overlaps multiple tiles, the full feature is written into every intersecting tile.

That means:

  • output is easy to reason about
  • output may be larger than a clipped-vector-tiles workflow
  • tile borders can contain repeated features

For many beginner and static-serving workflows, this is a good first step.

Coordinates use geographic longitude/latitude

The tool expects standard GeoJSON coordinates in longitude/latitude order ([lon, lat]). It clamps latitude to the Web Mercator limit used by XYZ tiles.

Examples

Generate one zoom level

geojson-tiler countries.geojson country-tiles --min-zoom 4 --max-zoom 4

Generate a zoom range

geojson-tiler roads.geojson road-tiles --min-zoom 5 --max-zoom 8

Re-run into an existing directory

geojson-tiler parcels.geojson parcel-tiles --min-zoom 10 --max-zoom 12 --overwrite

Quiet mode for scripts

geojson-tiler input.geojson public/tiles --min-zoom 0 --max-zoom 3 --quiet

Development

Run the test suite

python -m pytest

Check the CLI help

geojson-tiler --help
python -m geojson_tiler --help

Build distribution files

python -m pip install build
python -m build

Project structure

src/geojson_tiler/
├── __init__.py
├── __main__.py
├── cli.py
├── geojson.py
├── tiler.py
├── writer.py
└── xyz.py
tests/

Limitations of the current version

This repository now contains a complete, runnable first version, but it is still intentionally small.

Current limitations:

  • no geometry clipping at tile edges
  • no simplification by zoom level
  • no spatial index yet
  • no direct shapefile reader yet
  • no hosted GitHub automation yet in this workspace

Troubleshooting

“Output directory is not empty”

Use --overwrite if you want to write into an existing output directory.

“GeoJSON root must be a Feature or FeatureCollection”

The input file must be standard GeoJSON with a top-level Feature or FeatureCollection object.

My tiles seem duplicated

That is expected in this version when a feature spans multiple tiles. The tool duplicates full features into every intersecting tile rather than clipping them.

Contributing

When you extend this project, please keep the beginner-friendly goal in mind:

  • document new behavior in README.md
  • keep CLI examples copy-pasteable
  • preserve the Python-only implementation unless the project scope changes

For more spatial workflow ideas and tutorials, visit https://spatialworkflow.io/.

About

Beginner-friendly Python tool for chunking large GeoJSON datasets into XYZ tiles.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages