Vessel Routing API (Marine Content Services) (1.738)

Download OpenAPI specification:Download

DTN customer service: apisupport@dtn.com URL: https://www.dtn.com

Introduction

The Marine Content Services - Vessel Routing API from DTN can create routes for your vessel optimized by weather. It consists of two APIs:

REST API

The REST API can be used to retrieve specific data entities. These are things such as ports, weather limits, etc. This information can be used in a route request.

The REST API can be found at:

  • https://routing.api.shipping.dtn.com/v1

Asynchronous API

Connection

The async API is exposed using the Websocket protocol. Connection to the websocket endpoint needs to be successfully created to be able to send a request and receive a response. Valid token should be provided with the request in "Authorization" header to successfully open a connection, otherwise "401" error will be returned. The response to the request will be sent to the open connections that have the same client_id that initiated the request.

Requesting a route

Each request should contain a client specified id, to be able to correlate request and response on the client side. This is following a design similar to RPC, especially a more recent implementations such as JSON-RPC. User must be authorized for the corresponding request type, otherwise "403" error will returned.

Responses

Response shall be received when the calculation is finished. All existing open connections that use the same client_id to send the request, will receive the same response from the Vessel Routing API. To ensure the size of the response doesn't exceed the size limitation of a websocket message, a linked response is returned, which contains a URL to download the full response.

An empty route can be received if an issue is encountered during route calculation, description of the issue can be checked under warnings.

In case of any problem with the request or error during processing of the request, a failed response will be returned with the problem details. In case of an internal error that might be solved by retrying, the request is retried. This is indicated using a Running Response with an accompanying message. Below is the list of error codes that the async API might return:

Error codes
Code Type Description
400 BadRequest Request was not accepted (e.g. incorrect format)
401 Unauthorized No valid credentials were provided in the request
403 Forbidden Credentials are valid, but user is not allowed to execute the request
410 Connection Problem with the connection (e.g. connection is gone)
422 Validation Request was not coherent
500 RequestProcessing Something went wrong while trying to process the request
500 Internal An internal error happened
500 RoutingCalculation An error happened during routing calculation

Timeouts and limits

When a connection is idle for 10 minutes, the connection is automatically closed from the server. An active connection will be automatically closed after 2 hours. This will be accompanied with the corresponding close code 1001, as specified by WebSocket protocol. Client will also get disconnected upon sending a new request on a connection of which the access token is expired. The client code has to be setup to automatically reconnect after a close from server side.

Response is marked as pending when it is ready and no single connection is open to receive it. All pending responses for requests created within 24 hours will be resent once a new connection is opened, otherwise, a request should be reissued for those exceeding the timeframe.
An additional error response is also expected to be received once reconnected, with the following message:
"No valid connection to send the response. Response will be sent again once connection is established.". This is the response that the API tried to send after failing to send the first response.

The message size limit is 128 KB, when this is split up in 4 frames of 32 KB each. Usually websocket client libraries will do this automatically. A message over 128 KB will result in a closed connection as well (with code 1009). A typical route request will not reach this message size limit.

Endpoints

The following endpoints are available:

  • Shortest path :
    A path with minimal distance is calculated using the route network and great circle in open water. No other restrictions or weather optimization are considered.
    Endpoint: wss://shortest-path.routing.api.shipping.dtn.com/v1, Required Scope: VRA-ShortestPath

  • Shortest route :
    A viable route is calculated that minimizes distance and takes into account the given vessel parameters and the route network. Weather is reported along the resulting route but not used in optimizing the route.
    Endpoint: wss://shortest-route.routing.api.shipping.dtn.com/v1, Required Scope: VRA-ShortestRoute

  • Instructed speed :
    A weather optimized route is calculated with a given fixed speed along the route.
    Endpoint: wss://instructed-speed.routing.api.shipping.dtn.com/v1, Required Scope: VRA-InstructedSpeed

  • Recommended speed :
    A weather optimized route is calculated with a given range(s) of speeds, the one most optimum speed is selected for the result.
    Endpoint: wss://recommended-speed.routing.api.shipping.dtn.com/v1, Required Scope: VRA-RecommendedSpeed

  • Variable speed :
    Recommends a variable speed along the weather optimized route that will arrive closest to but before a given target ETA.
    Endpoint: wss://variable-speed.routing.api.shipping.dtn.com/v1, Required Scope: VRA-VariableSpeed

