Contents:
This API call is used to add locations to the Photomap. Each location can have a photo (though this is not required) and a set of metadata can be attached.
The Photomap is intended as a campaigning tool to enable citizens to geolocate and tag problems such as lack of cycle parking, or to highlight good practice, so that this data can be used by cycle campaign groups, Local Authorities and others. A variety of sites (e.g. Urban Cycle Parking) have been built using the API. Photos are used within route listings on the main site, on the Photomap for general browsing, and by any API client accessing them.
This call is ideal for use in audit-style applications.
You can add arbitrary metadata fields to a location using additionalMetadata. This could be useful for auditing and similar uses, e.g. storing results of a formal survey at the location.
You can retrieve any data added (including unpacking of any additionalMetadata) using the other Photomap calls, particularly photomap.location
and photomap.locations
.
Clients may wish to make an initial call to photomap.categories
(and then cache the result of this) so that a list of the supported categories (e.g. 'cycleparking') and metacategories (e.g. 'bad') can be displayed as a drop-down list. This then enables the user to express good metadata on what their photo represents e.g. a cycle parking problem (category=cycleparking,metacategory=bad) at the point of uploading.
Example which adds a location representing a cycle parking problem, including a photo, and supplying some additional metadata resulting from a survey.
This call requires a POST operation, because (a) images are a binary payload, and (b) to avoid us logging user credentials in the server logs.
POST https://api.cyclestreets.net/v2/photomap.add ( [mediaupload] => [binary payload of the image file, containing embedded EXIF location and time data] [username] => myusername [password] => mypassword1978 [category] => cycleparking [metacategory] => good [caption] => This location serves the nearby shops. [additionalMetadata] => {"spaces":10,"covered":"no","highway":"Red route"} )
Result:
{ "id": 64001, "url": "https://www.cyclestreets.net/location/64001/", "shortlink": "https://cycle.st/p64001", "imageUrl": "https://www.cyclestreets.net/location/64001/cyclestreets64001.jpg", "thumbnailUrl": "https://www.cyclestreets.net/location/64001/cyclestreets64001-size425.jpg" }
You could later retrieve the data via a request to photomap.location
as follows:
https://api.cyclestreets.net/v2/photomap.location?id=64001&fields=id,hasPhoto,caption,additionalMetadata
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 64001, "hasPhoto": true, "caption": "This location serves the nearby shops.", "additionalMetadata": { "spaces": 10, "covered": "no", "highway": "Red route" } }, "geometry": { "type": "Point", "coordinates": [ 0.144333, 52.196999 ] } } ] }
The following are required or highly-recommended parameters.
The mediaupload payload field can be omitted if there is no image, but, naturally, photos add interest and value when using the data.
The latitude/longitude/datetime values will be gleaned from EXIF data where they exist. The server will always try to read data from EXIF. However, explicitly-supplied values will take priority. If no data is available (from EXIF or explicitly), the location will be set as an unlocated photo. If possible, supply values explicitly, by giving the user the opportunity first to confirm/adjust the location in your GUI, to ensure a correct GPS location.
photomap.categories
call.photomap.categories
call.latitude
.JSON object as above, showing the unique ID of the added location, together with URLs for its public page, image file and thumbnail file.
You may wish to use these to show the successfully uploaded location to the user by way of a confirmation screen, and/or invite the user to share the link on social media.
JSON object containing an error key and a text string.
The error string from this method is suitable for passing directly on to the user.
Example errors (text string may vary):
{
"error": "The username/password combination did not match any validated account."
}