Core Features¶
This page covers fundamental geoextent capabilities used in everyday workflows.
Raster Temporal Extent Extraction¶
geoextent can extract temporal extents from raster files using several metadata sources. When multiple sources are present, the first successful result wins.
Fallback Chain¶
The metadata sources are tried in the following order:
NetCDF CF time dimension — checked on subdatasets first, then the main dataset
ACDD global attributes —
time_coverage_start/time_coverage_endGeoTIFF TIFFTAG_DATETIME — standard TIFF date/time tag
Band-level ACQUISITIONDATETIME — IMAGERY metadata domain
If none of the sources yield a valid date, the temporal extent is None (absent from the result)
while spatial extent extraction proceeds independently.
Supported Metadata Fields¶
Field |
Domain |
Format |
Specification |
|---|---|---|---|
|
default (dataset) |
|
|
|
IMAGERY (band) |
ISO 8601 (e.g. |
|
|
default (dataset/subdataset) |
CF convention (e.g. |
|
|
default (dataset) |
ISO 8601 |
Examples¶
GeoTIFF with TIFFTAG_DATETIME:
from geoextent.lib import extent
result = extent.from_file("satellite_image.tif", tbox=True)
# result["tbox"] == ["2019-03-21", "2019-03-21"]
NetCDF with CF time dimension:
result = extent.from_file("climate_model.nc", tbox=True)
# result["tbox"] == ["2015-01-01", "2016-01-01"]
NetCDF with ACDD global attributes:
result = extent.from_file("ocean_temp.nc", tbox=True)
# result["tbox"] == ["2018-04-01", "2018-09-30"]
CLI usage:
# Extract temporal extent from a GeoTIFF
python -m geoextent -t satellite_image.tif
# Extract both spatial and temporal extent
python -m geoextent -b -t climate_model.nc
Temporal Extent Output Format¶
By default, temporal extents are formatted as date-only strings (YYYY-MM-DD).
The --time-format CLI option and time_format API parameter let you choose
a different output precision or format.
Presets¶
Preset |
Format string |
Example output |
|---|---|---|
|
|
|
|
|
|
You can also pass any valid Python strftime format string directly
(detected by the presence of %).
When the source data only has date-level precision, time components default to
midnight (00:00:00).
Python API Examples¶
from geoextent.lib import extent
# Default (date only)
result = extent.from_file("image.tif", tbox=True)
# result["tbox"] == ["2019-03-21", "2019-03-21"]
# ISO 8601 with full time
result = extent.from_file("image.tif", tbox=True, time_format="iso8601")
# result["tbox"] == ["2019-03-21T08:15:00Z", "2019-03-21T08:15:00Z"]
# Custom strftime format
result = extent.from_file("image.tif", tbox=True, time_format="%d.%m.%Y %H:%M")
# result["tbox"] == ["21.03.2019 08:15", "21.03.2019 08:15"]
CLI Examples¶
# ISO 8601
python -m geoextent -t --time-format iso8601 satellite_image.tif
# Custom format
python -m geoextent -t --time-format "%Y/%m/%d %H:%M" satellite_image.tif
See also RFC 3339 for the ISO 8601 profile commonly used on the web.
Multiple Remote Resource Extraction¶
Overview¶
The from_remote() function accepts either a single identifier (string) or multiple identifiers (list) for extracting geospatial and temporal extents. When multiple identifiers are provided, the function returns a merged geometry (bounding box or convex hull) covering all resources, similar to directory extraction. This is useful for:
Processing multiple datasets from different repositories
Comparing spatial coverage across multiple sources
Automated workflows that need to handle lists of DOIs
Creating combined metadata for related datasets
Python API¶
Extract from multiple remote resources (list):
from geoextent.lib import extent
identifiers = [
'10.5281/zenodo.4593540',
'10.25532/OPARA-581',
'https://osf.io/abc123/'
]
result = extent.from_remote(
identifiers,
bbox=True,
tbox=True,
max_download_size='100MB',
download_skip_nogeo=True
)
# Access merged bounding box (covers all resources)
print(result['bbox']) # [minx, miny, maxx, maxy]
print(result['crs']) # '4326'
# Check extraction statistics
metadata = result['extraction_metadata']
print(f"Total: {metadata['total_resources']}")
print(f"Successful: {metadata['successful']}")
print(f"Failed: {metadata['failed']}")
# Optional: Access individual resource details for diagnostics
for identifier, details in result['details'].items():
if 'error' in details:
print(f"Failed: {identifier} - {details['error']}")
Extract from single remote resource (string):
result = extent.from_remote(
'10.5281/zenodo.4593540',
bbox=True,
tbox=True
)
CLI Usage¶
The CLI supports multiple inputs including remote resources:
# Extract from multiple repositories
python -m geoextent -b -t \
10.5281/zenodo.4593540 \
10.25532/OPARA-581 \
https://osf.io/abc123/
# Mix remote resources with local files (also supported)
python -m geoextent -b -t \
data.geojson \
10.5281/zenodo.4593540 \
data_dir/
Supported Parameters¶
All standard from_remote() parameters are supported:
bbox,tbox,convex_hull- Extraction optionsmax_download_size,max_download_method- Download controldownload_skip_nogeo- File filteringmax_download_workers- Parallel processingplacename- Geographic context lookupdetails- Include detailed extraction information
Return Structure¶
For multiple identifiers (list input), the function returns a merged geometry covering all resources:
{
"format": "remote_bulk",
"bbox": [minx, miny, maxx, maxy], # Merged bounding box (all resources)
"crs": "4326", # Coordinate reference system
"tbox": ["2020-01-01", "2023-12-31"], # Merged temporal extent (all resources)
"details": {
"10.5281/zenodo.4593540": {
"bbox": [...], # Individual resource bbox (for diagnostics)
"tbox": [...],
"format": "remote",
...
},
"10.25532/OPARA-581": {
"bbox": [...], # Individual resource bbox (for diagnostics)
...
}
},
"extraction_metadata": {
"total_resources": 2,
"successful": 2,
"failed": 0
}
}
The primary result is the merged bbox at the top level, which combines all successfully extracted resources into a single bounding box (or convex hull if convex_hull=True). Individual bounding boxes in details are retained for diagnostic purposes only.
For single identifier (string input):
{
"format": "remote",
"bbox": [minx, miny, maxx, maxy],
"crs": "4326",
"tbox": ["2020-01-01", "2023-12-31"],
...
}
See Content Providers for details on all supported repositories.
Output Formats¶
geoextent supports multiple output formats for spatial extents to facilitate integration with different programming languages and tools.
Supported Formats¶
# Default GeoJSON format (geographic coordinates as polygon)
python -m geoextent -b tests/testdata/geojson/muenster_ring_zeit.geojson
python -m geoextent -b --format geojson tests/testdata/geojson/muenster_ring_zeit.geojson
# Well-Known Text (WKT) format
python -m geoextent -b --format wkt tests/testdata/geojson/muenster_ring_zeit.geojson
# Well-Known Binary (WKB) format as hex string
python -m geoextent -b --format wkb tests/testdata/geojson/muenster_ring_zeit.geojson
Format Details¶
- GeoJSON (default)
Returns spatial extent as a GeoJSON Polygon geometry with coordinate arrays
- WKT
Returns spatial extent as Well-Known Text POLYGON string, easily parsed by PostGIS, GDAL, and other geospatial tools
- WKB
Returns spatial extent as Well-Known Binary hexadecimal string, compact binary format for database storage
An easy way to verify these outputs is the online WKB viewer/converter.
Interactive Visualization¶
Open extracted spatial extents in geojson.io for interactive visualization and editing.
Generate URL¶
Use --geojsonio to generate a clickable geojson.io URL:
python -m geoextent -b --geojsonio tests/testdata/geojson/muenster_ring.geojson
This prints the URL after the JSON output.
Open in Browser¶
Use --browse to automatically open the visualization in your default web browser:
python -m geoextent -b --browse tests/testdata/geojson/muenster_ring.geojson
This opens the browser without printing the URL. To both print the URL to the console and open it in the browser, use both --geojsonio and --browse:
python -m geoextent -b --geojsonio --browse tests/testdata/geojson/muenster_ring.geojson
Works with Remote Repositories¶
# Open Zenodo data visualization in browser
python -m geoextent -b --browse https://doi.org/10.5281/zenodo.4593540
# Combine with other options
python -m geoextent -b --convex-hull --browse --quiet https://doi.org/10.1594/PANGAEA.734969
Map Preview¶
Generate a static map image showing the extracted spatial extent overlaid on OpenStreetMap tiles. This is useful for quick visual verification of extraction results, inclusion in reports, or embedding in notebooks.
Note
Map preview requires the preview optional dependency group:
pip install geoextent[preview]
This installs staticmap, term-image, and Pillow.
Quick Start¶
The simplest way to get a map preview is --map with no arguments. A temporary PNG file is created automatically and its path is printed to stderr:
geoextent --map -b tests/testdata/geojson/muenster_ring_zeit.geojson
# stderr: Map preview saved to: /tmp/geoextent_map_abc12345.png
Tip
When using --map without a file path, place it before the input file
(e.g., --map -b file.geojson) so that argparse does not consume the input
as the map path.
Save to a Specific File¶
Provide a path after --map to choose where the PNG is saved:
geoextent -b --map extent.png tests/testdata/geojson/muenster_ring_zeit.geojson
The saved image includes a semi-transparent attribution bar at the bottom: “Created with geoextent {version} | (c) OpenStreetMap contributors”
The path is always printed to stderr unless --quiet is used.
Display in Terminal¶
Use --preview to render the map and display it directly in the terminal:
geoextent -b --preview tests/testdata/geojson/muenster_ring_zeit.geojson
geoextent displays the image using the following fallback chain:
term-image (Python library, included in
[preview]) — auto-detects Kitty graphics protocol, iTerm2 inline images, or Sixel, falls back to Unicode block characters. Works in any terminal without external tools.External CLI tools:
chafa,timg,catimg— used if term-image is unavailable or failsFile path — printed as a last resort so you can open the image manually
Save and Display¶
Combine both flags to save to a specific path and display in the terminal:
geoextent -b --map extent.png --preview tests/testdata/geojson/muenster_ring_zeit.geojson
Custom Dimensions¶
Use --map-dim to set the image size in pixels (default: 600x400):
geoextent -b --map extent.png --map-dim 800x600 tests/testdata/geojson/muenster_ring_zeit.geojson
Combining with Other Options¶
Map preview works with convex hulls, legacy coordinate order, and remote repositories:
# Convex hull overlay
geoextent -b --convex-hull --map hull.png tests/testdata/geojson/muenster_ring_zeit.geojson
# Legacy coordinate order
geoextent -b --legacy --map extent.png tests/testdata/geojson/muenster_ring_zeit.geojson
# Remote repository
geoextent -b --map zenodo_extent.png https://doi.org/10.5281/zenodo.4593540
# Preview from a directory
geoextent -b --preview tests/testdata/geojson/
# Quick map to temp file from a repository
geoextent --map -b https://doi.org/10.5281/zenodo.4593540
Note
Map preview requires a spatial extent (-b). If no bounding box is extracted
(e.g., only -t is used, or the file has no spatial data), the map is silently
skipped and extraction proceeds normally. If staticmap is not installed, a
message is printed to stderr and extraction continues.
Flag Summary¶
Flags |
File saved? |
Message shown? |
Terminal display? |
|---|---|---|---|
|
Yes (temp) |
Yes |
No |
|
Yes |
Yes |
No |
|
Yes (temp) |
Yes |
Yes |
|
Yes |
Yes |
Yes |
|
No (skipped) |
No |
No |
|
Yes |
No |
No |
|
No (skipped) |
No |
No |
|
Yes |
No |
No |
When --quiet is used, all sidecar output (the “saved to” message and the terminal image
display) is suppressed. If --map specifies an explicit file path, the image is still
generated and saved silently. When no file path is given (temporary file), the map is
skipped entirely since the path would not be visible.
Remote Raster / COG Support¶
Pass a direct HTTP(S) URL to a GeoTIFF (especially a Cloud Optimized GeoTIFF) and geoextent extracts its spatial and temporal extent without downloading the full file.
How it works: Uses GDAL’s /vsicurl/ virtual filesystem for HTTP range-request
access. For a COG, only ~16 KB is typically transferred to read the file header.
CLI examples:
# Extract bbox from a remote COG
geoextent -b https://raw.githubusercontent.com/GeoTIFF/test-data/main/files/gfw-azores.tif
# Extract both spatial and temporal extent
geoextent -b -t https://example.com/satellite_image.tif
Python API:
import geoextent.lib.extent as geoextent
result = geoextent.from_remote(
"https://raw.githubusercontent.com/GeoTIFF/test-data/main/files/gfw-azores.tif",
bbox=True, tbox=True,
)
Note
Cloud Optimized GeoTIFFs (tiled with overviews at the start of the file) are most efficient. Regular GeoTIFFs also work but may require more HTTP requests.
Note
For GeoTIFF files hosted on a supported repository (e.g. Zenodo), using the DOI triggers the full repository provider instead. Use the direct file URL for COG-style header-only access.
File Export¶
Export extraction results to a file using --output. The format is auto-detected from the
file extension.
Supported Formats¶
Extension |
Format |
Geometry |
Notes |
|---|---|---|---|
|
GeoPackage |
Native polygon |
Layer |
|
GeoJSON |
RFC 7946 |
FeatureCollection |
|
CSV |
WKT (or WKB via |
Geometry format controlled by |
Other |
GeoPackage (fallback) |
Native polygon |
Warning printed for unrecognised extensions |
Single File vs Directory¶
Single file: one feature with the file’s extent
Directory / multi-file: one feature per file plus one summary feature with the merged extent
CLI Examples¶
# Single file
geoextent -b -t --output result.gpkg file.geojson
# Directory to GeoJSON
geoextent -b -t --output result.geojson path/to/directory
# Multiple files to CSV
geoextent -b -t --output result.csv file1.shp file2.geojson
# With convex hull
geoextent -b --convex-hull --output hull.gpkg path/to/directory
# CSV with WKB geometry
geoextent -b --format wkb --output result.csv path/to/directory
Python API¶
import geoextent
result = geoextent.from_file("data.geojson", bbox=True, tbox=True)
geoextent.export_to_file(result, "output.gpkg")
Temporal Fields¶
Each exported feature includes tbox_start and tbox_end fields:
GeoPackage: proper OGR Date fields (
OFTDate)GeoJSON / CSV: ISO 8601 date strings (e.g.
"2020-01-15")
When no temporal extent was extracted, these fields are NULL (GeoPackage) or
empty / null (CSV / GeoJSON).
Coordinate Order¶
All three output formats use [longitude, latitude] order:
GeoPackage: traditional GIS axis order
GeoJSON: per RFC 7946
CSV (WKT/WKB): traditional GIS axis order
Interaction with --format¶
The --format flag is respected for CSV output (--format wkb writes hex-encoded
WKB instead of WKT in the geometry column). For GeoPackage and GeoJSON output, geometry
is stored natively and --format is ignored with a warning.
Interaction with --quiet¶
The export file is still written; only the “Exporting result into: …” message is suppressed.
Joining Export Files¶
Merge multiple export files (from --output) into a single file. This is useful when
you process many directories or sources in separate runs and want to combine the results.
Behaviour¶
Concatenates all individual-file features from each input file
Excludes summary rows (features where
handlerstarts with"geoextent:")Input files can be any supported format (GPKG, GeoJSON, CSV); the output format is auto-detected from the extension — cross-format joins work
No re-merging of bounding boxes or temporal extents — just concatenation
CLI Examples¶
# Merge two GPKG exports
geoextent --join --output merged.gpkg run1.gpkg run2.gpkg
# Merge all GPKG files into GeoJSON
geoextent --join --output all.geojson *.gpkg
# Cross-format: GeoJSON + GPKG -> CSV
geoextent --join --output combined.csv run1.geojson run2.gpkg
Note
--join requires --output but does not require -b/-t flags.
It bypasses the extraction pipeline entirely.
Python API¶
import geoextent
geoextent.join_files(["run1.gpkg", "run2.gpkg"], "merged.gpkg")
# Cross-format join with WKB geometry for CSV output
geoextent.join_files(["run1.geojson", "run2.gpkg"], "combined.csv", geometry_format="wkb")
Quiet Mode¶
Use the --quiet option to suppress all console messages including warnings, progress bars, map preview messages, and terminal display. This is particularly useful for scripting, automation, or when you only want the final result. File output (--map FILE, --output) is still written silently.
The following table summarises how --quiet interacts with other flags:
Feature |
Default |
With |
|---|---|---|
Progress bars |
Shown |
Hidden (implies |
Warnings / log messages |
Shown |
Hidden |
|
Image saved, path printed |
Image saved, path hidden |
|
Temp image saved, path printed |
Skipped entirely |
|
Image displayed in terminal |
Skipped entirely |
|
Image saved and displayed |
Image saved, display hidden |
|
URL printed |
URL printed |
|
Browser opened, status printed |
Browser opened, status hidden |
|
File written, status printed |
File written, status hidden |
|
N/A (conflicts with |
|
Basic Usage¶
# Normal output (shows progress bars and warnings)
python -m geoextent -b tests/testdata/geojson/
# Output: Progress bars, warnings, and result
# Quiet mode (clean output, no progress or warnings)
python -m geoextent -b --quiet tests/testdata/geojson/
# Output: Only the final result
# Quiet mode with specific format
python -m geoextent -b --format wkt --quiet tests/testdata/geojson/
# Output: POLYGON((6.220493316650391 50.52150360276628,...))
Scripting Examples¶
Perfect for shell scripts and pipelines:
# Capture output in variable
BBOX=$(python -m geoextent -b --format wkt --quiet tests/testdata/geojson/muenster_ring_zeit.geojson)
echo "Bounding box: $BBOX"
R Integration¶
You can call geoextent from within R scripts using the system2() function, in combination with WKT format for creating R objects easily:
sf::st_as_sfc(
system2("geoextent",
c("-b", "--format", "wkt", "--quiet", "tests/testdata/geojson"),
stdout=TRUE)
)
Convex Hull vs Bounding Box¶
By default, geoextent extracts a rectangular bounding box. For vector data, you can extract a more precise convex hull that better represents the actual spatial extent.
Basic Usage¶
# Default bounding box extraction
python -m geoextent -b tests/testdata/geojson/muenster_ring.geojson
# Convex hull extraction (more precise for vector data)
python -m geoextent -b --convex-hull tests/testdata/geojson/muenster_ring.geojson
When to Use Convex Hull¶
Use convex hull when:
You have vector data with complex or irregular shapes
You need a more accurate representation of the actual data coverage
You’re working with point data that doesn’t fill a rectangular area
The bounding box would include large areas with no data
Use bounding box when:
You need a simple rectangular extent
You’re working with raster data (convex hull not applicable)
You need maximum performance (bounding box is faster)
You need compatibility with systems that only accept rectangular extents
Combining with Other Features¶
# Convex hull with placename lookup
python -m geoextent -b --convex-hull --placename nominatim tests/testdata/geojson/muenster_ring.geojson
# Convex hull with WKT output format
python -m geoextent -b --convex-hull --format wkt tests/testdata/geojson/muenster_ring.geojson
# Convex hull from repository data
python -m geoextent -b --convex-hull --max-download-size 100MB https://doi.org/10.5281/zenodo.4593540
See Also¶
Quick Start Guide - Quick introduction to basic usage
Examples - Detailed examples for common tasks
advanced-features - Specialized options and performance tuning
Content Providers - Repository provider details
Command-Line Interface (CLI) - Complete CLI reference
API Docs - Python API documentation