This creates a feature collection from the bikes endpoint of a GBFS service, such as JUMP DC's feed: https://dc.jumpmobility.com/opendata/free_bike_status.json
{type: `FeatureCollection`, features: data.bikes[*].{id: bike_id, geometry: {type: `Point`, coordinates: [lon, lat]}, properties: @}}
GBFS Input:
{
"last_updated": 1518889202,
"ttl": 60,
"data": {
"bikes": [
{
"bike_id": "bike_17237",
"name": "JUMP DC-0239",
"lon": -76.9832,
"lat": 38.946725,
"is_reserved": 0,
"is_disabled": 0,
"jump_ebike_battery_level": "52%"
}
]
}
}
GeoJSON output:
{
"type": "FeatureCollection",
"features": [
{
"id": "bike_17237",
"geometry": {
"type": "Point",
"coordinates": [
-76.9832,
38.946725
]
},
"properties": {
"bike_id": "bike_17237",
"name": "JUMP DC-0239",
"lon": -76.9832,
"lat": 38.946725,
"is_reserved": 0,
"is_disabled": 0,
"jump_ebike_battery_level": "52%"
}
}
]
}
This creates a feature collection from the bikes endpoint of a GBFS service, such as CaBi's feed: https://gbfs.capitalbikeshare.com/gbfs/en/station_information.json
{type: `FeatureCollection`, features: data.stations[*].{id: station_id, geometry: {type: `Point`, coordinates: [lon, lat]}, properties: @}}
This isn't very useful with out Station status since this doesn't contain info about number of bikes.
GBFS input:
{
"last_updated": 1518889367,
"ttl": 10,
"data": {
"stations": [
{
"station_id": "1",
"name": "Eads St & 15th St S",
"short_name": "31000",
"lat": 38.858971,
"lon": -77.05323,
"region_id": 41,
"rental_methods": [
"KEY",
"CREDITCARD"
],
"capacity": 15,
"rental_url": "http://app.capitalbikeshare.com/vIiR/zVsfTIsOTF?station_id=1",
"eightd_has_key_dispenser": false
}
]
}
}
GeoJSON output:
{
"type": "FeatureCollection",
"features": [
{
"id": "1",
"geometry": {
"type": "Point",
"coordinates": [
-77.05323,
38.858971
]
},
"properties": {
"station_id": "1",
"name": "Eads St & 15th St S",
"short_name": "31000",
"lat": 38.858971,
"lon": -77.05323,
"region_id": 41,
"rental_methods": [
"KEY",
"CREDITCARD"
],
"capacity": 15,
"rental_url": "http://app.capitalbikeshare.com/vIiR/zVsfTIsOTF?station_id=1",
"eightd_has_key_dispenser": false
}
}
]
}
This creates a feature collection from the bikes endpoint of a GBFS service, such as CaBi's feed: https://gbfs.capitalbikeshare.com/gbfs/en/station_status.json
{type: `FeatureCollection`, features: data.stations[*].{id: station_id, properties: @}}
This isn't very useful with out Station information since this doesn't contain the location of the station.
GBFS input:
{
"last_updated": 1518889523,
"ttl": 10,
"data": {
"stations": [
{
"station_id": "1",
"num_bikes_available": 5,
"num_bikes_disabled": 0,
"num_docks_available": 10,
"num_docks_disabled": 0,
"is_installed": 1,
"is_renting": 1,
"is_returning": 1,
"last_reported": 1518885345,
"eightd_has_available_keys": false
}
]
}
}
GeoJSON output:
{
"type": "FeatureCollection",
"features": [
{
"id": "1",
"properties": {
"station_id": "1",
"num_bikes_available": 5,
"num_bikes_disabled": 0,
"num_docks_available": 10,
"num_docks_disabled": 0,
"is_installed": 1,
"is_renting": 1,
"is_returning": 1,
"last_reported": 1518885345,
"eightd_has_available_keys": false
}
}
]
}
Promise.all([fetch('https://gbfs.capitalbikeshare.com/gbfs/en/station_information.json', {cors: true}),
fetch('https://gbfs.capitalbikeshare.com/gbfs/en/station_status.json', {cors: true})])
.then(resps => Promise.all(resps.map(resp => resp.json())))
.then(([info, stat]) => [
jmespath.search(info, '{type: `FeatureCollection`, features: data.stations[*].{id: station_id, geometry: {type: `Point`, coordinates: [lon, lat]}, properties: @}}'),
jmespath.search(stat, '{type: `FeatureCollection`, features: data.stations[*].{id: station_id, properties: @}}')])
.then(([infoGeoJSON, statGeoJSON]) => {
const statMap = new Map(statGeoJSON.features.map(({id, properties}) => [id, properties]));
infoGeoJSON.features = infoGeoJSON.features.map(({id, geometry, properties}) => ({
id,
geometry,
properties: Object.assign({}, properties, statMap.get(id)),
}));
return infoGeoJSON;
})