Xpath-query against Overpass API-endpoint: an example with PHP SimpleXML
| From: | Martin Kaspar | Date: | Fri, 20 Jun 2014 12:11:51 +0000 |
| Subject: | Xpath-query against Overpass API-endpoint: an example with PHP SimpleXML | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-323502@lists.php.net to get a copy of this message | ||
Dear list,
new to PHP and to xpath as well...
Also new to this great list.
first of all - i am stuck with this issue of this posting. i have no glue
how to solve the xpath-request - is it a foreach in a loop. - i guess. but
i do not know. Well - to tell you the story from the beginning: i have a
little openstreetmap-project.
And i am fairly new to openstreetmap . i have a little project where i
have to gather infomration from the openstreetmap-file. i do this at the
overpass-api - to evaluate the code if it runs nicely i can do the request
via the downloaded overpass-api which i am willing to install on my
opensuse linux box.
Question and Purpose: i want to refiine an xpath query to get a more
sophisticated result. See below the live-example.
i am a teacher and i want to get the data from shools in africa, south
america and asia (so you see that we have different countries in
consideration which may map in a different way. This may be probably
intersting since i assune that there were different depths and different
ammmounts of tags within a xml-file...
The code wants 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.This 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 SimpleXML
it is a request that performs a Query to the OSM Overpass API Endpoint
<?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);
}
?>
The key point here are the xpath queries. Two are used, the first one to
get the nodes that have certain tags. The most interesting one for me is
//node[tag[@k = "amenity" and @v = "school"]]
This line says: Give me 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:
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 we can see, some parts are again similar to the line before.
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:
list($name) = $school->xpath('tag[@k = "name"]/@v') +
['(unnamed)'];
^^^^^^^^^^^^^^^
Provide Default Value
So here are the results for that code-example:
Query returned 907 node(s) and took 1.10735 seconds.
10 School(s) found:
#00: ID:332534486 [39.5017565,16.2721899] Scuola Primaria
#01: ID:1428094278 [39.3320912,16.1862820] (unnamed)
#02: ID:1822746784 [38.9075566,16.5776597] (unnamed)
#03: ID:1822755951 [38.9120272,16.5713431] (unnamed)
#04: ID:1903859699 [38.6830409,16.5522243] Liceo Scientifico Statale A.
Guarasci
#05: ID:2002566438 [39.1347698,16.0736924] (unnamed)
#06: ID:2056891127 [39.4106679,16.8254844] (unnamed)
#07: ID:2056892999 [39.4124687,16.8286119] (unnamed)
#08: ID:2272010226 [39.4481717,16.2894353] SCUOLA DELL'INFANZIA SAN
FRANCESCO
#09: ID:2272017152 [39.4502366,16.2807664] SCUOLA MEDIA
Question and Purpose:
well i want to have more tags - and more information that is in the
xml-file. i want to gather more - and now i try to figure out how i can
enter more xpath queries at the above mentioned code in a (foreach) loop
and get out even more important data - see here [url=
http://wiki.openstreetmap.org/wiki/Key:contact]Key:contact
- OpenStreetMap
Wiki[/url]
contact:phone
contact:fax
contact:website
contact:email
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:
tag[@k = "name"]/@v'
tag[@k = "contact:website"]/@v'
tag[@k = "contact:email"]/@v'
or - above all gathering all the infomration that are stored in the xml-file
on a sidenote; perhaps this may help - to evaluate the code - in order to
see which tags are in it.....
echo "<pre>";
var_dump($result);
echo "</pre>";
note; at the end i want to store the data in a mysql db..... so if we
gather as much infomration as possible i would be glad.
What do you say...? How can we extend the serach in the xml-documents to
gather more information? Which xpath-request does help here....
dear List - i look forward to hear from you
many many greetings from heidelberg,
Martin
On Fri, Jun 20, 2014 at 1:11 PM, Lester Caine <lester@lsces.co.uk> wrote:
> In the past life was easy and one could hand modify a .css to change the
> style of a website, then css3/html5 came along and where as we used
> small .css files in the past, something 20 times the size seems to be
> essential these days?
>
> I had ported the theme management over to 'ink', but with customers
> looking at these 'nice animated sites' created by bootstrap and slightly
> better way version 3 works, I'm now running a setup with almost stock
> bootstrap, except for the icon set which I'm still using 'proper colour
> icons' for :)
>
> There are a number of on-line services to allow customizing the base css
> and most seem to work well enough but they are a closed book when it
> comes to modifications such as tweaking the icon handling. A few do have
> code posted on github, but none of the ones I've tried so far will work
> without being able to 'phone home' and
> I can't run a clean local build. So has anybody found a php friendly
> bootstrap css editor or am I going to have to massage something from the
> parts I do currently have?
>
> --
> Lester Caine - G8HFL
> -----------------------------
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
--
<http://www.facebook.com/martin.kaspar.547>
[image:
gplus_Seiten_Signatur] <https://plus.google.com/u/0/104428351748591530426>