OKFFI Fluency Navigator MaaS API server
See Sujuvuusnavigaattori for further info.
If you're running into this error:
Retryable error: Error uploading script: Upload failed with non-zero exit status: 1
Then you're facing a known problem in mixing docker and packer, which exists as of June 2015, and is discussed in packer issue #1752.
This repository contains patched packer files that work fine with shell
provisioning scripts.
API server is used to collect, process and build reports on bicycle travel data.
API client applications can serve two purposes:
- contribute travel data to the server
- request reports to visualize travel situation
API clients specifically submit user's travel plans, traces, routes and may request and visualize reports.
Default format is JSON encoded as UTF-8.
Input data should be submitted with Content-type: application/json
header, in which case request
body must contain a JSON object.
In case Content-type: application/json
header is not present, all data should be submitted as
a JSON-encoded string in a payload
parameter.
Consider this plan object to be submitted:
var obj={
journey_id: 'abcdefghijklmnopqrstuvwxyz0123456789',
timestamp: (new Date()).toJSON(),
coordinates: [[0,0], [0,1], [1,1], [1,0]]
};
Standard approach:
$.ajax({
url: 'http://maas.okf.fi/plans',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(obj)
})
.done(...)
Conservative approach:
$.ajax({
url: 'http://maas.okf.fi/plans',
type: 'POST',
data: { payload:JSON.stringify(obj) }
})
.done(...)
The server supports CORS.
Successful responses with payload generate status code 200.
Empty responses generate status code 204.
Bad requests generate status code 400.
Server errors generate status code 500.
Requests are rejected entirely even if one of data elements is missing a mandatory field.
A client is expected to generate a UUID-like unique ID that is meant to identify a user actually following a travel plan and thus
performing a journey. This ID is called journey_id
and has to be provided in the API calls as per documentation below.
Please see the workflow description for working with journey_id
.
A typical workflow of client application is to:
- Generate
journey_id
as a sufficiently long (30+ characters) random string - Request an OTP plan
- Supply the plan and
journey_id
to the API server, obtaining theplanID
- Display speed report for a plan using
planID
- If user confirms the journey plan, start collecting traces/routes, otherwise go back to 2
- Submit traces/routes to the API server regularly
- If user reaches the destination, hits the stop button, cancels the journey or does not move for a significant amount of time (15+ minutes), go back to 1.
- If user requests a new plan on the way, go back to 2.
Another common type of workflow is to diplay speed situation using coordinates of a user's viewport as a boundaries
parameter.
Below is a list of currently implementes server endpoints.
URI | Description |
---|---|
GET /reports/speed-averages |
Obtain average speed report as a geoJSON FeatureCollection |
GET /plans/{planID} |
Obtain a previously saved plan as a geoJSON Feature |
POST /plans |
Save a plan |
POST /traces |
Save a trace or several traces |
POST /routes |
Save a route or several routes |
GET /demo.html |
Open a demo page (Content-type: text/html ) |
GET /wfs.xml? |
A very simple WFS-compatible interface to report data (Content-type: text/xml ) |
Plans are produced by Open Trip Planner based on Open Street Map and are used to spatially describe a travel intention of a user.
Plans are used to map traces onto existing map objects (streets etc.) to correct potentially inaccurate GPS data.
POST /plans
Parameters:
Name | Format | Mandatory | Notes |
---|---|---|---|
journey_id | string | yes | |
coordinates | array | yes | This must be a from->to array of 2 or more coordinates as in a geoJSON LINESTRING: longitude, latitude [, altitude] |
timestamp | string | yes | This should be in ISO8601 format with time zone (see toJSON() method). Submitting time in UTC time zone is strongly recommended |
Such request will return a unique plan id that can be used to retrieve plan details later via the following request:
GET /plans/{planID}
or to obtain a report on average speeds (see below).
Routes are segments (lines) in a travel plan that the traveller has just completed. A route is a just a single line with an average speed (in m/s) calculated for that line.
Routes form a dataset for average speeds report.
POST /routes
supports both single-object and array-of-objects formats.
Parameters:
Name | Format | Mandatory | Notes |
---|---|---|---|
journey_id | string | yes | |
timestamp | string | yes | This should be in ISO8601 format with time zone (see toJSON() method). Submitting time in UTC time zone is strongly recommended. |
coordinates | array | yes | This must be a from->to array of exactly 2 coordinates as in a geoJSON LINESTRING: longitude, latitude [, altitude] |
speed | float | yes | Average speed along the route. |
mode | string | yes | OTP plan mode |
Traces are momentary snapshots of data about a moving bicycle rider as collected from a mobile client. Each trace contains a single set of spatial coordinates.
Traces form a very basic dataset about actual bicycle travel.
POST /traces
supports both single-object and array-of-objects formats.
Parameters:
Name | Format | Mandatory | Notes |
---|---|---|---|
journey_id | string | yes | |
timestamp | string | yes | This should be in ISO8601 format with time zone (see toJSON() method). Submitting time in UTC time zone is strongly recommended. |
latitude | float | yes | Geographical latitude of a user |
longitude | float | yes | Geographical longitude of a user |
altitude | float | no | Geographical altitude of a user |
Reports generate aggregated data about average bicycle speeds in various spatial areas.
Data returned is a FeatureCollection
from geoJSON specification.
Each feature has a geometry
attribute, containing a linestring, and a speed
custom property that contains an array of average speed
values in meter/second, matching al of the segments in that linestring.
GET /reports/speed-averages
Parameters:
Name | Format | Mandatory | Notes |
---|---|---|---|
planID | integer | no | Obtained in a separate POST call (see above) |
boundary_sw_lon | float | no | Longitude of the south-western boundary (all four must be present) |
boundary_sw_lat | float | no | Latitude of the south-western boundary |
boundary_ne_lon | float | no | Longitude of the north-eastern boundary |
boundary_ne_lat | float | no | Latitude of the north-eastern boundary |
after | string | no | This should be in ISO8601 format with time zone (see toJSON() method). Submitting time in UTC time zone is strongly recommended. |
before | string | no | Same as above |
type | string | no | can be either baseline , realtime or combined (default: combined ) |
There are optional parameters that provide for limiting aggregation and averages based on space and/or time.
Specifically, boundaries
is used to specify spatial limit; before
and after
are timestamps to limit selection
(moments of time indicated by either of the timestamps are excluded from selection).
If a planID
is provided, the report will only cover areas that are part of the specified plan.
Baseline reports are based on carefully processed data, realtime reports are based on community data.
Fluency related data is stored in the following db tables (PostgreSQL/PotGIS data types):
trace
table:
Name | Type | notnull | PK | Notes |
---|---|---|---|---|
trace_id | BIGSERIAL | true | true | |
journey_id | TEXT | true | ||
timestamp | TIMESTAMP | true | ||
geometry | geometry | true | POINT |
plan
table:
Name | Type | notnull | PK | notes |
---|---|---|---|---|
plan_id | BIGSERIAL | true | true | |
journey_id | TEXT | true | ||
timestamp | TIMESTAMP | true | WITH TIME ZONE | |
geometry | geometry | true | LINESTRING |
route
table:
Name | Type | notnull | PK | Notes |
---|---|---|---|---|
route_id | BIGSERIAL | true | true | |
journey_id | TEXT | true | ||
timestamp | TIMESTAMP | true | WITH TIMEZONE | |
geometry | geometry | true | LINESTRING, simple, two points | |
speed | DECIMAL(21,16) | true | ||
mode | TEXT | true | obtained from an OTP plan | |
realtime | BOOLEAN | false | default: true |
report
table (used as a cache for quicker delivery of report data):
Name | Type | notnull | PK | Notes |
---|---|---|---|---|
report_id | BIGSERIAL | true | true | |
timestamp | TIMESTAMP | true | WITH TIMEZONE, contains report generation time | |
geometry | geometry | true | LINESTRING | |
speed | DECIMAL(21,16) | true | average speed per linestring, defaults to 0 | |
reading | DECIMAL(21,16) | true | average number of readings per linestring, defaults to 0 | |
type | TEXT | true | either 'realtime', 'baseline' or 'combined' |
Maas-docker is a utility that facilitates deployment and running of MaaS API Server via Docker container with the use of Packer.
Packer is a utility to streamline creation and deployment of virtual machine images.
Docker is a flavor of machine virtualization tools with neat features.
maas-docker.sh
script allows you to:
- create Docker image from official ubuntu:latest and build MaaS API Server environment inside it
- run MaaS API API Server as a docker container
- view running Docker containers
- stop a running Docker container
The script is also capable of updating the base operating system.
Run script to see the usage help.