Отношение типа street в OSM

Когда в Раменском какой-то добрый леловек из альтруистических побуждений заменил в названиях улиц "ул." на "улица" и сбил всю адресацию, я понял, что это не дело. Название улицы должно быть только в одном экземпляре. Этог можно добиться используя отношения типа street. Оно пока не утверждено, но в полной мере удовлетворяет тому, что мне нужно. Вот только ни рендереры, ни конвертеры его не поддерживают. Поэтому пришлось написать скриптик, который копирует название из отношения в его участников. Просто выгружаем кусочек с помощью JOSM, скармливаем скрипту:
php street.php current.osm new.osm
И заливаем его обратно.
<?php
$doc = new DOMDocument();
$doc->loadXML(file_get_contents($_SERVER['argv'][1]));
 
function replaceTag (&$object, $tag, $value) {
	global $doc;
	$changed = true;
 
	$tags = $object->getElementsByTagName("tag");
	$found = false;
	foreach ($tags as $otag) {
		if ($otag->getAttribute('k') == $tag) {
			$found = true;
			if ($otag->getAttribute("v") == $value)
				$changed = false;
			else
				$otag->setAttribute("v", $value);
		}
	}
	if (!$found) {
		$otag = $doc->createElement('tag');
		$object->appendChild($otag);
		$otag->setAttribute("k", $tag);
		$otag->setAttribute("v", $value);
	}
	return $changed;
}
 
$relations = $doc->getElementsByTagName ("relation");
foreach ($relations as $relation) {
	$tags = $relation->getElementsByTagName("tag");
	$type = false;
	$name = false;
	foreach ($tags as $tag) {
		if ($tag->getAttribute('k') == "type") {
			$type = $tag->getAttribute('v');
		}
		if ($tag->getAttribute('k') == "name") {
			$name = $tag->getAttribute('v');
		}
	}
	if ($type != "street" || !$name)
		continue 1;
 
	echo "Processing " . $name . "\n";
 
	$members = $relation->getElementsByTagName("member");
	foreach ($members as $member) {
		$id = $member->getAttribute('ref');
		echo "\t " . $member->getAttribute('type') . " $id";
		$refs = $doc->getElementsByTagName($member->getAttribute('type'));
		foreach ($refs as $ref) {
			if ($ref->getAttribute('id') == $id) {
				$changed = false;
				echo " +";
				switch ($member->getAttribute('role')) {
					case street:
						$changed = replaceTag ($ref, "name", $name);
						break;
					case house:
						$changed = replaceTag ($ref, "addr:street", $name);
						break;
				}
				if ($changed){
					$ref->setAttribute("action", "modify");
				}
				break;
			}
		}
		echo "\n";
	}
}
 
$fp = fopen($_SERVER['argv'][2], 'w');
fwrite($fp, $doc->saveXML());
fclose($fp);