The specifics of the requests and responses can be found in the Async API section below.

Other

Units

Please refer to the descriptions of specific properties to confirm the units used. However, as a rule of thumb, larger scale distances such as route lengths are in nautical miles, shorter distances such as vessel dimensions are in meters. Correspondingly vessel speeds are in knots and most weather elements are in meters and knots. Absolute courses and directions are decimal degrees clockwise from north. Date and times follow the RFC 3339 standard and are in UTC.

Weather Elements

The following table describes the weather elements used in the API:

Weather Elements Table
Weather Element Unit Description
Pressure hectopascals/millibars (hPa) Air pressure
hPa500 meters (m) Altitude where the pressure is 500 hPa
AirTemperature degrees Celsius (°C) Air temperature at 10 meters above sea
WaterTemperature degrees Celsius (°C) Sea water temperature
WaveHeight meters (m) Sea significant wave height (Hs)
WavePeriod seconds (s) Mean wave period (Tm) of sea waves
SwellHeight meters (m) Swell significant wave height (Hs)
SwellPeriod seconds (s) Mean wave period (Tm) of swell waves
SwellDirection degrees (deg) Swell wave direction (represented according to the nautical convention)
WindSpeed10m knots (kn) Wind speed
WindDirection10m degrees ( deg) Wind direction (represented according to the wind convention)
WindSpeed50m knots (kn) Wind speed at 50 meters
WindDirection50m degrees ( deg) Wind direction at 50 meters (represented according to the wind convention)
WindGusts10m knots (kn) Wind gusts at 10 meters
WindGusts50m knots (kn) Wind gusts at 50 meters
RiskWindSpeed knots (kn) Risk wind speed. There is 90% confidence that wind speed at 10 metres height will not exceed this value
RiskWaveHeight meters (m) Risk wave height. There is 90% confidence that the significant wave height will not exceed this value
Precipitation percent (%) Precipitation probability
RelativeHumidity percent (%) Relative Humidity
FreezingLevel meters (m) Altitude of freezing level
DewPoint degrees Celsius (°C) Dew point
SeaWaterSalinity parts per million (ppm) The salinity of the seawater
CurrentDirection degrees (deg) Direction of the current (represented according to the nautical convention)
CurrentSpeed knots (kn) Speed of the current speed.
Visibility enum Visibility Level: Poor, PoorModerate, Moderate, ModerateGood, Good
IcingRisk enum Risk of Icing: None, Light, Moderate, Severe, VerySevere
WeatherClass enum The general class of weather: Clear, Partly cloudy, Cloudy, Fog, Drizzle, Rain, Freezing rain, Snow, Rain shower, Snow shower, Hail, Thunder

Standards

Most geographic information complies with the GeoJSON spec, although requests and responses as a whole do not.

Vessel Models

The DTN weather optimized routing algorithm uses vessel models to simulate a vessel's performance in specific weather conditions. Approximately 50 different default models are available (provided in close cooperation with the Marin Maritime Research institute) for different vessel types and size classes. Additionally, clients can provide their own models included in the request (or in the future separately uploaded to the Vessel Profiles API). more info

Restrictions

