Contents:
The photomap locations API retrieves photos of categorised cycling-related infrastructure from a specified geographical area which have been submitted by users. The same data is visible on our Photomap.
As well as this call, a single-location equivalent is available as the photomap.location call.
Each location has various metadata attached to it, such as a caption, a category (e.g. cycleparking/obstruction/etc.), a metacategory (e.g. good/bad), date/time, location, and more.
You can retrieve arbitrary metadata fields added to a location using additionalMetadata. This could be useful for auditing and similar uses.
Note that each location has a license (e.g. Creative Commons, Public Domain, No reproduction permitted, etc.) as specified by the contributor. You are required to respect the specified license. Also, CycleStreets naturally has a database right in the collective dataset.
Not all locations have a photo attached to them. Such 'placeholders', however, do contain the other metadata.
The data is optimised to give an even spread within a map view when there would be too many to show at the current zoom level. To do this, it breaks the visible map into a 10x10 grid and chooses one photo from each grid cell.
Example which returns problem cycle parking locations in an area of Cambridge.
(In this example, a limit of only 3 locations has been set, to avoid a long example on this page, but normally a limit of perhaps 150 would be appropriate for web viewing.)
https://api.cyclestreets.net/v2/photomap.locations?category=cycleparking&metacategory=bad&limit=3&fields=id,hasPhoto,thumbnailUrl,license,caption&bbox=0.1456,52.1990,0.1487,52.2006
https://api.cyclestreets.net/v2/photomap.locations?category=cycleparking&metacategory=bad&limit=3&fields=id,hasPhoto,thumbnailUrl,license,caption&boundary=[[0.145246,52.199900],[0.146663,52.200873],[0.148401,52.200189],[0.147156,52.198808],[0.145246,52.199900]]
Result:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 10289, "hasPhoto": "yes", "thumbnailUrl": "https://www.cyclestreets.net/location/10289/cyclestreets10289-size200.jpg", "license": "cc-by-sa", "caption": "Complete lack of cycle parking on the highway forces cyclists to do this sort of thing. The pavement is totally blocked." }, "geometry": { "type": "Point", "coordinates": [ 0.146092, 52.199314 ] } }, { "type": "Feature", "properties": { "id": 23583, "hasPhoto": "no", "thumbnailUrl": null, "license": "publicdomain", "caption": "A lot of residents in side streets off Mill Road use bicycles as their primary means of transport. Converting a few car parking spaces into bicycle parking would be enormously helpful, since current bicycle parking provisions are virtually non-existent." }, "geometry": { "type": "Point", "coordinates": [ 0.147658, 52.200581 ] } }, { "type": "Feature", "properties": { "id": 53500, "hasPhoto": "yes", "thumbnailUrl": "https://www.cyclestreets.net/location/53500/cyclestreets53500-size200.jpg", "license": "publicdomain", "caption": "No home for bikes on a street dominated by car storage." }, "geometry": { "type": "Point", "coordinates": [ 0.14748, 52.1996 ] } } ] }
A boundary string as geojson-style polygonal coordinates of longitude,latitude that encloses the results.
The bbox and boundary parameters are mutually exclusive.
It is strongly recommended to specify a fields list, so that clients receive exactly the data they need.
Controls what information is returned for each location. It is strongly recommended to send this, so that clients receive exactly the data they need.
Available fields are listed below.
If fields is not supplied, the default is used, which represents a sensible and useful set of fields.
The fields id,latitude,longitude,caption are always returned.
When the data is returned in the geojson format, the values for latitude,longitude appear only in the /geometry/coordinates field rather than being duplicated in the properties list.
Fields are returned in the ordering specified by the caller, which can be useful when using export=csv.
Unrecognised fieldnames are simply ignored rather than an error being thrown.
cycleparking,obstructions
. The values for category [see examples] can be found using the photomap.categories
API call.good,bad
. The values for metacategory [see examples] can be found using the photomap.categories
API call.Limit to locations where caption contains the search value.
Currently there is a limitation that a bbox/boundary must be included.
Ouputs the data for export, with the specified format. The appropriate HTTP headers will be sent. The limit is increased to 2,000. Available values are:
fields
order will be respected.If specified, the datetime field (if requested in the fields list) will be converted from unixtime (the default output format) to a formatted version; the available output formats are:
date ('g:ia, jS F Y', $date)
in PHPdate ('jS F, Y', $date)
in PHPThe available fields are as follows:
(These are shown grouped for clarity; the groupings themselves are not part of the API itself.)
Sometimes, a client application may wish to capture from users additional metadata that is not currently supported in the standard list of fields. For instance, a client may wish to capture the number of cycle parking spaces at a location, or land ownership details.
In this circumstance, data can be submitted and retrieved using the additionalMetadata
field. The data is stored in this field as key/value string pairs, and is not indexed in the sense of being searchable by a key or value.
You can limit the specific key fields you want returned by specifying the field(s) as additionalMetadata[subfield1,subfield2,…]
.
When using export=csv
, and including fields=additionalMetadata
, you must specify the required subfield(s) as fields=additionalMetadata[subfield1,subfield2,…]
, as otherwise the CSV output could potentially contain an inconsistent number of columns.
additionalMetadata Example 1: The following example includes the additionalMetadata field.
The effect of this is that those subfields which do exist in the data are returned, or where no metadata is available the value is null
.
https://api.cyclestreets.net/v2/photomap.locations?category=cycleparking&fields=id,latitude,longitude,caption,additionalMetadata,datetime,shortlink&bbox=-0.489,51.28,0.236,51.686&limit=3&datetime=sqldatetime
Result:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 57141, "caption": "Cycle parking needed", "additionalMetadata": { "landtype": "highway" }, "datetime": "2014-03-18 13:33:55", "shortlink": "https://cycle.st/p57141" }, "geometry": { "type": "Point", "coordinates": [ 0.077049, 51.620388 ] } }, { "type": "Feature", "properties": { "id": 56208, "caption": "12 stands needed", "additionalMetadata": null, "datetime": "2014-01-16 18:06:39", "shortlink": "https://cycle.st/p56208" }, "geometry": { "type": "Point", "coordinates": [ -0.003292, 51.462429 ] } }, { "type": "Feature", "properties": { "id": 57143, "caption": "test", "additionalMetadata": { "landtype": "highway", "capacity": "2" }, "datetime": "2013-04-25 10:02:10", "shortlink": "https://cycle.st/p57143" }, "geometry": { "type": "Point", "coordinates": [ -0.163186, 51.523872 ] } } ] }
additionalMetadata Example 2: This example includes the additionalMetadata field but specifying the required subfields that the client believes are likely to be present (e.g. because the application commonly adds locations with such subfields).
The effect of this is to promote the subfields to be real fields, but capitalised to avoid the potential for clashes with standard fields. If a subfield is not present in a record, its key will still be present in the result, but set to NULL
as the value.
https://api.cyclestreets.net/v2/photomap.locations?category=cycleparking&fields=id,latitude,longitude,caption,additionalMetadata[landtype,capacity],datetime,shortlink&bbox=-0.489,51.28,0.236,51.686&limit=3&datetime=sqldatetime
Result:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 58827, "caption": "Incredible there is now such a large amount of space, but no cycle parking. A sign of a modern city is the presence of plenty of cycle parking at a station.", "Landtype": "highway", "Capacity": "200", "datetime": "2014-05-16 17:58:40", "shortlink": "https://cycle.st/p58827" }, "geometry": { "type": "Point", "coordinates": [ -0.123687, 51.53035 ] } }, { "type": "Feature", "properties": { "id": 30754, "caption": "The supermarket have provided good cycle parking outside their store, but as this picture clearly shows they need to provide more!", "Landtype": false, "Capacity": false, "datetime": "2011-03-12 17:04:53", "shortlink": "https://cycle.st/p30754" }, "geometry": { "type": "Point", "coordinates": [ -0.399704, 51.658985 ] } }, { "type": "Feature", "properties": { "id": 39233, "caption": "Segregated cycle lanes in both directions along King Henry's Drive", "Landtype": false, "Capacity": false, "datetime": "2012-06-10 13:48:02", "shortlink": "https://cycle.st/p39233" }, "geometry": { "type": "Point", "coordinates": [ -0.024977, 51.352341 ] } } ] }
GeoJSON feature list as per example above. Geometry types will always be Point.
(If export
has been specified, the relevant export format will be returned instead.)
Example with no locations in an area:
{ "type": "FeatureCollection", "features": [ ] }
JSON object containing an error key and a text string.
Even if export=…
is specified, any error response will still be a JSON object, as shown below.
Example errors (text string will vary):
{
"error": "Neither a bbox nor a detailed boundary have been supplied."
}
{ "error": "The category is not valid" }