Flight Planning

Contextual Airspace Preview

Contextual Airspace (Rules API, Advisory API, and Flight Plan API) is currently in developer PREVIEW for testing and is subject to change. Please Contact Us for more information.

The flight planning process provides the opportunity to create, review, and update a potential flight on the AirMap platform prior to submitting. The real value of flight planning comes through, however, when utilized within the framework of Contextual Airspace. By sending values for desired Rulesets and Flight Features during the planning process, your application can provide the pilot with clear picture of their compliance status and the opportunity to make any necessary adjustments prior to flight.

1. Create Flight Plan

The first step of the flight planning process is to create a new Flight Plan using the AirMap Flight API.

The Flight API requires that, at a minimum, your application passes the following details for a flight:

Parameter
Type
Description

geometry

String

GeoJSON Polygon of flight area

takeoff_latitude

Float

Latitude of take off location in decimal format

takeoff_longitude

Float

Longitude of take off location in decimal format

max_alittude_agl

Double

Maximum altitude in meters Above Ground Level

pilot_id

String

Pilot (user) identifier

start_time

String

Start time of flight in ISO 8601 format (cannot be in the past)

end_time

String

End time of flight in ISO 8601 format (must be after start_time)

buffer

Integer

Buffer around flight area in meters (must be at least 1)

In order to receive a detailed Fight Briefing, you must also include some context about the flight, namely, which Rulesets the pilot is operating under and, optionally, other Flight Features based on those rulesets:

Parameter
Type
Description

rulesets

Array of Strings

String list of rulesets

flight_features

Array of Objects

List of key:value pairs of individual flight features and their corresponding values provided by the pilot

See the full Flight Plan API reference for more details.

Note

Including Contextual Airspace in a Flight Plan is optional, but it is required to generate a Flight Briefing. Including rulesets will return the relevant advisories, and including flight features will evaluate the flight against each of the rules in the rulesets. If you would prefer not to use Contextual Airspace in the flight plan, your application can directly submit the flight after creating a flight plan.

As an example, create a flight plan within a park in Los Angeles. You will include the optional rulesets parameter, identifying your pilot as a US Part 107 operator in this case, so that a flight briefing can be generated.

Note

Authorization requires a valid JSON Web Token. See SSO Authentication for instructions on obtaining a token.

## Create Flight Plan (Polygon)
curl -X "POST" "https://api.airmap.com/flight/v2/plan" \
     -H "Content-Type: application/json; charset=utf-8" \
     -H "Authorization: Bearer <AUTH_TOKEN>" \
     -H "X-API-Key: <API_KEY>" \
     -d $'{
  "rulesets": [
    "usa_part_107"
  ],
  "start_time": "now",
  "end_time": "2018-01-01T12:00:00-08:00",
  "max_altitude_agl": 60.96,
  "takeoff_latitude": "33.85505651142062",
  "takeoff_longitude": "-118.37099075317383",
  "buffer": "1",
  "geometry": "{ \\"type\\": \\"Polygon\\", \\"coordinates\\": [ [ [ -118.37099075317383, 33.85505651142062 ], [ -118.37305068969727, 33.85502978214579 ], [ -118.37347984313963, 33.854673391015496 ], [ -118.37306141853333, 33.85231226221667 ], [ -118.37193489074707, 33.85174201755203 ], [ -118.36997151374815, 33.85176874785573 ], [ -118.36995005607605, 33.8528112231754 ], [ -118.37099075317383, 33.85505651142062 ] ] ] }",
  "pilot_id": "auth0|591dea1006732e54be4b875f"
}'

## The response confirms the details of the submitted flight plan as well as including the newly generated flight plan `id`.

{
  "status": "success",
  "data": {
    "rulesets": [
      "usa_part_107"
    ],
    "start_time": "now",
    "end_time": "2018-01-01T12:00:00-08:00",
    "max_altitude_agl": 60.96,
    "takeoff_latitude": "33.85505651142062",
    "takeoff_longitude": "-118.37099075317383",
    "buffer": "1",
    "geometry": "{ \\"type\\": \\"Polygon\\", \\"coordinates\\": [ [ [ -118.37099075317383, 33.85505651142062 ], [ -118.37305068969727, 33.85502978214579 ], [ -118.37347984313963, 33.854673391015496 ], [ -118.37306141853333, 33.85231226221667 ], [ -118.37193489074707, 33.85174201755203 ], [ -118.36997151374815, 33.85176874785573 ], [ -118.36995005607605, 33.8528112231754 ], [ -118.37099075317383, 33.85505651142062 ] ] ] }",
    "pilot_id": "auth0|591dea1006732e54be4b875f",
    "id": "flight_plan|Dv5oxg8FXL7PQCylRO0piJn0LMq"
  }
}
let point = AirMapPoint(coordinate: Coordinate2D(latitude: 34.2, longitude: -118.5))
let rulesetIds: [AirMapRulesetId] = ["usa_part_107", "usa_sec_91"]
let flightPlan = AirMapFlightPlan(startTime: Date(), duration: 60*60, takeoffCoordinate: point.coordinate)

