githubEdit

Geospatial Data

Introduction

This tutorial walks through a complete geospatial data workflow in Supervisely: downloading satellite imagery, DTM elevation tiles, and OpenStreetMap vector annotations; storing geographic context in image metadata and dataset custom data; labeling with multi-layer interfaces and AI assistance; and exporting annotated data back to OSM XML format.

Everything in this workflow is built on standard Supervisely primitives β€” images with metadata, datasets with custom data, and object annotations. No special project types or external geodata infrastructure are required. The result is a fully reproducible pipeline where geographic context travels with the data at every step and any Supervisely platform feature can be applied without modification.

The Satellite, DTM & OSM Downloaderarrow-up-right and Export to OSM Formatarrow-up-right apps implement this pipeline end to end. This article explains the underlying mechanics so you can reproduce, extend, or integrate any part of it using the Python SDK.

circle-info

Source code for both apps is available at github.com/supervisely-ecosystem/slyosmarrow-up-right.

Prerequisites

Step 1. Prepare ~/supervisely.env with your credentials. Learn more here.arrow-up-right

Step 2. Install dependencies.

pip install supervisely pyproj numpy

Step 3. Initialize the API client.

import os
from dotenv import load_dotenv
import supervisely as sly

if sly.is_development():
    load_dotenv("local.env")
    load_dotenv(os.path.expanduser("~/supervisely.env"))

api = sly.Api.from_env()

Architecture Overview

The geospatial pipeline relies on two storage mechanisms built into the Supervisely API:

Storage
What is stored
API

Image metadata (meta field)

Per-image geographic context: center coordinates, homography matrix, CRS, bounding box

api.image.upload_path(..., meta={...})

Dataset custom data

OSM class mapping shared across all images in the dataset

api.dataset.update_custom_data(id, data)

This separation is deliberate. Geographic context is per-image because each tile covers a different location. The OSM class mapping is per-dataset because it is the same for every image downloaded in one session β€” changing it between images would make annotations inconsistent.

OSM Class Mapping

The OSM class mapping defines which OpenStreetMap features are downloaded, how they map to Supervisely object classes, and which OSM tags are written when annotations are exported back to .osm files.

Structure

The mapping is a list of class specification objects stored as a JSON array. Each entry describes one Supervisely object class:

Field
Required
Description

name

Yes

Supervisely object class name

geometry

Yes

"polygon", "line", or "point"

tags

Yes

OSM tag filters. Value can be a string, boolean, or list of strings

default_tag

Yes

Single OSM tag written when exporting annotations to .osm files

buffer_m

No

Expand lines and points by this many meters to produce a polygon footprint in Supervisely

color

No

RGB color [R, G, B] for the Supervisely object class

Saving the Mapping to a Dataset

Reading the Mapping Back

The export app reads from this key automatically. If the key is absent it falls back to the built-in default mapping, so existing datasets without custom data continue to work.

Image Geo Metadata

Every georeferenced image uploaded by the downloader app carries a geo object inside its meta field. This payload contains everything needed to project pixel coordinates back to longitude/latitude at export time.

Geo Payload Structure

circle-info

The local CRS is an azimuthal equidistant projection centered on the scene center. It maps the scene to a flat plane in meters, which is valid for tiles up to a few kilometers across. The homography matrix maps directly from pixel space to this local metric space. To reach WGS84 longitude/latitude, apply the homography then transform with pyproj.

Uploading an Image with Geo Metadata

Reading Geo Metadata from an Existing Image

Projecting Pixel Coordinates to WGS84

Creating a Georeferenced Project

Here is a minimal end-to-end example that creates a project, adds object classes from the OSM mapping, saves the class mapping to the dataset, and uploads a georeferenced image.

Labeling Interfaces

Because each downloaded tile is a standard Supervisely image with object annotations, all labeling toolbox modes are available without any additional setup.

Multiview

When the downloader app runs in Multiview mode, the satellite image and the DTM elevation image are uploaded as a linked pair using api.image.upload_multiview_images. Both images appear side by side in the labeling toolbox. Annotations are shared β€” a polygon drawn on the satellite view is visible on the DTM view and vice versa.

This is useful when elevation context is needed to make annotation decisions, for example distinguishing embankments from roads, identifying vegetation by canopy height, or locating buildings in shadow.

Learn more about Multiview labeling β†’arrow-up-right

Overlay

In Overlay mode, a single composited image is uploaded with the DTM blended on top of the satellite layer. The annotator can adjust DTM transparency on the fly in the labeling interface.

Learn more about Overlay mode β†’arrow-up-right

Choosing a Mode Programmatically

The downloader app exposes interface mode as a configurable parameter. To replicate this in your own pipeline, upload either a single image (satellite-only or DTM-only) or a multiview pair:

AI-Assisted Annotation

Georeferenced datasets are standard Supervisely image datasets, so every AI feature on the platform works without modification.

Smart Tool β€” interactive segmentation model that produces polygon or mask output from a few clicks. Effective for consistently shaped features like building footprints, water bodies, and agricultural fields that repeat across many tiles.

Auto Labeling β€” run any model from the Supervisely Ecosystem on your geospatial dataset to pre-annotate tiles in batch. Use the resulting annotations as a starting point for human review rather than annotating from scratch.

NN training β€” train or fine-tune a model directly on your geospatial dataset within the platform, then apply it to newly downloaded tiles. The geographic metadata in image meta is preserved through the training pipeline and remains available for export afterward.

Exporting to OSM Format

The Export to OSM Formatarrow-up-right app reads geo metadata from each image and the OSM class mapping from the dataset, then projects polygon and line annotations back to WGS84 coordinates and writes standard OSM XML files.

Output Archive Structure

Running the Export via SDK

The export logic is importable directly. To run it programmatically:

OSM XML Output Format

Each .osm file is a standard OSM XMLarrow-up-right file compatible with JOSMarrow-up-right, osmium, Overpass API, and any other OSM tooling. Polygon annotations become closed ways or multipolygon relations (when holes are present). Line annotations become open ways. All IDs are negative, following OSM convention for locally generated data.

Dataset Custom Data Reference

The following keys are written and read by the slyosm apps. Use the same schema if you are integrating your own pipeline.

Key
Type
Description

osm_class_specs

list[dict]

OSM class mapping array (see structure above)

slyosm_schema_version

int

Schema version, currently 1

Summary

This tutorial covered the complete geospatial data workflow in Supervisely using standard SDK primitives:

  1. OSM class mapping is stored in dataset custom data under osm_class_specs and read automatically by the export app β€” change it once per dataset, not per image.

  2. Geographic context is stored in image metadata under the geo key as a homography matrix, local CRS, and bounding box β€” enough to round-trip any pixel coordinate to WGS84 and back.

  3. Labeling works in Multiview, Overlay, or standard single-image mode β€” all Supervisely tools and AI features apply without modification.

  4. Export produces standard OSM XML files alongside original images and Supervisely annotation JSONs, ready to open in JOSMarrow-up-right or any other OSM tool.

The full source code is available in the slyosm repositoryarrow-up-right.

Last updated