Closed hunterowens closed 4 years ago
Hi all! I’ve been doing some exploratory work on how to best represent docked
bike sharing vehicles in MDS, and would like to propose a new Stop
data-type in MDS. I considered calling these Docks
instead, however as I started to play around with crafting the type, I realized that making this generic could allow it to easily be applicable to future modes of transportation in MDS.
Stops
are heavily inspired by GBFS/GTFS, and should serve as a strict superset of them. This could potentially enable data consumed by a City Services interface or polled from a Provider Services interface, for example, to be served back out as GBFS/GTFS/GTFS-RT feeds, though I personally think this is out of scope for 0.4.1. The primary addition you’ll notice with the Stop
data-type, is that they can optionally piggyback off of the Geography
data-type that is used by the Policy API. Using GeoJSON FeatureCollections to represent items that are taking up potentially substantial space in the public right of way is much more accurate than a simple latitude and longitude. However, because latitude & longitude are also required, we’ll be supporting backwards compatibility with GBFS/GTFS.
Stop Registration Body:
Field | R/O | Type | Description |
---|---|---|---|
stop_id | R | UUID | Unique ID for stop |
stop_name | R | String | Name of stop |
lat | R | Double | Latitude of the location |
lng | R | Double | Longitude of the location |
capacity | R | {vehicle_type: number} | Number of total spots per vehicle_type |
geography_id | O | UUID | Pointer to the Geography that represents the Stop geospatially |
short_name | O | String | Abbreviated stop name |
platform_code | O | String | |
zone_id | O | UUID | |
address | O | String | Postal address (useful for directions) |
post_code | O | String | |
rental_methods | O | String[] (Enum?) | Payment methods accepted at stop |
location_type | O | String (Enum?) | |
level | O | String | Floor designation for this stop (e.g.1st, 2nd, Roof) |
timezone | O | String | Timezone stop is located in |
cross_street | O | String | |
wheelchair_boarding | O | Boolean | Is this stop handicap accessible? |
parent_stop | O | UUID | Describe a basic hierarchy of stops (e.g.a stop inside of a greater stop) |
Update Body:
Field | R/O | Type | Description |
---|---|---|---|
stop_id | R | UUID | Unique ID for stop |
num_spots_available | O | {vehicle_type: number} | How many spots are free to be populated with vehicles at this stop? |
num_spots_disabled | O | {vehicle_type: number} | How many docks are disabled and unable to accept vehicles at this stop? |
Fetch Body: (additional properties exposed by a City Services or Provider Services interface)
Field | R/O | Type | Description |
---|---|---|---|
stop_id | R | UUID | Unique ID for stop |
stop_name | R | String | Name of stop |
lat | R | Double | Latitude of the location |
lng | R | Double | Longitude of the location |
capacity | R | {vehicle_type: number} | Number of total spots per vehicle_type |
num_vehicles_available | R | {vehicle_type: number} | How many vehicles are available per vehicle_type at this stop? |
num_vehicles_disabled | R | {vehicle_type: number} | How many vehicles are unavailable/reserved per vehicle_type at this stop? |
geography_id | O | UUID | Pointer to the Geography that represents the Stop geospatially |
short_name | O | String | Abbreviated stop name |
platform_code | O | String | |
zone_id | O | UUID | |
address | O | String | Postal address (useful for directions) |
post_code | O | String | |
rental_methods | O | String[] (Enum?) | Payment methods accepted at stop |
location_type | O | String (Enum?) | |
level | O | String | Floor designation for this stop (e.g.1st, 2nd, Roof) |
timezone | O | String | Timezone stop is located in |
cross_street | O | String | |
num_spots_available | O | {vehicle_type: number} | How many spots are free to be populated with vehicles at this stop? |
num_spots_disabled | O | {vehicle_type: number} | How many docks are disabled and unable to accept vehicles at this stop? |
wheelchair_boarding | O | Boolean | Is this stop handicap accessible? |
parent_stop | O | UUID | Describe a basic hierarchy of stops (e.g.a stop inside of a greater stop) |
Additionally, I propose a modification in the data required at event-ingest time for docked vehicles. For trip_start
, trip_end
, and provider_drop_off
events, we will require a stop_id
property to be included in the event payload to indicate which stop the docked vehicle is arriving/leaving. As you can see in the typing snippet above, there will be additional properties which are included when GETing a stop. These values will either be computed at event-ingest time by a City Services interface with the new event requirements, or should be served by a Provider Services interface.
@avatarneil I absolutely support the approach of generalizing docks to stops, I have been thinking about similar things as well. One issue I see with representing stops is how it seems more natural not to represent changes to their state as an event stream (perhaps more due to their history in GBFS than anything).
This is particularly relevant when thinking about stops in an analysis context, where we would want to have an accurate history of the stop. The data model you propose works for representing stops in real-time, but how should we think about it in a historical setting? I see two approaches: representing changes as a set of events, similar to how we deal with changes to scooters, or keeping track of the time range over which each state is held.
Then, when making requests for a stop's state, a time range is necessary, and responses would include all states intersecting with the time range provided.
Generalizing docks to stops brings up the question of how hybrid systems should be represented. Are they considered docked or dockless (which determines if stops are optional or required)? Should a virtual station be considered a stop?
I also wonder if other pieces of infrastructure such as battery swap stations should be included in MDS. There's a wide variety of potential infrastructure pieces possible in the micromobility world, but it feels a bit early to try to account for all of it in MDS.
I think at the very least, MDS should provide definitions of docked and dockless systems. Maybe a straw man to start with is "In a docked system, trips must start and end at docks that physically lock the vehicle; anything that doesn't fit this description is a dockless system".
This will be resolved with #427.
We have a working solution with #427 for release 1.0.0, marked as beta.
Is your feature request related to a problem? Please describe.
I'd love to see the ability to support docked bike share systems in MDS, with the appropriate changes to reflect the lack of GPS / the introduction of docks in the system. For example, trips/ route info is probably impossible to get.
Prior art:
LA metrobike historical trips Motivate Bay Wheels System Data BikeshareMap Statistical Models around bikeshare data / Divvy
Describe the solution you'd like
MDS, but for docked bikeshare systems.
Is this a breaking change
A breaking change would require consumers or implementors of the API to modify their code for it to continue to function (ex: renaming of a required field or the change in data type of an existing field). A non-breaking change would allow existing code to continue to function (ex: addition of an optional field or the creation of a new optional endpoint).
Provider
oragency
For which API is this feature being requested:
provider
Describe alternatives you've considered
Continue to get CSV dumps in different formats across different operators.
Additional context
Add any other context or screenshots about the feature request here.