A program for taking a GeoTIFF image and splitting it into tiles for label tasks
  • Go 97.4%
  • Nix 2.2%
  • Shell 0.4%
Find a file
2026-06-19 13:42:09 +00:00
.gitignore Allow tiling of any available asset 2026-06-17 18:17:02 +00:00
AGENTS.md Add initial AGENTS.md for setting logging standards 2026-06-17 15:50:53 +00:00
catalog.go Add S3 upload of tiles after creation 2026-06-17 17:00:36 +00:00
flake.lock Initial creation of the build 2026-06-17 15:44:04 +00:00
flake.nix Split out tiles from main source into usable pieces 2026-06-17 16:33:33 +00:00
go.mod Add S3 upload of tiles after creation 2026-06-17 17:00:36 +00:00
go.sum Add S3 upload of tiles after creation 2026-06-17 17:00:36 +00:00
main.go Put temp files under the input file name for namespacing. 2026-06-19 13:41:48 +00:00
manifest.go Allow tiling of any available asset 2026-06-17 18:17:02 +00:00
README.md Update READMe with the latest AI context. 2026-06-19 13:42:09 +00:00
s3config.go Add S3 upload of tiles after creation 2026-06-17 17:00:36 +00:00
scene.go Calculate the correct tile size from the provided STAC data 2026-06-17 16:10:53 +00:00
start-satellite-label-task-splitter.sh Add S3 upload of tiles after creation 2026-06-17 17:00:36 +00:00
tile.go Attempt to process pelican and skysat satellite images 2026-06-17 18:34:04 +00:00
upload.go Allow tiling of any available asset 2026-06-17 18:17:02 +00:00

Satellite Label Task Splitter

Takes Planet satellite imagery bundles, splits GeoTIFF assets into square PNG tiles, and uploads them to S3 for use with labeling tools like Label Studio.

Overview

This tool processes Planet bundle ZIP files containing STAC-compliant satellite imagery. It:

  1. Extracts the bundle to a working directory
  2. Validates file integrity against the bundle manifest (SHA-256/MD5 checksums)
  3. Parses STAC metadata to determine image dimensions, pixel resolution, and geospatial extents
  4. Tiles each GeoTIFF asset into square PNG tiles of configurable area
  5. Filters out empty/nodata tiles automatically
  6. Uploads tiles to an S3-compatible bucket with a hierarchical key structure

Supported Imagery

Constellation Asset Types Bands
Pelican ortho_visual 4-band (RGB + alpha)
SkySat ortho_pansharpened, ortho_pansharpened_udm, ortho_pansharpened_udm2 36 band, 816 bit

The tool automatically handles band reduction, 16→8-bit conversion, planar→contig conversion, and internal tiled→strip reorganization.

Usage

go run . [-tilearea N] [-debug] <input.zip>

Flags

Flag Default Description
-tilearea 1000 Target tile area in square meters (~¼ acre). Tile size is computed as ceil(sqrt(area) / pixel_resolution) pixels
-debug false Enable debug-level logging (per-tile extraction, validation, etc.)

Examples

# Default ~¼ acre tiles
go run . input/bundle.zip

# Larger ~2.5 acre tiles (200px at 0.5m/px)
go run . -tilearea 10000 input/bundle.zip

# With debug logging
go run . -debug input/bundle.zip

S3 Upload

Tiles are uploaded to S3 when the following environment variables are set:

Variable Required Description
S3_BUCKET yes Bucket name
S3_REGION yes AWS region or S3-compatible region
S3_ENDPOINT yes S3 endpoint URL (e.g. https://s3.amazonaws.com)
S3_CLIENT_ID yes Access key / client ID
S3_CLIENT_SECRET yes Secret key
S3_PREFIX no Optional base path within the bucket

If any required variable is missing, upload is skipped with a warning.

S3 Key Structure

{S3_PREFIX}/{catalog_id}/{item_id}/{asset_type}/tile_{xoff}_{yoff}.png

Example:

label-tasks/1dd631ac-1003-495a-9fc0-2d775fa81a04/20260405_183712_51_300c/ortho_visual/tile_0_0.png

Output Structure

All output lives under ./tmp/{bundle_name}/:

tmp/
└── Visalia_High_Res_Test_2_pelicanscene_visual/
    ├── catalog.json
    ├── manifest.json
    ├── PelicanScene/
    │   ├── 20260405_183712_51_300c.json          # STAC item metadata
    │   ├── 20260405_183712_51_300c_metadata.json
    │   ├── PelicanScene_collection.json
    │   └── 20260405_183712_51_300c_ortho_visual_clip.tif
    └── tiles/
        └── 20260405_183712_51_300c/
            └── ortho_visual/
                ├── tile_0_0.png
                ├── tile_0_200.png
                └── ...

Tiles are named tile_{xoff}_{yoff}.png where xoff and yoff are the pixel offsets from the top-left corner of the source image.

Project Structure

├── main.go         # Entry point, pipeline orchestration
├── manifest.go     # Bundle manifest parsing, validation, asset discovery
├── catalog.go      # STAC catalog ID extraction
├── scene.go        # STAC item parsing, tile layout computation
├── tile.go         # GeoTIFF→PNG tiling with empty-tile filtering
├── s3config.go     # S3 configuration from environment variables
├── upload.go       # S3 upload client and batch upload logic
├── flake.nix       # Nix flake for reproducible development environment
├── go.mod / go.sum # Go module dependencies
└── README.md

Development

Requires Nix with flakes enabled.

nix develop     # enter dev shell with Go, libtiff, and tooling
go run . ...    # build and run
go build ./...  # compile

Key Dependencies

  • github.com/rs/zerolog — structured logging
  • github.com/paulmach/go.geojson — STAC/GeoJSON parsing
  • github.com/aws/aws-sdk-go-v2 — S3 upload
  • golang.org/x/image/tiff — TIFF decoding (small tiles only)
  • libtiff (system) — tiff2rgba and tiffcrop for GeoTIFF preprocessing