Campaign¶
A Campaign organises a study area, airspace data,
flight lines, reusable patterns, and line groups into a single object that can
be saved to and loaded from a plain folder.
Folder structure¶
my_campaign/
campaign.json # name, version, campaign_id, revision metadata
domain.geojson # study area polygon
airspaces.json # raw OpenAIP items (re-parsed on load)
flight_lines/
all_lines.geojson # free-standing flight lines only
groups.json # logical groupings with generation params
patterns/
all_patterns.json # serialized Pattern objects
What changed in the pattern-aware campaign model¶
Campaigns now manage both free-standing lines and first-class
Patternobjects.Line-based patterns receive stable campaign-global
line_idvalues when added to a campaign.Campaign mutation bumps
revisionandupdated_at, which makes the object easier to synchronize with interactive clients.patterns_to_geojson()exposes waypoint-based pattern geometry for map display, whileflight_lines_to_geojson()continues to expose all line geometry.
Common workflow¶
Build a pattern with a generator such as
racetrack().Add it to a campaign with
add_pattern().Edit the pattern or individual legs with
replace_pattern(),replace_line_anywhere(), orreplace_line().Save the campaign and use the stored IDs and revision metadata to track changes across planning sessions.
Campaign class¶
- class Campaign[source]¶
Bases:
objectA flight campaign with geographic domain, reference data, and flight lines.
- Parameters:
name (
str) – Human-readable campaign name.bounds (
Optional[Tuple[float,float,float,float]]) –(min_lon, min_lat, max_lon, max_lat)bounding box. Mutually exclusive with polygon.polygon (
Optional[Polygon]) – Shapely Polygon defining the domain boundary. Mutually exclusive with bounds.country (
Optional[str]) – Optional ISO 2-letter country code to filter API results.
- Raises:
HyPlanValueError – If neither or both of bounds/polygon are given, or if coordinates are out of range.
- property flight_lines: List[FlightLine]¶
- fetch_airspaces(api_key=None, force=False)[source]¶
Fetch airspaces from OpenAIP for this domain.
If data is already loaded (from a previous fetch or from
load()), this is a no-op unless force=True.Returns self for chaining.
- check_conflicts(flight_lines=None)[source]¶
Check flight lines against this campaign’s airspaces.
- Parameters:
flight_lines – Lines to check. If None, checks this campaign’s own flight lines.
- Raises:
HyPlanRuntimeError – If airspace data has not been fetched.
- Return type:
- add_flight_lines(lines, group_name=None, group_type='manual', generation_params=None)[source]¶
Add flight lines to the campaign and create a group.
- Parameters:
lines (
List[FlightLine]) – Flight lines to add.group_name (
Optional[str]) – Human-readable group name. Defaults to"group_NNN".group_type (
str) – Group type label ("flight_box","pattern","single_line","manual").generation_params (
Optional[dict]) – Optional dict recording how the lines were generated (method, parameters) for reproducibility.
- Return type:
- Returns:
The group ID string.
- remove_flight_line(line_id)[source]¶
Remove a flight line by ID and update group memberships.
Removes line_id from the campaign-wide flight-line registry and from any groups that reference it. Groups left with no remaining lines are removed.
- Parameters:
line_id (
str) – Stable campaign line ID, e.g."line_001".- Raises:
HyPlanValueError – If line_id is not present in the campaign.
- Return type:
- replace_flight_line(line_id, line)[source]¶
Replace an existing flight line in place, preserving its ID.
- Parameters:
line_id (
str) – Stable campaign line ID to replace.line (
FlightLine) – NewFlightLineobject.
- Raises:
HyPlanValueError – If line_id is not present in the campaign.
HyPlanValueError – If line is not a
FlightLineinstance.
- Return type:
- flight_lines_to_geojson()[source]¶
Return all campaign flight lines as a GeoJSON FeatureCollection.
Each feature includes the stable
line_idin both the featureidfield and inproperties.line_id. Includes free-standing lines as well as flight lines that belong to line-based patterns; pattern lines carrypattern_idandpattern_kindin their properties.- Return type:
- add_pattern(pattern)[source]¶
Add a pattern to the campaign.
Assigns a stable
pattern_idand rekeys any contained flight lines with campaign-globalline_idvalues. The input Pattern is mutated in place so the caller holds the live reference.
- remove_pattern(pattern_id)[source]¶
Remove a pattern and all of its contained flight lines or waypoints.
- replace_pattern(pattern_id, new_pattern)[source]¶
Replace a pattern in place, preserving its
pattern_id.Contained flight lines receive fresh campaign-global
line_idvalues — callers that want to preserve individual line IDs should usePattern.replace_line()instead.
- patterns_to_geojson()[source]¶
Return waypoint-based patterns as one GeoJSON FeatureCollection for display.
Only waypoint-based patterns (polygon, sawtooth, spiral) contribute features here; their geometry (Point waypoints + connecting track) is not available elsewhere. Line-based patterns (rosette, racetrack) are intentionally omitted because their legs are already exposed through
flight_lines_to_geojson(); emitting them again would cause duplicate rendering in map clients.- Return type:
- get_line(line_id)[source]¶
Return the FlightLine with line_id from free-standing lines or any line-based pattern. Raises if not found.
- Return type:
- Parameters:
line_id (str)
- find_pattern_for_line(line_id)[source]¶
Return the Pattern owning line_id, or None if the line is free-standing or does not exist.
- all_flight_lines()[source]¶
Return all FlightLines in the campaign: free-standing plus pattern-owned lines, in a stable order.
- Return type:
- all_flight_lines_dict()[source]¶
Return
{line_id: FlightLine}for every flight line in the campaign — free-standing or pattern-owned.- Return type:
- replace_line_anywhere(line_id, line)[source]¶
Replace a flight line by id whether free-standing or pattern-owned.
Routes to
replace_flight_line()for free-standing lines orPattern.replace_line()on the owning pattern.- Return type:
- Parameters:
line_id (str)
line (FlightLine)
- remove_line_anywhere(line_id)[source]¶
Remove a flight line by id whether free-standing or pattern-owned.
Free-standing removal uses
remove_flight_line()(deletes the line and trims empty groups). Pattern-owned removal drops the leg from the pattern and, if the pattern has no legs left, removes the pattern entirely.
- save(path)[source]¶
Save the campaign to a folder.
Creates the directory structure and writes all files. Existing files are overwritten.