Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Quick hack to take an OpenStreetMap bus route relation and convert it to an ordered series of points (suitable for use in a GTFS feed)
<?php
// This is the ID of the bus route relation.
$relation = '5838068';
// Retrieve the OSM for the object (which is XML of the relation and all of its children)
$xml = simplexml_load_file("http://www.openstreetmap.org/api/0.6/relation/$relation/full");
// First, we'll get all the ways that make up the "route" relation (assuming here there's only one!)
$relation_ways = array();
foreach ($xml->relation->member as $key => $member) {
// We only want the components with the role "forward" or "backward", which omits stops and platforms
if (((string)$member->attributes()->role == 'forward') or ((string)$member->attributes()->role == 'backward')) {
$relation_ways[] = array('ref' => (string)$member->attributes()->ref, 'direction' => (string)$member->attributes()->role);
}
}
// Next, we'll get ALL of the ways
$node = array();
foreach ($xml->way as $key => $member) {
$nd = array();
foreach ($member->nd as $key2 => $nd_member) {
$nd[] = (string)$nd_member->attributes()->ref;
}
$way[(string)$member->attributes()->id] = $nd;
}
// Next, we'll get ALL of the nodes
$node = array();
foreach ($xml->node as $key => $member) {
$node[(string)$member->attributes()->id] = array(
(string)$member->attributes()->lat,
(string)$member->attributes()->lon
);
}
// Now we loop through each way in the relation...
$points = array();
foreach ($relation_ways as $key => $one_way) {
// And if the way has a role of "forward" then we walk through the points in natural order
if ($one_way['direction'] == 'forward') {
foreach ($way[$one_way['ref']] as $key2 => $one_nd) {
$points[] = $node[$one_nd][0] . "," . $node[$one_nd][1] . "\n";
}
}
// Otherwise we assume the role is "backcward" and walk through the points in reverse order
else {
foreach (array_reverse($way[$one_way['ref']]) as $key2 => $one_nd) {
$points[] = $node[$one_nd][0] . "," . $node[$one_nd][1] . "\n";
}
}
}
print_r($points);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment