Crafting bespoke maps of bike-share service areas

Noah G
Coord
Published in
6 min readJun 21, 2018

Earlier this year, we released our Bike-Share API, allowing developers to search for available bikes over 65 bike systems in over 80 cities. While data about bike locations is broadly available in GBFS, bike-share systems are so much more than just their bikes — there’s pricing, plans, accounts, service areas, and more. Our goal at Coord is to make all of these data accessible and understandable, and enable new uses for these services.

Where can I go?

Dockless bikes

Planning a trip with a dockless system is easy — find the nearest bike and ride it to your destination. Or is it that easy? Dockless systems aren’t (yet) everywhere, and cities and system operators both set limits on where you are allowed to operate a dockless bike. We call the region where you can use a given company’s bike a “service area”. Some systems don’t allow bikes to be left outside this area at all, while others simply charge a high fee for the privilege. So how do you find out what that area is?

Sometimes, we can get this data directly — providers or partners have their own API endpoints that return service areas. While we still need to do some work to merge disconnected areas and associate areas with systems, this is by far the best method — not only for us, but for cities, too. Chicago is one of the latest US cities to try a dockless pilot, and is requiring vendors to publish data adhering to the GBFS v1.1 (draft) spec. This draft spec adds new data endpoints that provide information about service areas (“geofencing zones”), including their exact geometry! Making this data available programmatically is beneficial for users, developers, cities, and regulators — users want to know they’re leaving bikes in the right places, and cities want to keep their streets and sidewalks (and canals and rivers) open for all users.

More often, the data is visible but not machine-readable, and sometimes it’s not visible at all. Often, the only publicly available service area data is a map on a provider’s website, or even just a list of areas in a permit or regulation. In these cases, we manually reconstruct the maps from whatever sources are available. This involves a lot of dropping points on a map, and joining those points into a contiguous polygon.

Docked bikes

Docked systems are easier to think about than dockless; after all, you can only get and return bikes via docks, so no need for a service area, right? While knowing about docks is useful for taking a single trip, knowing what area a system covers can make it easier for developers to find the nearest system, and whether taking a bike is the right choice for a trip.

A reasonable definition for a docked-bike system service area is all area encompassed by the outermost bike stations, plus some buffer outside of that. While we could do all the data processing manually, since we’re working on geographic data, we can rely on powerful tools built specifically for manipulating geospatial data, such as PostGIS.

First, we query our Bike-Share API to find all bike locations:

curl -G "https://api.coord.co/v1/bike/location?latitude=38.907241&longitude=-77.036521&radius_km=10&access_key=<our_api_key>"

We get back a GeoJSON FeatureCollection of all bike locations within the search area, including docks and free bikes:

{
“type”: “FeatureCollection”,
“features”: [
{
“type”: “Feature”,
“id”: “CapitalBikeShare-91”,
“geometry”: {
“coordinates”: [-77.029822, 38.900283],
“type”: “Point”
},
“properties”: {
“location_id”: “91”,
“location_type”: “bike_station_dock”,
“region_id”: “42”,
“system_id”: “CapitalBikeShare”
...
}
},
...
]
}

First, we filter out anything that doesn’t have a location_type of bike_station_dock, and group the locations by system_id and region_id. Then, we put all of those station locations into a PostgreSQL database, where we can easily run queries and add processing steps.

Next, we plot each of the stations on the map and build a circular buffer around each of the stations, merging overlapping buffers together:

Each dock location, with a 500m circular area around it.

The resulting polygons define the direct service area of the bike system — namely, where are you no more than a 5 minute walk from a bike? — but this ignores the fact that once on a bike, you can bike to any other dock. To make a more useful map, we construct a more general area covering all of the buffered points, and the area within and between those points as well. This is known as a hull, and we can generate these using PostGIS as well.

The Capital Bikeshare service area, with a convex hull around all points.

We can further slice the data, for example to split systems by region and construct the areas from those groups. This lets us generates areas for systems like Capital Bikeshare that don’t have a single contiguous coverage area, but instead cover multiple locations in different jurisdictions. This avoids incorrectly showing areas as covered where bikes may actually be miles away in either direction — something we call a “dock desert”.

The Capital Bikeshare service area, split by region ID, with a convex hull.

We have a choice of creating convex or concave hulls. Convex hulls look cleaner, but often end up covering large areas of dock desert. Concave hulls can look worse with sparse geometry, but often more accurately fit the area.

The Madison BCycle service area as a convex hull. Notice how much area is covered that isn’t even close to a station!
The Madison BCycle service area as a concave hull. Now, only areas close to and between stations are covered.

For systems where a few stations are far removed from the majority, we segment those stations into a separate region (and therefore a separate polygon) to ensure the resulting service area doesn’t include huge swaths of dock deserts. Adjusting the radius of the buffer is also key; we start with 500m — roughly a five-minute walk — and tweak as needed to make a shape that covers key areas without overextending. The more geographically-minded among you may wonder how we project that radius evenly across latitudes, and compensate for other quirks of geospatial systems. Well…

Aside: Projection Systems

We’ve talked about geospatial coordinates and projections before (link), and why we use a projection system known as Web Mercator. In our Web Mercator coordinate system, a single unit in projection space is equal to one meter at the Equator, but shrinks the farther away you get. The southernmost point in the US (in Hawaii) at around 18N has a scale factor of 1.05, the top of the continental US is at 49N with a scale factor of 1.5, while one of the northernmost cities (Fairbanks, Alaska) at around 65N has a scale factor of 2.37! This isn’t just a fun fact for trivia nights either; there are bike-share systems in all of these places.

This scale factor means our circular buffers are actually smaller than we specify, which means smaller usable areas. Luckily, the people behind PostGIS have realized this obvious pitfall, and have a data type of geography, which models the Earth as a spheroid, and handles these issues for you. The geography type has some restrictions, like less function support and higher CPU load, but since our math is relatively simple and we only generate these areas once, the geography type is the way to go.

Conclusion

Our work to generate and collate all of these service areas, and other information about bike-share systems, is to enable our users to access the data easily and build solutions of their own. In the future, we hope that systems will start to provide more of this information through standards like GBFS, and cities will require it as part of the permitting process. Until then, we will continue building hand-crafted datasets to make it easy for people to access and integrate this information.

As always, we welcome feedback and would love to hear from you via chat on our website coord.co.

--

--