Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Geofencing, virtual station, and dockless support #175

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 111 additions & 22 deletions gbfs.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# General Bikeshare Feed Specification (GBFS)
This document explains the types of files and data that comprise the General Bikeshare Feed Specification (GBFS) and defines the fields used in all of those files.

This branch and associated pull request is to discuss (a proposal)[https://docs.google.com/document/d/1po4tlv5p7jXB6KQYohLAIS0qKJfxI1e-EH3JjiyUWoc/edit] to add support for dockless, geofencing, and virtual stations.

## Table of Contents

* [Revision History](#revision-history)
Expand All @@ -18,6 +20,7 @@ This document explains the types of files and data that comprise the General Bik
* [system_regions.json](#system_regionsjson)
* [system_pricing_plans.json](#system_pricing_plansjson)
* [system_alerts.json](#system_alertsjson)
* [geofencing_zones.json](#geofencing_zonesjson)
* [Possible Future Enhancements](#possible-future-enhancements)

## Revision History
Expand Down Expand Up @@ -62,6 +65,7 @@ system_calendar.json | Optional | Describes the days of op
system_regions.json | Optional | Describes the regions the system is broken up into
system_pricing_plans.json | Optional | Describes the system pricing
system_alerts.json | Optional | Describes current system alerts
geofencing_zones.json | Optional | Geofenced zones and their associated rules and attributes.

## File Requirements
* All files should be valid JSON
Expand Down Expand Up @@ -227,20 +231,25 @@ license_url | Optional | A fully qualified URL of a page that defines the
### station_information.json
All stations contained in this list are considered public (ie, can be shown on a map for public use). If there are private stations (such as Capital Bikeshare’s White House station) these should not be exposed here and their status should not be included in station_status.json.

Field Name | Required | Defines
------------------| --------- | ----------
stations | Yes | Array that contains one object per station in the system as defined below
\- station_id | Yes | Unique identifier of a station. See [Field Definitions](#field-definitions) above for ID field requirements
\- name | Yes | Public name of the station
\- short_name | No | Short name or other type of identifier, as used by the data publisher
\- lat | Yes | The latitude of station. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- lon | Yes | The longitude of station. The field value must be a valid WGS 84 longitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- address | Optional | Valid street number and name where station is located. This field is intended to be an actual address, not a free form text description (see "cross_street" below)
\- cross_street | Optional | Cross street of where the station is located. This field is intended to be a descriptive field for human consumption. In cities, this would be a cross street, but could also be a description of a location in a park, etc.
\- region_id | Optional | ID of the region where station is located (see [system_regions.json](#system_regionsjson))
\- post_code | Optional | Postal code where station is located
\- rental_methods | Optional | Array of enumerables containing the payment methods accepted at this station. <br />Current valid values (in CAPS) are:<br /><ul><li>KEY _(i.e. operator issued bike key / fob / card)_</li> <li>CREDITCARD</li> <li>PAYPASS</li> <li>APPLEPAY</li> <li>ANDROIDPAY</li> <li>TRANSITCARD</li> <li>ACCOUNTNUMBER</li> <li>PHONE</li> </ul> This list is intended to be as comprehensive at the time of publication as possible but is subject to change, as defined in [File Requirements](#file-requirements) above
\- capacity | Optional | Number of total docking points installed at this station, both available and unavailable
Field Name | Required | Defines
---------------------- | --------- | ----------
stations | Yes | Array that contains one object per station in the system as defined below
\- station_id | Yes | Unique identifier of a station. See [Field Definitions](#field-definitions) above for ID field requirements
\- name | Yes | Public name of the station
\- short_name | No | Short name or other type of identifier, as used by the data publisher
\- lat | Conditionally required | The latitude of station. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees. Required if `station_area` is not defined.
\- lon | Conditionally required | The longitude of station. The field value must be a valid WGS 84 longitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees. Required if `station_area` is not defined.
\- address | Optional | Valid street number and name where station is located. This field is intended to be an actual address, not a free form text description (see "cross_street" below)
\- cross_street | Optional | Cross street of where the station is located. This field is intended to be a descriptive field for human consumption. In cities, this would be a cross street, but could also be a description of a location in a park, etc.
\- region_id | Optional | ID of the region where station is located (see [system_regions.json](#system_regionsjson))
\- post_code | Optional | Postal code where station is located
\- rental_methods | Optional | Array of enumerables containing the payment methods accepted at this station. <br />Current valid values (in CAPS) are:<br /><ul><li>KEY _(i.e. operator issued bike key / fob / card)_</li> <li>CREDITCARD</li> <li>PAYPASS</li> <li>APPLEPAY</li> <li>ANDROIDPAY</li> <li>TRANSITCARD</li> <li>ACCOUNTNUMBER</li> <li>PHONE</li> </ul> This list is intended to be as comprehensive at the time of publication as possible but is subject to change, as defined in [File Requirements](#file-requirements) above
\- capacity | Optional | Number of total docking points installed at this station, both available and unavailable
\- is_virtual_station | Optional | 1/0 Boolean- Is this a virtual station? <br /> <ul><li>1 - The station is a location without physical infrastructure, defined by a point (lat/lon) and/or station_area (below).</li> <li>0 - The station consists of physical infrastructure (docks).</li> </ul>
\- station_area | Conditionally required | A GeoJSON multipolygon that describes the area of a virtual station. If station_area is supplied then the record describes a virtual station. If lat/lon and 'station_area' are both defined, the lat/lon is the significant coordinate of the station (e.g. dock facility or valet drop-off and pick up point). Required if `lat` and `lon` are not provided.
\- capacity | Optional | Number of total docking points installed at this station, both available and unavailable. Empty indicates unlimited capacity.
\- vehicle_capacity | Optional | _*"vehicle_capacity" depends on passage of the [vehicle_types proposal](https://github.com/NABSA/gbfs/pull/136)._ An object where each key is a vehicle_type_id as described in vehicle_types.json, and the value is a number representing the total number of vehicles of this type that can park within the area defined in the station_area field. If the field station_area is defined, and a particular vehicle type id is not defined in this object, then that vehicle type has unlimited capacity.
\- valet | Optional | 1/0 Boolean- Are there valet services at this station? <br /> <ul><li>1 - Valet services.</li> <li>0 - No valet services [default].</li> </ul>

### station_status.json

Expand All @@ -260,14 +269,15 @@ stations | Yes | Array that contains one object per station i
### free_bike_status.json
Describes bikes that are not at a station and are not currently in the middle of an active ride.

Field Name | Required | Defines
------------------| ----------| ----------
bikes | Yes | Array that contains one object per bike that is currently docked/stopped outside of the system as defined below
\- bike_id | Yes | Unique identifier of a bike
\- lat | Yes | Latitude of the bike. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- lon | Yes | Longitude of the bike. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- is_reserved | Yes | 1/0 value - is the bike currently reserved for someone else
\- is_disabled | Yes | 1/0 value - is the bike currently disabled (broken)
Field Name | Required | Defines
------------------| ------------------------ | ----------
bikes | Yes | Array that contains one object per bike that is currently docked/stopped outside of the system as defined below
\- bike_id | Yes | Unique identifier of a bike
\- lat | Yes | Latitude of the bike. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- lon | Yes | Longitude of the bike. The field value must be a valid WGS 84 latitude in decimal degrees format. See: http://en.wikipedia.org/wiki/World_Geodetic_System, https://en.wikipedia.org/wiki/Decimal_degrees
\- is_reserved | Yes | 1/0 value - is the bike currently reserved for someone else
\- is_disabled | Yes | 1/0 value - is the bike currently disabled (broken)
\- system_id | Conditionally required | ID- Refers to the system_id field in system_information.json. Required in the case of feeds that specify free (undocked) bikes and define systems in system_information.json.

### system_hours.json
Describes the system hours of operation. A JSON array of hours defined as follows:
Expand Down Expand Up @@ -368,6 +378,85 @@ alerts | Yes | Array - alert objects each indicating a separa
\- description | Optional | String - Detailed text description of the alert
\- last_updated | Optional | Integer POSIX timestamp indicating the last time the info for the particular alert was updated

### geofencing_zones.json
This file is optional. All fields indicated as “Required” are only required if geofencing_zones.json is supplied.

Field Name | Required | Defines
----------------------------------- | ------------| ----------
geofencing_zones{} | Yes | A GeoJSON FeatureCollection (as described by the IETF [RFC 7946](https://tools.ietf.org/html/rfc7946#section-3.3)). Each geofenced zone and its associated rules and attributes is described as an object within the array of features, as follows.
\- type | Yes | String- “Feature” (as per IETF [RFC 7946](https://tools.ietf.org/html/rfc7946#section-3.3)).
\- geometry | Yes | A GeoJSON Multipolygon that describes where rides might not be able to start, end, go through, or have other limitations. A clockwise arrangement of points defines the area enclosed by the polygon, while a counterclockwise order defines the area outside the polygon [(right-hand rule)](https://tools.ietf.org/html/rfc7946#section-3.1.6). All geofencing zones contained in this list are public.
\- properties{} | Yes | As defined below, describes travel allowances and limitations.
&emsp;- name | Optional | String- Name of the geofencing zone.
&emsp;- rules[] | Optional | Array that contains one object per rule as defined below. In the event of overlapping or colliding rule, the earlier defined rule (in order of the JSON file) takes precedence.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this should be an object of the rules. I don't see a use case for a single Multipolygon having an array of rules. There can be instances where the rules from Features that have overlapping geometry would be in conflict, so it might be good to note that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One type of rule not currently represented in this PR (but mentioned in the discussion and used at Bird) is a speed-limited zone. Perhaps we should add a max_speed field, with integer value. We should decide what units we want to use (mi/hr, km/hr, something else).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wellorder I think the intention was to only cover rules related to parking in these zones and leave other types of rules/regulations as a responsibility of the MDS spec.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@contra Whoa, I don't agree with this at all. GBFS should include everything that consumer-facing application can use and max_speed is certainly part of it : it impacts trip planning and is certainly interesting for the user to know in a UI. I though the speed was discarded because there were no implementer for it, but seems @wellorder is one of them now.

I agree regulation/rules that aren't user facing at all can be left to MDS (like vehicle caps).

&emsp;&emsp;- vehicle_type_id | Optional | Array of IDs of vehicle types for which any restrictions should be applied (see vehicle type definitions in [PR #136](https://github.com/NABSA/gbfs/pull/136)). If vehicle_type_ids are not specified, then restrictions apply to all vehicle types.
&emsp;&emsp;- ride_start_allowed | Yes | 1/0 Boolean- Is a ride allowed to start in this zone? <br /> <ul><li>1 - Undocked (“free bike”) ride can start in this zone.</li> <li>0 - Undocked (“free bike”) ride cannot start in this zone.</li> </ul>
&emsp;&emsp;- ride_end_allowed | Yes | 1/0 Boolean- Is a ride allowed to end in this zone? <br /> <ul><li>1 - Undocked (“free bike”) drop-offs are allowed in this zone.</li> <li>0 - Undocked (“free bike”) drop-offs are not allowed in this zone.</li> </ul>
&emsp;&emsp;- ride_through_allowed | Yes | 1/0 Boolean- Is a ride allowed to travel through this zone? <br /> <ul><li>1 - Ride can travel through this zone.</li> <li>0 - Ride cannot travel through this zone.</li></ul>

Example:
```json
{
"last_updated":1434054678,
"ttl":0,
"version":"2.X",
"data":{
"geofencing_zones":{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"properties":{
"name":"Downtown Waterfront",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend three optional additional keys next to name here:

  • start_date: string (ISO 8601) | Date and time of the start of the geo-fencing zone
  • end_date: string (ISO 8601) | Date and time of the end of the geo-fencing zone
  • description: string | Description about the geo-fencing zone

These could be used to display temporary no-park zones for which cities place, for example for Christmas markets or street construction sites.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Empty2k12: If start_date and end_date were included would you or another application developer commit to implementing that in software?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we would love to implement start_date for our unofficial GBFS feeds we're providing.

We'd also like to support start_date and end_date for the GBFS explorer application we're actively developing. For that we'd implement these changes into our GraphQL wrapper for GBFS (GbfsQL) and incorporate displaying that into the viewer frontend.

"rules":[
{
"vehicle_type_id":"scooter",
"ride_start_allowed":0,
"ride_end_allowed":0,
"ride_through_allowed":0
}
]
},
"geometry":{
"type":"MultiPolygon",
"coordinates":[
[
[
[
-122.66780376434326,
45.49896266763551
],
[
-122.66810417175292,
45.49824825558575
],
[
-122.66830801963805,
45.49632305799116
],
[
-122.66762137413023,
45.49625537406554
],
[
-122.66721367835997,
45.49924842991741
],
[
-122.66780376434326,
45.49896266763551
]
]
]
]
}
}
]
}
}
}
```

## Possible Future Enhancements
There are some items that were proposed in an earlier version of this document but which do not fit into the current specification. They are collected here for reference and for possible discussion and inclusion in this or a future version.

Expand Down