harpia is an open-source Python library to program automatic close-up photo missions to carry out with the DJI Mavic 3E or Matrice 4E drones. It generates an optimized flight path from feature locations (selected tree crowns for example) to acquire the close-up photos, supporting tropical botanical and ecological work.
Automatically generates optimized flight paths from tree/feature locations:
- Input: Features (centroids, points or polygons) from GeoPackage/Shapefile + Digital Surface Model (DSM)
- Process: Extracts elevations, solves Traveling Salesman Problem (TSP) for optimal route, creates path checkpoints above obstacles
- Output: Waypoints CSV with precise coordinates and flight heights above features
Converts waypoints into DJI-compatible mission files:
- Template KML: Defines mission structure and flight parameters
- Waylines WPML: Contains detailed waypoint sequences and actions
- KMZ Package: Complete mission file ready for DJI Pilot 2 app
Periodically ascends to a higher altitude to re-establish signal and transmit updated RTK corrections to the drone:
- Purpose: Fly to higher altitude periodically to restore connection between controller and drone before losing RTK signal
- Configurable: Set interval (every N waypoints) and altitude (up to 200m above DSM)
Optionally specify takeoff coordinates (--takeoff-coords or in YAML config). The first waypoint will be automatically selected as the closest one to the provided coordinates, optimizing the initial flight path from the takeoff location.
- Purpose: Start the mission from a defined first waypoint for improved route planning
- Configurable: Provide coordinates as
x y(projected CRS) orlat lon(WGS84)
Clone the repository to your local machine:
git clone https://github.com/traitlab/harpia.git
cd harpiaInstall the required Python packages in a python 3.11 conda environment:
conda create -n harpia python=3.11
conda activate harpia
pip install -r requirements.txtIt is possible to pass a YAML configuration file or to use command-line arguments when running the pipeline.
Create a configuration file (e.g., config.yaml) with your settings. A detailed configuration template, including explicit descriptions for each argument, is available in the config folder.
# Input/Output settings
csv_path: /path/to/waypoints.csv # Optional
features_path: /path/to/features.gpkg # Optional
dsm_path: /path/to/dsm.tif # Optional
drone_model: m3e # 'm3e' and 'm4e' are currently supported
output_folder: /path/to/output # Optional
output_filename: my_mission # Optional
# Flight settings
buffer: 6
approach: 10
# Waypoint generation settings
buffer_path: 10 # Optional
buffer_feature: 3 # Optional
takeoff_coords: [45.5572, -73.5558] # Optional (lat lon for WGS84, or x y if projected)
takeoff_coords_projected: false # Optional
# Area of Interest (AOI) settings
aoi_path: /path/to/aoi.gpkg # Optional
aoi_index: 1 # Optional
aoi_qualifier: north # Optional
# Touch-sky settings
touch_sky: false
touch_sky_interval: 10
touch_sky_altitude: 100
# System settings
debug_mode: false--config, -c: Path to YAML configuration file--csv, -csv: Path to existing waypoints CSV file--features, -f: Path to input features file (GeoPackage, Shapefile)--dsm, -dsm: Path to DSM raster file--drone-model, -m: Model of the drone to carry out the mission ('m3e' or 'm4e')--output-path, -op: Output directory path (optional)--output-filename, -of: Custom output filename without extension (optional)
--aoi, -aoi: Path to AOI file for filtering features (optional)--aoi-index, -i: Index of AOI polygon to use (optional)--aoi-qualifier, -q: Qualifier for AOI in output filename (optional)
--takeoff-coords, -to: Takeoff site coordinates as two floats: x y OR lat lon (optional)--takeoff-coords-projected, -proj: Flag to indicate takeoff coordinates are in projected CRS (default: False (WGS84)) (optional)
--touch-sky, -ts: Enable touch-sky feature (default: False)--touch-sky-interval, -n: Number of features between touch-sky actions (default: 10, min: 5)--touch-sky-altitude, -alt: Touch-sky altitude in meters above DSM (default: 100, min: 16, max: 200)
--debug, -d: Run in debug mode
python main.py --config config.yaml(replace \ with ^ for Windows Command Prompt)
with custom output settings and --touch-sky option to enable periodic ascents
python main.py \
--csv waypoints.csv \
--output-path /path/to/output \
--output-filename my_mission \
--touch-skypython main.py \
--features data/site_centroids.gpkg \
--dsm data/dsm.tifpython main.py \
--features data/site_polygons1.gpkg \
--dsm data/dsm.tif \
--aoi data/aoi.gpkg \
--aoi-index 2 \
--aoi-qualifier north- Format: GeoPackage (.gpkg) or Shapefile (.shp)
- Geometry: Point, Polygon, or MultiPolygon
- Naming convention:
{site}_{centroids|points|polygons}[version].{ext}- Examples:
site_centroids.gpkg,area_polygons3.shp
- Examples:
- CRS: Any projected coordinate system that matches the DSM and AOI
- Unique Identifier: Each feature should have a unique
point_idorFIDthat will be used for naming output pictures
- Format: GeoTIFF (.tif, .tiff)
- Content: Ellipsoidal elevation values in meters
- CRS: Any projected coordinate system that matches the features and AOI
- Format: GeoPackage (.gpkg) or Shapefile (.shp)
- Geometry: Polygon or MultiPolygon
- Purpose: Filter features to specific areas
- CRS: Any projected coordinate system that matches the features and DSM
The pipeline generates several output files:
{site}_wpt[qualifier][version].csv: Waypoints for mission generation{site}_wpt[qualifier][version].gpkg: Spatial waypoints data to visualize in GIS software
The output CSV from features-based waypoint generation contains the following columns:
point_id: Unique identifier for each pointcluster_id: Cluster identifier if available (default: 0)type: Point type ('wpt' for waypoints, 'cpt' for checkpoints)lon_x: Longitude in WGS84lat_y: Latitude in WGS84elevation_from_dsm: Ellipsoidal elevation from DSM in metersorder: Waypoint order for mission planning
CSV as input needs to respect the format above.
template.kml: KML template for DJI missionwaylines.wpml: WPML waylines for DJI dronemission.kmz: Complete mission package to upload to DJI Pilot 2 app
If you use harpia in your research, please cite our paper (bioRxiv preprint):
@misc{Lalibert2025harpia,
title={Seeing the forest and the trees: a workflow for automatic acquisition of ultra-high resolution drone photos of tropical forest canopies to support botanical and ecological studies},
author={Laliberté, Etienne and Caron-Guay, Antoine and Le Falher, Vincent and Tougas, Guillaume and Muller-Landau, Helene C. and Rivas-Torres, Gonzalo and Walla, Thomas R. and Baudchon, Hugo and Hernandez, Mélvin and Buenaño, Adrian and Weber, Anna and Chambers, Jeffrey and Inuma, Jomber and Araúz, Fernando and Valdes, Jorge and Hernández, Andrés and Brassfield, David and Sérgio, Paulo and Vasquez, Vicente and Simonetti, Adriana and Marra, Daniel M. and Vasconcelos, Caroline and Vaca, Jarol F. and Rivadeneyra, Geovanny and Illanes, José and Salagaje-Muela, Luis A. and Gualinga, Jefferson},
year={2025},
url={https://www.biorxiv.org/content/10.1101/2025.09.02.673753v1},
doi={10.1101/2025.09.02.673753},
keywords={Unoccupied aerial vehicle (UAV),biodiversity,monitoring,RGB imagery,canopy,remote tree-survey,Panama,Ecuador,Brazil,tropical tree diversity}
}