Querying OpenStreetMap API with CURL in a shell
The following snippets try to demonstrate how the OSM API can be accessed with
curl
in a
shell.
URL=https://api.openstreetmap.org
VERSION=0.6
API=$URL/api/$VERSION
Get the capabilities as
XML:
curl -s -X GET $API/capabilities
Get the capabilities as
JSON:
curl -s -X GET $API/capabilities.json
Use
jq
to extract the status of the OpenStreetMap database (ideally, this query returns
"online"
):
curl -s -X GET $API/capabilities.json | jq .api.status.database
Get a
way's data in XML format:
curl -s -X GET $API/way/1154969870
Get a way's data in JSON format:
curl -s -X GET $API/way/1154969870.json
Get elements in a given area
Specify values of bounding box (longitude and lattitude):
left=8.6408537
right=8.6532347
top=47.5215385
bottom=47.513771
Then get the bounding box's elements as XML …
curl -s -X GET $API/map?bbox=$left,$bottom,$right,$top
… or JSON:
curl -s -X GET $API/map.json?bbox=$left,$bottom,$right,$top
Modifying data (changesets)
OSM data is modified in the context of a changeset.
A changeset that is idle for one hour or is open for 24 hours or exceeds a certain limit of number of edits will be closed automatically.
Modifications of changesets are visible to other users while they're not closed.
URL=https://master.apis.dev.openstreetmap.org
VERSION=0.6
API=$URL/api/$VERSION
A user needs to be authenticated. We store the name of the OSM user and his password in environment variables:
OSMUSER=…
OSMPASSWORD=…
A changeset is opened and its id assigned to the variable changeset_id
.
This request apparently requires a
PUT
(rather than a
GET
)
method!
changeset_id=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/changeset/create -d '<osm><changeset>
<tag k="created_by" v="myself" />
<tag k="comment" v="testing changesets" />
</changeset></osm>' )
echo $changeset_id
We create four nodes and assign their ids to the environment variables node_id_1
through node_id_4
.
Note the changeset
attribut in the <node…>
tag of the request.
node_id_1=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/node/create -d @- <<PAYLOAD
<osm>
<node
changeset= "$changeset_id"
lon = "22.00001"
lat = "44.00001"
>
<tag k="name" v="test node one" />
</node>
</osm>
PAYLOAD
)
node_id_2=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/node/create -d @- <<PAYLOAD
<osm>
<node
changeset= "$changeset_id"
lon = "22.00002"
lat = "44.00001"
>
<tag k="name" v="test node two" />
</node>
</osm>
PAYLOAD
)
node_id_3=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/node/create -d @- <<PAYLOAD
<osm>
<node
changeset= "$changeset_id"
lon = "22.00002"
lat = "44.00002"
>
<tag k="name" v="test node three" />
</node>
</osm>
PAYLOAD
)
node_id_4=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/node/create -d @- <<PAYLOAD
<osm>
<node
changeset= "$changeset_id"
lon = "22.00001"
lat = "44.00002"
>
<tag k="name" v="test node four" />
</node>
</osm>
PAYLOAD
)
echo $node_id_{1..4}
We're now able to create a way that connects the four nodes:
way_id=$( curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT $API/way/create -d @- <<PAYLOAD
<osm>
<way
changeset= "$changeset_id"
>
<nd ref="$node_id_1" />
<nd ref="$node_id_2" />
<nd ref="$node_id_3" />
<nd ref="$node_id_4" />
<tag k="name" v="test way one" />
</way>
</osm>
PAYLOAD
)
echo $way_id
Finally, we close the changeset and thus persist our changes to the database:
curl -s -u "$OSMUSER:$OSMPASSWORD" -X PUT "$API/changeset/$changeset_id/close"
Get the data for the region with our way:
curl -s -X GET $API/map?bbox=$22.00000,44.00000,22.00003,44.00003