hello dear buddy - i have another question -
sure you can help me here tooo...
I am new to PHP's SimpleXML. Below I have added my own answer to the question, how to refine the code to ad more tags.
I want to filter the data to get the nodes with special category. Here is sample of the OSM data I want to get the whole schools within an area. The first script runs well - but now I want to refine the search and add more tags. I want to store all into MySQL.
So we need to make some XML parsing with PHP:
The following is a little OSM Overpass API example with PHP SimpleXM
we need to do this here
- Code: Select all
<?php
/**
* OSM Overpass API with PHP SimpleXML / XPath
*
* PHP Version: 5.4 - Can be back-ported to 5.3 by using 5.3 Array-Syntax (not PHP 5.4's square brackets)
*/
//
// 1.) Query an OSM Overpass API Endpoint
//
$query = 'node
["amenity"~".*"]
(38.415938460513274,16.06338500976562,39.52205163048525,17.51220703125);
out;';
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => ['Content-Type: application/x-www-form-urlencoded'],
'content' => 'data=' . urlencode($query),
]]);
# please do not stress this service, this example is for demonstration purposes only.
$endpoint = 'http://overpass-api.de/api/interpreter';
libxml_set_streams_context($context);
$start = microtime(true);
$result = simplexml_load_file($endpoint);
printf("Query returned %2\$d node(s) and took %1\$.5f seconds.\n\n", microtime(true) - $start, count($result->node));
//
// 2.) Work with the XML Result
//
# get all school nodes with xpath
$xpath = '//node[tag[@k = "amenity" and @v = "school"]]';
$schools = $result->xpath($xpath);
printf("%d School(s) found:\n", count($schools));
foreach ($schools as $index => $school)
{
# Get the name of the school (if any), again with xpath
list($name) = $school->xpath('tag[@k = "name"]/@v') + ['(unnamed)'];
printf("#%02d: ID:%' -10s [%s,%s] %s\n", $index, $school['id'], $school['lat'], $school['lon'], $name);
}
?>
i just have had a quick view on the above mentioned site. i try to figure out how to do this - for any and all hints i am thankful
The following code lists all schools and tries to obtain their names as well. I have not covered translations yet because my sample data didn't have those, but you can also look for all kind of names including translations and just prefer a specific one):
Code:
//
// 2.) Work with the XML Result
//
# get all school nodes with xpath
$xpath = '//node[tag[@k = "amenity" and @v = "school"]]';
$schools = $result->xpath($xpath);
printf("%d School(s) found:\n", count($schools));
foreach ($schools as $index => $school)
{
# Get the name of the school (if any), again with xpath
list($name) = $school->xpath('tag[@k = "name"]/@v') + ['(unnamed)'];
printf("#%02d: ID:%' -10s [%s,%s] %s\n", $index, $school['id'], $school['lat'], $school['lon'], $name);
}
The key point here are the xpath queries.
In the above mentioend example two are used, the first xpath queriy is to get the nodes that have certain tags.I think this is the most interesting one for me:
- Code: Select all
//node[tag[@k = "amenity" and @v = "school"]]
This line says: Give us all node elements that have a tag element inside which has the k attribute value "amenity" and the v attribute value "school". This is the condition we have to filter out those nodes that are tagged with amenity school.
Further on xpath is used again, now relative to those school nodes to see if there is a name and if so to fetch it:
- Code: Select all
tag[@k = "name"]/@v'
This line says: Relative to the current node, give me the v attribute from a tag element that as the k attribute value "name". As you can see, some parts are again similar to the line before. I think you can both adopt them to your needs.
Because not all school nodes have a name, a default string is provided for display purposes by adding it to the (then empty) result array:
- Code: Select all
list($name) = $school->xpath('tag[@k = "name"]/@v') + ['(unnamed)'];
^^^^^^^^^^^^^^^
Provide Default Value
So here my results for that code-example:
Query returned xxxxx node(s) and took 1.10735 seconds.
2179 School(s) found: the last ones are shown below.....
- Code: Select all
#2151: ID:2688357765 [51.4668941,-0.9731135] New Directrions, North Reading
#2152: ID:2702504696 [51.5884265,-0.7829013] Burford School
#2153: ID:2702549737 [51.5802201,-0.7653918] Great Marlow School
#2154: ID:2706219304 [51.3779317,-0.0895302] ARK Oval Primary Academy
#2155: ID:2706219314 [51.3871935,-0.0623001] Ashburton Primary School
#2156: ID:2706219320 [51.3210977,-0.1398859] CALAT Smitham Centre
#2157: ID:2706219326 [51.3638861,-0.0922032] Elmhurst School
#2158: ID:2706219339 [51.4007121,-0.0743710] Harris Academy South Norwood
#2159: ID:2706219343 [51.3831662,-0.0405476] Orchard Way Primary School
#2160: ID:2706219347 [51.3531047,-0.0959447] Purley Oaks Primary School
#2161: ID:2706219348 [51.3428384,-0.0069931] Rowdown Primary School
#2162: ID:2706219350 [51.3954917,-0.0732185] South Norwood Primary School
#2163: ID:2706219351 [51.3377151,-0.1230482] St David's Preparatory School
#2164: ID:2706219353 [51.3993760,-0.1144352] Winterbourne School
#2165: ID:2717394621 [51.8706538,0.1480886] Prep
#2166: ID:2717394636 [51.8685838,0.1463720] Pre-Prep
#2167: ID:2722704201 [51.1398429,-0.0457445] Felbridge Primary School
#2168: ID:2723815070 [50.8465429,-0.3030261] Lancing College
#2169: ID:2727170814 [51.5780664,-0.0249051] Adult Education Centre
#2170: ID:2833253896 [50.9928140,-0.7774996] (unnamed)
#2171: ID:2837001831 [51.1783749,-0.7970866] More House School
#2172: ID:2865091022 [50.9090614,-0.5565425] Dorset House School
#2173: ID:2882477853 [51.6261198,-0.7349665] Bowerdean Primary School
#2174: ID:2901434856 [51.6542477,-0.3098923] The Haberdashers' Aske's Girls School
#2175: ID:2901434857 [51.6565707,-0.3129822] The Haberdashers' Aske's Boys School
and now i try to figure out how i can enter more xpath queries at the above mentioned code
and get out even more important data - see here Key:contact - OpenStreetMap Wiki
- Code: Select all
contacthone
contact:fax
contact:website
contact:email
i will digg into all documents and come back later the weekend... and report all the findings
well - i think that i need to extend the xpath requests within the loop where xpath is used again,
now relative to those school nodes to see if there is a name and if so to fetch it:
- Code: Select all
tag[@k = "name"]/@v'
tag[@k = " contact:website"]/@v'
tag[@k = " contact:email"]/@v'
hope you can help me...
look forward to hear from you