The route request calculations are accounting for specific restrictions. In case the relevant properties are set within a route request, the below restrictions will be applied.

  • Cargo
    On some local shipping routes, it is prohibited to carry specific cargo goods. The returned route will comply with the local cargo type restrictions.
    Input properties used: vesselParameters.cargoTypes

  • Vessel Type
    Some local shipping routes are prohibited for specific vessel classes. The returned route will comply with the local vessel type restrictions.
    Input properties used: vesselParameters.vesselType

  • Length Overall
    Some local shipping routes have vessel length overall restrictions. The returned route will comply with the local vessel length overall restrictions.
    Input properties used: vesselParameters.measurements.lengthOverall

  • Gross Tonnage
    Some local shipping routes have gross tonnage restrictions. The returned route will comply with the local gross tonnage restrictions.
    Input properties used: vesselParameters.measurements.grossTonnage

  • Maximum Draft
    Some local shipping routes have maximum draft restrictions. The returned route will comply with the local vessel draft restrictions.
    Input properties used: vesselParameters.measurements.draft

  • Vertical Clearance
    Some locations have a maximum vertical clearance where vessel can pass, the combination of air draft and the air safety margin is used to avoid locations with too little vertical clearance.
    Input properties used: vesselParameters.measurements.airDraft, vesselParameters.safetyMargins.air(optional)

  • Beam size
    Some local shipping routes have maximum beam size restrictions. The returned route will comply with the local beam size restrictions.
    Input properties used: vesselParameters.measurements.beam

  • Conditional Areas
    Areas are taken into account that hold specific restrictions, usually to comply with governmental or company regulations (e.g., speed limits, emission control, avoidance areas). Depending on the properties used you can enable (i) a whole conditional area group, (ii) override specific active conditional areas or (iii) specify your own conditional areas.
    Input properties used: restrictions.conditionalAreas

  • Local traffic
    Areas that are off-limits to vessels that are not stopping at specific ports (through traffic) are avoided and only available to voyages starting or ending at those ports (local traffic). If no voyage ports are given, this restriction will not be applied, but a warning will be issued if the route goes through an area that is off limits to through traffic.
    Input properties used: voyage.ports

  • Vertex
    The northern and southern latitudes that the vessel cannot go beyond.
    Input properties used: restrictions.northVertex, restrictions.southVertex

  • Weather Limits
    Limits can be set on numerous weather parameters. Specify in the request if the return route should avoid violating the weather limit or only report a warning.
    Input properties used: restrictions.weatherLimits

  • Depth
    Water depth along the route is checked and compared with the minimum required water depth as specified by the client in the request (vessel draft + required under keel clearance (UKC)). A route can be avoided or can generate warnings on the relevant waypoints based on the outcome of this comparison. It is advised to inspect a route that has warnings, paying extra attention to warnings with higher severity. Several types of depth values are used to determine a warning severity:

    DepthType Description WarningSeverity when depth < draft + UKC
    ManualDepth A manually set depth, overriding the charted depth.* avoided
    MinChartedDepth The minimum charted depth along the leg. Moderate
    MinSpotSounding The minimum spot sounding within a corridor (define corridor?) along the leg. Major
    LowestMaxDepth The lowest value among the maximum charted depths of the areas this leg crosses. Critical

    *ManualDepth is manually inserted by ChartWorld and intended to overwrite bathymetric data in cases where the underlying ENC depth area is missing or interrupted by a chart object that does not have bathymetric information, and where the resulting leg-line depth consequently defaults to zero. Examples:

    • Leg intersecting with ENC chart objects that have no bathymetry – such as a lock gate
    • Leg passing through an unsurveyed area on an ENC
    • In rare cases, manual depth is used to improve an existing depth area value, but only if otherwise the leg-line cannot be used at all.

    Final route check must be done onboard with the latest ENC materials and Temporary and Preliminary Notices to Mariners.
    Input properties used: vesselParameters.measurements.draft, vesselParameters.safetyMargins.underKeel(optional)

Carbon Intensity Indicator

