Key:uuid/Example Code
Jump to navigation
Jump to search
Example Code to Automatically Tag OSM Objects
This example PHP cli script requires the php5-uuid module loaded, while there are pure php implementations of v4 UUID functions, using the OSSP library the php module is linked to should be more consistently random.
Output
In the sample output below, the script is using the dev server, the first time the script runs the UUID is added to the object, the next time any UUIDs are simply displayed.
# ./makeuuid.php node 268549131 uuid:amenity=a1b77379-37c0-46c1-ba70-8683c57493ac # ./makeuuid.php node 268549131 uuid:amenity=a1b77379-37c0-46c1-ba70-8683c57493ac
Code
#!/usr/bin/php -q
<?
$server = 'api06.dev.openstreetmap.org';
$OSMuser = 'username';
$OSMpass = 'password';
$uuidtypes = array('operator', 'building', 'amenity', 'barrier', 'waterway', 'railway', 'bridge', 'tunnel', 'aeroway', 'aerialway',
'power', 'man_made', 'leisure', 'office', 'shop', 'tourism', 'historic', 'landuse', 'military', 'natural', 'route',
'boundary', 'crossing', 'mountain_pass', 'cutting', 'embankment', 'place');
$setUUIDs = $UUIDs = array();
if(intval($argc) != 3)
die("Error!\n".$argv['0']." <object type> <object id>\n");
$objtype = strtolower($argv['1']);
$objid = intval($argv['2']);
if($objtype != 'node' && $objtype != 'way' && $objtype != 'relation')
$objtype = 'node';
$url = 'http://'.$server.'/api/0.6/'.$objtype.'/'.$objid;
$lines = explode("\n", trim(@file_get_contents($url)));
if(count($lines) < 1 || $lines['0'] == '')
die("No data returned from OSM server\n");
$lines['0'] = '<osmChange version="0.6" generator="makeuuid.php">';
$lines['1'] = '<modify>';
list($type, $rest) = explode(' ', trim($lines['2']), 2);
$lines['2'] = $type.' action="modify" '.$rest;
unset($lines[count($lines)-1]);
$close = $lines[count($lines)-1];
unset($lines[count($lines)-1]);
foreach($lines as $line)
{
$line = trim($line);
if(substr($line, 0, 5) == '<tag ')
{
list($crud, $key) = explode(' k="', $line, 2);
list($key, $val) = explode('" v="', $key, 2);
list($val, $crud) = explode('"', $val, 2);
if(in_array($key, $uuidtypes))
$UUIDs['uuid:'.$key] = true;
else if(substr($key, 0, 5) == 'uuid:')
$setUUIDs[$key] = $val;
}
}
foreach($setUUIDs as $key => $val)
{
if(isset($UUIDs[$key]))
unset($UUIDs[$key]);
}
if(count($UUIDs) <= 0)
{
if(count($setUUIDs))
{
foreach($setUUIDs as $key => $val)
echo "$key=$val\n";
die;
} else
die("Unable to add UUID to object.\n");
}
foreach($UUIDs as $key => $val)
{
$uuid = new uuid();
$UUIDs[$key] = $uuid->v4();
$lines[] = '<tag k="'.$key.'" v="'.$UUIDs[$key].'"/>';
}
$lines[] = $close;
$lines[] = '</modify>';
$lines[] = '</osmChange>';
$lines = implode("\n", $lines)."\n";
$chID = newChangeSet();
list($start, $rest) = explode(' changeset="', $lines, 2);
list($crud, $rest) = explode('"', $rest, 2);
$lines = $start.' changeset="'.$chID.'" '.$rest;
uploadChange($chID, $lines);
foreach($UUIDs as $key => $val)
echo "$key=$val\n";
foreach($setUUIDs as $key => $val)
echo "$key=$val\n";
function newChangeSet()
{
global $OSMuser, $OSMpass, $server;
$changeset = "<osm><changeset><tag k='created_by' v='BigTinCan Upload Script' /><tag k='comment' v='Adding UUIDs to Object'/></changeset></osm>";
$head = "PUT /api/0.6/changeset/create HTTP/1.1\r\n";
$head .= "host: $server\r\n";
$head .= "Authorization: Basic ".base64_encode($OSMuser.':'.$OSMpass)."\r\n";
$head .= "Content-Length: ".strlen($changeset)."\r\n";
$head .= "Connection: close\r\n\r\n".$changeset;
if(($fp = @fsockopen($server, 80)) === FALSE)
die("Unable to contact OSM Server.\n");
fputs($fp, $head);
$body = false;
while(!feof($fp))
{
$line = trim(fgets($fp));
if($line == '')
{
$body = true;
continue;
} else if(!$body)
continue;
$changeid = $line;
break;
}
fclose($fp);
if(intval($changeid) != $changeid || $changeid <= 0)
die("Failed to open new change set, error return from OSM: $changeid.\n");
return intval($changeid);
}
function uploadChange($chID, $object)
{
global $OSMuser, $OSMpass, $server;
$head = "POST /api/0.6/changeset/$chID/upload HTTP/1.1\r\n";
$head .= "host: $server\r\n";
$head .= "Authorization: Basic ".base64_encode($OSMuser.':'.$OSMpass)."\r\n";
$head .= "Content-Length: ".strlen($object)."\r\n";
$head .= "Content-Type: application/x-www-form-urlencoded\r\n";
$head .= "Connection: close\r\n\r\n".$object;
if(($fp = @fsockopen($server, 80)) === FALSE)
die("Unable to contact OSM Server.\n");
fputs($fp, $head);
fflush($fp);
$bits = explode(' ', trim(fgets($fp)), 3);
$lines = '';
while(!feof($fp))
$lines .= $line = fgets($fp);
fclose($fp);
if($bits['1'] != 200)
die("Failed to upload changes\n");
}
class uuid
{
protected $uuidobject;
protected function create()
{
if(!is_resource($this->uuidobject))
uuid_create(&$this->uuidobject);
}
public function v4()
{
$this->create();
uuid_make($this->uuidobject, UUID_MAKE_V4);
uuid_export($this->uuidobject, UUID_FMT_STR, &$uuidstring);
return trim($uuidstring);
}
}