flightPlan.rulesetIds = rulesetIds
flightPlan.geometry = point
flightPlan.buffer = 100

AirMap.createFlightPlan(flightPlan) { (result: Result<AirMapFlightPlan>) in
	
	switch result {
	case .error(let error):
		print(error)
	case .value(let flightPlan):
		print(flightPlan.id!)
	}
}
// sets required params
AirMapFlightPlan flightPlan = new AirMapFlightPlan();
flightPlan.setPilotId(AirMap.getUserId());
flightPlan.setGeometry(polygon);
flightPlan.setBuffer(buffer);
flightPlan.setTakeoffCoordinate(takeoffCoordinate);
flightPlan.setRulesetIds(rulesetIds);

flightPlan.setMaxAltitude(100);

flightPlan.setStartsAt(startDate);
flightPlan.setEndsAt(endDate);

AirMap.createFlightPlan(flightPlan, new AirMapCallback<AirMapFlightPlan>() {
    @Override
    protected void onSuccess(AirMapFlightPlan response) {
        AirMapLog.d(TAG, "Flight plan created: " + response.getPlanId());
        // Handle success
    }

    @Override
    protected void onError(AirMapException e) {
        AirMapLog.e(TAG, "Failed to create flight plan", e);
        // Handle error
    }
});

Now that the flight plan is created, you are ready to receive a briefing for the flight. You can skip to Flight Briefing or continue reading to learn how to update a flight plan.

2. Update Flight Plan

Sometimes plans change, and flight plans are no different. The pilot may want to change the location or other parameters of their flight, especially after reviewing the flight briefing. Consider that the pilot has now decided to "Fly for Fun" under US Sec 336 rules rather than US Part 107. Based on this input, your application can update the flight plan rulesets with a PATCH:

Note that the API endpoint has changed slightly to include the flight plan id which was returned when creating the flight plan.

## Update Flight Plan (Rulesets)
curl -X "PATCH" "https://api.airmap.com/flight/v2/plan/flight_plan%7CDv5oxg8FXL7PQCylRO0piJn0LMq" \
     -H "Content-Type: application/json; charset=utf-8" \
     -H "Authorization: Bearer <AUTH_TOKEN>" \
     -H "X-API-Key: <API_KEY>" \
     -d $'{
  "rulesets": [
    "usa_sec_336"
  ]
}'

## The response confirms that the flight plan has been updated with the new ruleset, with no changes to the other original parameter values:
{
  "status": "success",
  "data": {
    "rulesets": [
      "usa_sec_336",
      "usa_sec_91"
    ],
    "start_time": "now",
    "end_time": "2018-01-01T12:00:00-08:00",
    "max_altitude_agl": 60.96,
    "takeoff_latitude": "33.85505651142062",
    "takeoff_longitude": "-118.37099075317383",
    "buffer": "1",
    "geometry": "{ \\"type\\": \\"Polygon\\", \\"coordinates\\": [ [ [ -118.37099075317383, 33.85505651142062 ], [ -118.37305068969727, 33.85502978214579 ], [ -118.37347984313963, 33.854673391015496 ], [ -118.37306141853333, 33.85231226221667 ], [ -118.37193489074707, 33.85174201755203 ], [ -118.36997151374815, 33.85176874785573 ], [ -118.36995005607605, 33.8528112231754 ], [ -118.37099075317383, 33.85505651142062 ] ] ] }",
    "pilot_id": "auth0|591dea1006732e54be4b875f",
    "id": "flight_plan|Dv5oxg8FXL7PQCylRO0piJn0LMq"
  }
}

let rulesetIds: [AirMapRulesetId] = ["usa_sec_336", "usa_sec_91"]
flightPlan.rulesetIds = rulesetIds

AirMap.updateFlightPlan(flightPlan) { result in
	switch result {
	case .error(let error):
		print(error)
	case .value(let flightPlan):
		print(flightPlan.id!)
	}
}
AirMap.updateFlightPlan(flightPlan, new AirMapCallback<AirMapFlightPlan>() {
    @Override
    protected void onSuccess(AirMapFlightPlan response) {
        AirMapLog.d(TAG, "Flight plan updated: " + response.getPlanId());
        // Handle success
    }

    @Override
    protected void onError(AirMapException e) {
        AirMapLog.e(TAG, "Failed to update flight plan", e);
        // Handle error
    }
});

What's Next

You have created a flight plan, now you can review a flight briefing before deciding to submit the flight

Flight Briefing

Flight Planning