I'm a bit unclear how to use MagicParser to extract all the node ids, lat and long from this:
http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145
all the best
Scott
Thanks very much David. It worked like a dream!
You must get fed up with all the questions but now I'm having a problem with WAY from the same file.
WAY is in this format:
<way id="4020271" visible="true" timestamp="2007-07-13T09:52:50+01:00" user="user_4133">
<nd ref="21324374" />
<nd ref="21324376" />
<nd ref="398692" />
<tag k="highway" v="secondary" />
<tag k="created_by" v="JOSM" />
<tag k="name" v="Arnulfstraße" />
<tag k="lanes" v="2" />
<tag k="oneway" v="true" />
</way>
I need to parse the file so that the nd refs and the tag k elements are connected to the correct way ID.
So in one parse I need to pick up each nd ref, each tag k (both "highway" and "secondary" and the way id holding them. Is this straightforward?
all the best (again!)
Scott
Hi Scott,
These are slightly trickier because there are multiple NDs and TAGs within each WAY record. Magic Parser resolves duplicate names by appending @2, @3 etc. to each field name, so some mechanism is required to reformat the data into a more usable format.
The best method in this case I think is to loop through $record, checking for NDs, and the -K and -V attributes of each TAG. You do this by using a foreach() loop through $record; and then adding each value you come across (using string comparison) to an appropriate array - $nds for the NDs and $tags for the TAGs. It's probably easier to show you by example, so here's a script to create arrays of each:
<?php
header("Content-Type: text/plain");
require("MagicParser.php");
function myRecordHandler($record)
{
$nds = array();
$tags = array();
foreach($record as $k => $v)
{
if (strpos($k,"-REF"))
{
$nds[] = $v;
}
if (strpos($k,"-K"))
{
$currentK = $v;
}
if (strpos($k,"-V") && $currentK)
{
$tags[$currentK] = $v;
$currentK = "";
}
}
print_r($nds);
print_r($tags);
print "\n\n";
}
$url = "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
MagicParser_parse($url,"myRecordHandler","xml|OSM/WAY/");
?>
This script using content-type text/plain for clarity, but in your application this is probably not relevant, and you can then just use the data from $nds and $tags as required.
$nds is just an array of the nd refs, whereas $tags is an associative array using the -K and -V attributes from the XML, so you would access the "lanes" value as:
$tags["lanes"]
Hope this helps!
Cheers,
David.
Hi David,
Sorry for all these questions. I implemented this like so:
function XMLtrails_passtwo($item)
{
$nds = array();
$tags = array();
foreach($item as $k => $v)
{
if (strpos($k,"-REF"))
{
$nds[] = $v;
}
if (strpos($k,"-K"))
{
$currentK = $v;
}
if (strpos($k,"-V") && $currentK)
{
$tags[$currentK] = $v;
$currentK = "";
}
}
echo $nds[1]."<br>";
echo $tags["highway"]."<br>";
}
require("MagicParser.php");
$url = "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
$format_string = "xml|OSM/WAY/";
MagicParser_parse($url, "XMLtrails_passtwo", $format_string);
It parsed the very first WAY successfully, but then gave up.
best regards
Scott
Hi Scott,
I just ran your code on my server, completely unmodified and it has displayed 5 WAYs correctly..
Are you only seeing:
21324376
secondary
...when you run this on your server?
Cheers,
David.
It works perfect - I confused myself by using item[1] hardcoded. Now solved with a count variable inside the foreach and resolving that way.
Thanks for all of your excellent help!
Scott
Hi Scott,
Assuming that you're using auto-detection, what's happening here is that because there are more WAY records than NODE records, these are what are being picked up as the repeating record. To handle this, you need to specify a format string in order to specify that it is the NODE records you want. In the case of your XML, the format string required is:
xml|OSM/NODE/
Here's an example, which will display each node ID, lat and long:
<?php
require("MagicParser.php");
function myRecordHandler($record)
{
print "<p>";
print "Node ID: ".$record["NODE-ID"]." ";
print "Lat: ".$record["NODE-LAT"]." ";
print "Lon: ".$record["NODE-LON"]." ";
print "</p>";
}
$url = "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
MagicParser_parse($url,"myRecordHandler","xml|OSM/NODE/");
?>
If you want to access the other set of records in that file (WAYs), then the format string would be:
xml|OSM/WAY/
Hope this helps!
Cheers,
David.