Runnable Examples
The examples/ directory contains focused scripts for the common UavPy workflows.
Run them from the repository root so the shared paths in examples/common.py
resolve consistently.
| uv run python examples/demo.py
|
Shared Demo Paths
Each example imports the same dataset paths and output folders:
1
2
3
4
5
6
7
8
9
10
11
12
13 | """Shared paths and settings for the UavPy examples."""
from pathlib import Path
DATA_FOLDER = Path("../data/Stephenville_Peanut_Images")
MULTISPECTRAL_ORTHOMOSAIC = (
DATA_FOLDER / "Multispectral/ms_orthomosaic_Y2025_20250819_cog.tif"
)
RGB_ORTHOMOSAIC = DATA_FOLDER / "RGB/rgb_orthomosaic_Y2025_20250819.tif"
PLOT_BOUNDARY = DATA_FOLDER / "plot_boundary/plots_shapefile.shp"
TILE_DIR = Path("examples/.uavpy_tiles")
PLOT_EXPORT_DIR = Path("examples/.uavpy_plots")
|
Update these constants for your local project before running the scripts.
Load An Orthomosaic
Use this first to validate the input path, inspect shape and dtype, and confirm
the available bands.
| uv run python examples/load_orthomosaic.py
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | """Load an orthomosaic and inspect its raster metadata."""
import asyncio
from dotenv import find_dotenv, load_dotenv
from common import MULTISPECTRAL_ORTHOMOSAIC
from uavpy.artifacts import Orthomosaic
async def main() -> None:
"""Load the demo orthomosaic and print metadata used by later examples."""
load_dotenv(find_dotenv())
orthomosaic = Orthomosaic.from_path(MULTISPECTRAL_ORTHOMOSAIC)
await orthomosaic.load()
print("Path:", MULTISPECTRAL_ORTHOMOSAIC)
print("Shape:", orthomosaic.shape)
print("Dtype:", orthomosaic.dtype)
print("Band info:", orthomosaic.band_info)
if __name__ == "__main__":
asyncio.run(main())
|
This workflow loads a plot shapefile, crops the orthomosaic by each feature,
and saves one sample plot as both GeoTIFF and PNG.
| uv run python examples/extract_plot_rois.py
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | """Extract plot-level regions of interest from an orthomosaic."""
import asyncio
import matplotlib.pyplot as plt
from dotenv import find_dotenv, load_dotenv
from common import MULTISPECTRAL_ORTHOMOSAIC, PLOT_BOUNDARY, PLOT_EXPORT_DIR
from uavpy.artifacts import Orthomosaic, ShapeFile
async def main() -> None:
"""Crop the demo orthomosaic by plot polygons and save one sample plot."""
load_dotenv(find_dotenv())
shape_file = ShapeFile(PLOT_BOUNDARY, target_crs="EPSG:4326")
await shape_file.load()
print("Shape fields:", list(shape_file.gdf.columns))
orthomosaic = Orthomosaic.from_path(MULTISPECTRAL_ORTHOMOSAIC)
await orthomosaic.load()
plots = await orthomosaic.extract_plots(shape_file, plot_id_field="Plot No")
PLOT_EXPORT_DIR.mkdir(parents=True, exist_ok=True)
for plot in plots[:1]:
plot_id = str(plot.attrs["plot_id"])
print("Plot:", plot_id, plot.shape)
fig, _ = plot.plot(
rgb=(6, 4, 2),
title=f"Plot {plot_id}",
show=False,
)
plot.save(PLOT_EXPORT_DIR / f"{plot_id}.tif", overwrite=True)
fig.savefig(PLOT_EXPORT_DIR / f"{plot_id}.png")
plt.close(fig)
if __name__ == "__main__":
asyncio.run(main())
|
Compute Spectral Indices
This example computes NDVI and NDRE with one-based band numbers and saves the
derived rasters for downstream analysis or map display.
| uv run python examples/compute_spectral_indices.py
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | """Compute spectral indices from a multispectral orthomosaic."""
import asyncio
from dotenv import find_dotenv, load_dotenv
from common import MULTISPECTRAL_ORTHOMOSAIC, PLOT_EXPORT_DIR
from uavpy.artifacts import Orthomosaic
from uavpy.tools import SpectralIndex
async def main() -> None:
"""Compute NDVI and NDRE rasters from the demo multispectral orthomosaic."""
load_dotenv(find_dotenv())
orthomosaic = Orthomosaic.from_path(MULTISPECTRAL_ORTHOMOSAIC)
await orthomosaic.load()
ndvi = await SpectralIndex.ndvi(nir=6, red=4)(orthomosaic)
ndre = await SpectralIndex.ndre(nir=6, red_edge=5)(orthomosaic)
PLOT_EXPORT_DIR.mkdir(parents=True, exist_ok=True)
ndvi_path = PLOT_EXPORT_DIR / "ndvi.tif"
ndre_path = PLOT_EXPORT_DIR / "ndre.tif"
ndvi.save(ndvi_path, overwrite=True, dtype="float32")
ndre.save(ndre_path, overwrite=True, dtype="float32")
print("NDVI:", ndvi.shape, ndvi_path)
print("NDRE:", ndre.shape, ndre_path)
if __name__ == "__main__":
asyncio.run(main())
|
Show An Interactive Map
This example uses mapwidgets to generate raster tiles with the Python backend
and display them with plot boundaries in a desktop map.
| uv run python examples/show_interactive_map.py
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | """Display raster and vector layers in a mapwidgets desktop map."""
import asyncio
import sys
from dotenv import find_dotenv, load_dotenv
from mapwidgets import MapViewer, RasterLayer, VectorLayer
from PySide6.QtWidgets import QApplication
from common import MULTISPECTRAL_ORTHOMOSAIC, PLOT_BOUNDARY, TILE_DIR
async def main() -> None:
"""Generate tiles for the demo raster and display them with plot boundaries."""
load_dotenv(find_dotenv())
tile_layer = RasterLayer.from_tiled_geotiff(
MULTISPECTRAL_ORTHOMOSAIC,
output_dir=TILE_DIR / "false_color",
bands=(6, 4, 2),
zoom_levels=range(18, 23),
backend="python",
max_tiles=5000,
overwrite=True,
opacity=0.85,
transparent_values=(0,),
transparent_match="any",
)
app = QApplication.instance() or QApplication(sys.argv[:1])
viewer = MapViewer(backend="maplibre").resize(1200, 800).show()
viewer.add_layer(tile_layer, zoom_to=True)
viewer.add_layer(
VectorLayer.from_shapefile(PLOT_BOUNDARY, id="plots", name="Plot boundaries"),
)
viewer.wait_for_map_ready()
app.exec()
if __name__ == "__main__":
asyncio.run(main())
|