The Carbon Intensity Indicator (CII) rating will be computed and shall be included as part of the response of Shortest Route, Instructed Speed, Recommended Speed, and Variable Speed endpoints. Below are the required CII rating calculation parameters for the route and total CII result to be included in the response.

  • Route
    The CII calculation result for the current route.
    Input properties used: vesselParameters.vesselType, vesselParameters.measurements.deadweight or vesselParameters.measurements.grossTonnage (depending on vessel type)

  • Total At Route End
    The total CII calculation result including the current route.
    Input properties used: vesselParameters.cii.yearToDateDistance, vesselParameters.cii.yearToDateCo2Emissions

tokens

Get a token

Get token for use in HTTP and websocket requests.

Request Body schema: application/json
audience
required
string

Resource URL intended for the token, provided by DTN

Value: "https://shipping.api.dtn.com"
client_id
required
string

Client ID as provided by DTN

client_secret
required
string

Client secret as provided by DTN

grant_type
required
string
Default: "client_credentials"

The type of token request

Responses

Response Schema: application/json
object

Request samples

Content type
application/json
{
  • "client_id": "string",
  • "client_secret": "string",
  • "audience": "https://shipping.api.dtn.com",
  • "grant_type": "client_credentials"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

ports

Lists all the ports.

Endpoint for listing all the available ports.

Authorizations:
(BearerDAIS)

Responses

Response Schema: application/json
Array
required
object (Point)

GeoJSON geometry

required
object

Additional properties for routing specific information about this GeoJSON object

type
required
string
Value: "Feature"

GeoJSON type

Response samples

Content type
application/json
[
  • {
    }
]

weather-limits

Lists all the weather limits.

Endpoint for listing all the available weather limits.

Authorizations:
(BearerDAIS)

Responses

Response Schema: application/json
Array
One of
allowMax
required
boolean
Default: false

Does this limit type admit a maximum value.

allowMin
required
boolean
Default: false

Does this limit type admit a minimum value.

description
required
string
Value: "Distance to hurricanes"
maxValue
required
number
Default: 999

The maximum accepted value for the limit.

minValue
required
number
Default: 200

The minimum accepted value for the limit.

name
required
string
Value: "HurricaneDistance"

The name of the weather limit.

unit
required
string
Value: "nautical miles (nm)"

The unit this weather limit is expressed in.

Response samples

Content type
application/json
[
  • {
    }
]

conditional-areas

Lists all the conditional areas.

Endpoint for listing all the available conditional areas. Conditional areas are specific predefined areas, where certain conditions apply. Examples are SECA zones, whale areas, etc.

Authorizations:
(BearerDAIS)

Responses

Response Schema: application/json
Array
required
object (Polygon)

GeoJSON geometry

required
object

Additional properties for routing specific information for this GeoJSON object.

type
required
string
Value: "Feature"

GeoJSON type

Response samples

Content type
application/json
[
  • {
    }
]

route-network-versions

Lists all the route network versions.

Endpoint for listing the available route network versions.

Authorizations:
(BearerDAIS)

Responses

Response Schema: application/json
Array
date
string <RFC 3339 (UTC)>

The date when the version of route network was processed.

version
string non-empty

The version of route network.

Response samples

Content type
application/json
[
  • {
    }
]

Route requests

Shortest path request

id
required
string

A client provided id for this request, this should be used for correlating a request to a response on the client side.

required
Array of objects (TemplatePathPoint) >= 2 items

The ordered fixed way points that must be included in the route (including departure and destination locations).

{
  • "points": [
    ],
  • "id": "string"
}

Shortest route request

etd
required
string <RFC 3339 (UTC)>

The estimated time of departure. Must not be more than 7 days in the past.

id
required
string

A client provided id for this request, this should be used for correlating a request to a response on the client side.

required
Array of objects (TemplateRoutePoint) >= 2 items

The ordered fixed way points that must be included in the route (including departure and destination locations).

speed
required
number <knots (kn)> ( 0 .. 50 ]

The speed to use when calculating the route.

required
object (VesselParameters)

Describes the vessel and its state.

object (RouteConfig)

Parameters that configure the behaviour of the API for this request.

object (Costs)

Describes monetary costs of operating the vessel, without reference to any currency. Costs must be present with at least one non-zero value for Cost optimization.

object (Restrictions)

The restrictions that should apply for this calculation.

object (Voyage)

Information about the voyage this route is for.

object (WeatherSourceInfo)
{
  • "points": [
    ],
  • "id": "string",
  • "voyage": {
    },
  • "etd": "2020-09-20T19:20:30.45Z",
  • "vesselParameters": {
    },
  • "config": null,
  • "costs": {
    },
  • "weatherSource": {
    },
  • "speed": 10,
  • "restrictions": {
    }
}

Instructed speed request

etd
required
string <RFC 3339 (UTC)>

The estimated time of departure. Must not be more than 7 days in the past.

id
required
string

A client provided id for this request, this should be used for correlating a request to a response on the client side.

required
string
required
Array of objects (TemplateRoutePoint) >= 2 items

The ordered fixed way points that must be included in the route (including departure and destination locations).

speed
required
number <knots (kn)> ( 0 .. 50 ]

The speed to use when calculating the route.

required
object (VesselParameters)

Describes the vessel and its state.

object (RouteConfig)

Parameters that configure the behaviour of the API for this request.

object (Costs)

Describes monetary costs of operating the vessel, without reference to any currency. Costs must be present with at least one non-zero value for Cost optimization.

object

The restrictions that should apply for this calculation.

object (Voyage)

Information about the voyage this route is for.

object (WeatherSourceInfo)
{
  • "points": [
    ],
  • "id": "string",
  • "voyage": {
    },
  • "etd": "2020-09-20T19:20:30.45Z",
  • "vesselParameters": {
    },
  • "config": null,
  • "costs": {
    },
  • "weatherSource": {
    },
  • "speed": 10,
  • "optimizationType": "Fuel",
  • "restrictions": {
    }
}

Recommended speed request

etd
required
string <RFC 3339 (UTC)>

The estimated time of departure. Must not be more than 7 days in the past.

id
required
string

A client provided id for this request, this should be used for correlating a request to a response on the client side.

required
string
required
Array of objects (TemplateRoutePoint) >= 2 items

The ordered fixed way points that must be included in the route (including departure and destination locations).

required
Array of objects (Speeds) non-empty unique

Set of speeds and/or speed ranges.

required
object (VesselParameters)

Describes the vessel and its state.

object (RouteConfig)

Parameters that configure the behaviour of the API for this request.

object (Costs)

Describes monetary costs of operating the vessel, without reference to any currency. Costs must be present with at least one non-zero value for Cost optimization.

object

The restrictions that should apply for this calculation.

object (Voyage)

Information about the voyage this route is for.

object (WeatherSourceInfo)
{
  • "points": [
    ],
  • "id": "string",
  • "voyage": {
    },
  • "etd": "2020-09-20T19:20:30.45Z",
  • "vesselParameters": {
    },
  • "config": null,
  • "costs": {
    },
  • "weatherSource": {
    },
  • "speeds": [
    ],
  • "optimizationType": "Fuel",
  • "restrictions": {
    }
}

Variable speed request

eta
required
string <RFC 3339 (UTC)>

The estimated time of arrival with a resolution of one minute.

etd
required
string <RFC 3339 (UTC)>

The estimated time of departure. Must not be more than 7 days in the past.

id
required
string

A client provided id for this request, this should be used for correlating a request to a response on the client side.

required
string
required
Array of objects (TemplateRoutePoint) >= 2 items

The ordered fixed way points that must be included in the route (including departure and destination locations).

required
Array of objects (SpeedRange) non-empty unique

Set of speeds and/or speed ranges. Requires at least one speed range

required
object (VesselParameters)

Describes the vessel and its state.

object (RouteConfig)

Parameters that configure the behaviour of the API for this request.

object (Costs)

Describes monetary costs of operating the vessel, without reference to any currency. Costs must be present with at least one non-zero value for Cost optimization.

object

The restrictions that should apply for this calculation.

object (Voyage)

Information about the voyage this route is for.

object (WeatherSourceInfo)
{
  • "points": [
    ],
  • "id": "string",
  • "voyage": {
    },
  • "etd": "2020-09-20T19:20:30.45Z",
  • "vesselParameters": {
    },
  • "config": null,
  • "costs": {
    },
  • "weatherSource": {
    },
  • "eta": "2020-09-21T16:30:00.00Z",
  • "optimizationType": "Fuel",
  • "speeds": [
    ],
  • "restrictions": {
    }
}

Route responses

Path response

One of
One of
apiVersion
required
string

Version of the API this response was generated from.

correlationId
required
string

Internal identifier of the request.

requestId
required
string

The client provided id of the request this is a response to. This should be used for correlating a request to a response on the client side.

Array of objects (CalculatedPath)

The resulting paths, currently is always size of one.

object (schemas-ShortestPathRequest)

The parameters for a shortest path calculation.

status
string
Value: "Success"

The calculation succeeded.

Array of objects (ProblemDetails)

The list of warnings.

Example
{
  • "correlationId": "string",
  • "apiVersion": "1.738",
  • "warnings": [
    ],
  • "status": "Success",
  • "requestId": "sp-12",
  • "request": {
    },
  • "paths": [
    ]
}

Route response

One of
One of
apiVersion
required
string

Version of the API this response was generated from.

correlationId
required
string

Internal identifier of the request.

requestId
required
string

The client provided id of the request this is a response to. This should be used for correlating a request to a response on the client side.

object (RouteRequest)
Array of objects (CalculatedRoute)

The resulting routes, currently is always size of one.

status
string
Value: "Success"

The calculation succeeded.

Array of objects (ProblemDetails)

The list of warnings.

Example
{
  • "correlationId": "string",
  • "apiVersion": "1.738",
  • "warnings": [
    ],
  • "status": "Success",
  • "requestId": "sp-12",
  • "request": {
    },
  • "routes": [
    ]
}

Vessel Models

About Vessel Models

DTN collaborated with MARIN (Maritime Research Institute Netherlands) to create vessel models for approximately 50 different vessel (sub) classes. These models include speed loss curves and wind and wave added resistance tables. DTN’s weather optimized routing algorithm uses these models to predict speed loss under the influence of wind and waves.

Additionally, clients can provide their own models included in the request (or in the future, separately uploaded to the Vessel Profiles API). When there is no vessel model in the request to the routing API, a default model is chosen based on the vessel type and measurements.

User defined vessel models are recommended in the following cases:

  • The vessel is not covered by the default models.

  • The main dimensions of the vessel design are more than 5% different from the default vessel models or the fuel consumption is significantly different.

  • Availability of more accurate information on the calm water resistance and/or wind & wave added resistance (e.g., from model tests or computational fluid dynamics simulations).

Resistance

Speed Loss

Throughout the models, a non-dimensional resistance is used. To explain this, it is helpful to first define some terms:

  • Vcalm and Rcalm are respectively the maximum speed (kns) and the accompanying resistance (kN) in calm water, at 100% Maximum Continuous Rating (MCR).

  • The Pull is the difference between effective thrust and resistance, it can be used to, e.g., tow another vessel or in our case, overcome adverse weather.

The speed loss function describes the vessel speed (Vs) at a given Pull. This can be made non-dimensional by dividing the Vs by Vcalm and Pull by Rcalm, giving a function from a non-dimensional Pull (Pull/Rcalm) to a speed fraction (V_actual over V_calm).

Wind and Wave Added Resistances

The wind resistance is computed as a function of wind speed and direction and is represented in the model as a 2D matrix of non-dimensional wind added resistance values (rows and columns indexed by wind speed in knots at 10m and relative wind direction at 10m).

The wave (sea and swell) resistances are obtained as a function of mean wave period, significant wave height, and direction and are represented as a 3D matrix of non-dimensional wave added resistance values.

The non-dimensional wind, sea-wave, and swell-wave resistances are added together and the resulting sum (non dimensional total added resistance) is used as the input to the speed loss function. This should be in equilibrium with the Pull/Rcalm. This equilibrium point can be found by linear interpolation within the speed loss function.

The result is the Vs/Vcalm ratio and the sustained speed (Vs) can be found by multiplying the Vs/Vcalm ratio with Vcalm.

Specifying Custom Vessel Models

To specify a custom vessel model, include a customModel object as part of the vesselParameters in a request. The exact format of the customModel object is specified in main request documentation, but is also reproduced here.

required
object (SpeedLossCurve)

The speed loss curve that provides the relation between total (Non Dimensional) added resistance from all weather conditions and speed fraction (V_actual / V_calm).

required
object (WavesResistance)

The waves resistance model that provides information about (Non Dimensional) added resistance from the sea and swell waves depending on their height, period and relative direction to the vessel's heading.

required
object (WindResistance)

The wind resistance model that provides information about (Non Dimensional) added resistance from the wind depending on its speed and relative direction (both taken at 10m height).

{
  • "wind": {
    },
  • "waves": {
    },
  • "speedLossCurve": {
    }
}

The customModel has three sub objects specifying the wind resistance, wave resistance, and speed loss functions. Each is composed of a domains object that describes the shape of the values matrix interpreted as the vessel model.domains is a set of domain objects each describing one dimension of the input to the model with a min, max and steps. The values in the wind and waves matrices are non-dimensional resistance values as described above, and the values in the speedLossCurve are fractions.

In the example below, the wind speed domain means that the resistance values in the matrix go from 0 knots to 50 knots with 6 evenly spaced values each 10 knots apart. Thus, there are six rows corresponding to resistance at wind speed 0, 10, 20, 30, 40, 50 knots. The relative direction goes from 0 to 180 in 5 steps of 45, so 0, 45, 90, 135, 180 corresponding to the five columns. The waves works similarly.

Example customModel object (note: the values are only illustrative and not realistic):


"customModel": {
  "wind": {
    "domains": {
      "speed":     {"min": 0, "max": 50, "steps": 6},
      "direction": {"min": 0, "max": 180, "steps": 5}
    },
    "values":  [
      [1, 0, 0, 0, 0],
      [2, 1, 0, 0, 0],
      [3, 2, 1, 0, 0],
      [4, 3, 2, 1, 0],
      [5, 4, 3, 2, 1],
      [6, 5, 4, 3, 2]
    ]
  },
  "waves": {
    "domains": {
      "height":    {"min": 0, "max": 10, "steps": 5},
      "direction": {"min": 0, "max": 180, "steps": 5},
      "period":    {"min": 0, "max": 10, "steps": 2}
    },
    "values":  [
      [[1, 10], [0, 0], [0, 0], [0, 0], [0, 0]],
      [[2, 20], [1, 10], [0, 0], [0, 0], [0, 0]],
      [[3, 30], [2, 20], [1, 10], [0, 0], [0, 0]],
      [[4, 40], [3, 30], [2, 20], [1, 10], [0, 0]],
      [[5, 50], [4, 40], [3, 30], [2, 20], [1, 10]],
      [[6, 60], [5, 50], [4, 40], [3, 30], [2, 20]]
    ]
  },
  "speedLossCurve": {
    "values":  [
      { "resistance": 1.3906, "speedFraction": 0 },
      { "resistance": 1.248, "speedFraction": 0.25 }, 
      { "resistance": 0.9265, "speedFraction": 0.5 }, 
      { "resistance": 0.5114, "speedFraction": 0.75 }, 
      { "resistance": -0.0009, "speedFraction": 1 }
    ]
  }
}