Use your own GeoTIFF
Drone and aerial orthophotos, commercial imagery and national mapping rasters usually come as GeoTIFF files. mapcv reads them directly, local or remote: patches are cut from the file’s own pixels, in the file’s CRS, at the file’s resolution. Nothing is resampled. This page walks through a local file and a public Cloud Optimized GeoTIFF (COG) URL.
No extra install is needed: pip install mapcv is enough.
What mapcv does with the file
Section titled “What mapcv does with the file”- Grid. Your WGS-84
regionis reprojected into the file’s CRS and expanded outward to whole pixels of the file, then clipped to the raster. Every patch is a block of the file’s pixels, so it equals whatrasterioreads from the same window. - Labels. Keep your labels in WGS-84 longitude/latitude, as for any mapcv dataset. mapcv reprojects them into the file’s CRS and burns them onto the same pixels. Never reproject labels yourself.
- Bands and data type. The file’s bands and data type are kept. 8-bit RGB (or one gray band) can be written as PNG or JPG; everything else (16-bit, float, 2 or 4 and more bands) needs
npy(bands-first) ortif(a georeferenced GeoTIFF), both in the file’s own data type. - NoData. Pixels equal to the file’s NoData value in every selected band, and the area outside the file, count as empty and become
labels.ignore_index(255) in masks.
A local file
Section titled “A local file”-
Look at the file. The guided
mapcv initasks for the path, opens it and prints what it found; answergeotiffto the first question:Terminal window $ mapcv init…GeoTIFF / COG path or URL: ortho/paris-2024.tifCRS EPSG:32631Size 12,000 × 9,000 px · 3 bands · uint8Pixel 0.1 × 0.1 CRS unitsNoData 0Overviews 4It then offers the whole file as the area (press Enter), asks for labels and writes a working config. To write a commented starting file instead, run
mapcv init --template geotiff. -
Write the config. Relative paths are resolved against the config file’s folder:
mapcv.yaml region: { west: 2.3330, south: 48.8560, east: 2.3400, north: 48.8600 }imagery:type: geotiffpath: ortho/paris-2024.tiflabels:path: buildings.geojson # lon/latlabel_field: classsampler:patch_size: 256edge_strategy: dropmax_empty_ratio: 0.2 # skip patches that are mostly NoDatawriter:staging_dir: ./datasetimage_format: png # 8-bit RGBsplit:strategy: spatial -
Plan, then generate.
mapcv planopens the file’s header (no pixels), reports the CRS, the window on the file’s grid, the pixel size in metres and the expected patches, and warns if the region leaves the file:Terminal window $ mapcv plan mapcv.yaml╭─ Plan for mapcv.yaml ────────────────────────────────────────────────────────────────────────────╮│ Region 2.333, 48.856 → 2.34, 48.86 (≈ 0.5 × 0.4 km) ││ Imagery GeoTIFF paris-2024.tif · EPSG:32631 · 3 bands uint8 (≈ 0.10 m/px) ││ Raster 5,174 × 4,492 px ││ Labels buildings.geojson · … polygons · classes: building → 1 ││ Patches ≈ 340 × 256 px (grid, stride 256) ││ Output dataset · png (≈ 36.8 MB) ││ Split spatial · test 0.2 · val 0.1 ││ Memory ≈ 53.0 MB per chunk │╰──────────────────────────────────────────────────────────────────────────────────────────────────╯$ mapcv generate mapcv.yaml -
Inspect it.
mapcv info dataset/showsgeotiff · paris-2024.tif, the band names (b1, b2, b3) and the CRS. The manifest’ssources[0]records the file, its grid and a fingerprint, so resuming into the same folder with a different file is refused.
Multiband and 16-bit rasters: NPY
Section titled “Multiband and 16-bit rasters: NPY”A 4-band uint16 file (blue, green, red, near-infrared, for example) cannot be a PNG. Ask for npy, which keeps the band count and data type, and optionally pick or reorder bands with 1-based numbers:
imagery: type: geotiff path: ortho/multispectral.tif bands: [3, 2, 1, 4] # red, green, blue, NIR, in this orderwriter: image_format: npy # patches are (4, H, W) uint16 arrays; tif writes them as GeoTIFFsWith the default png, a file that does not fit stops mapcv plan and mapcv generate with a message that says so. To get an 8-bit RGB PNG from a 4-band 8-bit file, select three bands (bands: [1, 2, 3]); 16-bit data has to stay npy (rescale it in your training code).
NoData
Section titled “NoData”mapcv uses the NoData value stored in the file. If the file does not declare one, or declares the wrong one, set it in the config:
imagery: type: geotiff path: ortho/scene.tif nodata: 0Floating-point files also treat NaN and infinite values as empty.
Coarser resolution: overviews
Section titled “Coarser resolution: overviews”If the file has overviews (check the Overviews line above), overview: 1 reads the first one, usually half the resolution, overview: 2 the next, and so on. The patches then use that coarser grid. mapcv does not build overviews or resample otherwise; to change the resolution by another factor, resample the file first (for example with gdalwarp).
A public COG URL
Section titled “A public COG URL”A Cloud Optimized GeoTIFF stores its pixels in tiles with an index at the start, so mapcv can read only the tiles under your region with HTTP range requests; the rest of the file is never downloaded. Use the URL as the path:
region: { west: 2.3330, south: 48.8560, east: 2.3400, north: 48.8600 }imagery: type: geotiff path: https://example.com/cogs/paris-2024.tifA public object in S3 works as s3://bucket/key.tif (anonymous access, for buckets that allow it). One example is the Sentinel-2 L2A COGs of the Earth Search sentinel-cogs bucket; their 8-bit true-colour file is TCI.tif inside each scene folder, and the Earth Search catalogue lists the scenes. To read their spectral bands, let type: stac_cog find the scene and stack the bands for you.
Rules for remote files:
- The server must support HTTP range requests; otherwise the error says so.
- Only
https://and anonymouss3://URLs are accepted. A URL with a username, password, query string or fragment is rejected, so signed (pre-signed, SAS) URLs and private buckets are not supported.http://is accepted only for a local test server onlocalhostor127.0.0.1. - Reads are cached in memory and retried on transient errors. A plain, non-tiled GeoTIFF over HTTP works too, but mapcv then has to fetch whole strips, so a COG is much cheaper.
- Resuming checks the URL, the server’s
ETagand the file size, so a file replaced on the server is noticed. - A remote read is bound by latency, not bandwidth. Every tile of the file that the region touches is one range request, so even a small region can take dozens of seconds, depending on how far away the server is and how quickly it answers.
planis quick because it reads only the header;generateis where the time goes. For a file you will read more than once, download it and pointpathat the local copy.
Several co-registered files
Section titled “Several co-registered files”Files that cover the same place on the same pixel grid (two dates, optical and a DEM, a stack of indices) can be sampled together: list them under imagery, each with a name. Every patch then has one file per source, Images/<name>/patch_*.tif, all at the same position and with one shared mask.
imagery: - {type: geotiff, name: before, path: city_2023.tif} - {type: geotiff, name: after, path: city_2025.tif} - {type: geotiff, name: dem, path: dem_2m.tif, bands: [1]}writer: {staging_dir: ./dataset, image_format: tif}The first file’s grid is the dataset’s grid. The others must be in the same CRS with pixels that are the same size or a whole number of them across (the 2 m DEM above, under 1 m imagery), sharing pixel corners with the first; coarser pixels are repeated, never interpolated. A pixel has imagery only where every file has it. See Several imagery sources for the rules.
A folder of tiles: one mosaic
Section titled “A folder of tiles: one mosaic”Orthophotos and national mapping rasters are often delivered as many files, each covering part of the area. Give a glob pattern as the path and mapcv reads the matching files as one raster, without merging them first:
imagery: type: geotiff path: ortho/tiles/*.tif # or ortho/**/*.tif to include subfoldersmapcv plan shows the pattern and how many files it matched (*.tif (24 files)). The files have to be pieces of one grid: the same CRS, data type, band count, NoData value, pixel size, and pixel corners that line up. Otherwise the error names the file and what differs. Where tiles overlap, the first file in sorted path order that has data at a pixel wins, and a pixel that is NoData in one file is taken from the next. Gaps between tiles are empty, like the area outside a single file. Patches cut from a mosaic are byte-identical to patches cut from the same raster as one file.
Patterns work for local files only; a remote COG is always one URL. Files on different grids (another CRS or resolution) have to be warped onto one grid first, for example with gdalwarp.
Limits
Section titled “Limits”- Tiles of one grid can be read as a mosaic (above); files on different grids are not resampled to fit together.
- The file’s CRS must be an EPSG code (UTM, Web Mercator, WGS-84 and national grids all are); files with a custom CRS or no CRS are reported with the reason, and need re-tagging first.
- Supported compression: none, Deflate, LZW, PackBits, ZSTD, JPEG and WebP. A file that uses another one (LERC, JPEG 2000, …) fails when opened, naming it; convert it with
gdal_translate -co COMPRESS=DEFLATE. - External
.ovroverviews, internal mask bands and GCP-only georeferencing are not read.
See the configuration reference for every field and rule, and Coordinates and grids for how the window is chosen.