2 Replies - 360 Views - Last Post: 20 February 2018 - 05:32 PM Rate Topic: -----

#1 sayhello   User is online

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 52
  • Joined: 12-November 17

improve an request against OSM Overpass API with PHP SimpleXML

Posted 17 February 2018 - 03:31 PM

The following is a little OSM Overpass API example with PHP SimpleXML I've compiled because we do not have it here for PHP and I love OSM, so let's show some useful examples.

The first part shows how tro query an Overpass Endpoint with standard PHP.
For you the second part is more interesting. That is querying the XML data; This is most easily done with xpath, the used PHP XML library is based on libxml which supports XPath 1.0 which covers the various querying needs very well.

<?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"~".*"]
  (-54.5247541978, 2.05338918702, 9.56001631027, 51.1485061713);
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)'];
list($website) = $school->xpath('tag[@k = "website"]/@v') + ['(no website)'];
list($email) = $school->xpath('tag[@k = "contact:email"]/@v') + ['(no email)'];
printf("#%02d: ID:%' -10s  [%s,%s]  %s %s %s\n", $index, $school['id'], $school['lat'], $school['lon'], $name, $website, $email);
}


//node[tag[@k = "amenity" and @v = "school"]]
//tag[@k = "name"]/@v'

$query = 'node
  ["addr:postcode"~"RM12"]
  (51.5557914,0.2118915,51.5673083,0.2369398);
   node
  (around:1000)
  ["amenity"~"fast_food"];
           out;';

$context = stream_context_create(['http' => [
    'method'  => 'POST',
    'header' => ['Content-Type: application/x-www-form-urlencoded'],
    'content' => 'data=' . urlencode($query),
]]);

$endpoint = 'http://overpass-api.de/api/interpreter';
libxml_set_streams_context($context);

$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));





well i wonder - the results look like a bit poor. I want to have a full adress-block if possible?

What can i do!? i need a full adress-data-set.


# Get the name of the school (if any), again with xpath
list($name) = $school->xpath('tag[@k = "name"]/@v') + ['(unnamed)'];
list($website) = $school->xpath('tag[@k = "website"]/@v') + ['(no website)'];
list($email) = $school->xpath('tag[@k = "contact:email"]/@v') + ['(no email)'];
printf("#%02d: ID:%' -10s  [%s,%s]  %s %s %s\n", $index, $school['id'], $school['lat'], $school['lon'], $name, $website, $email);




in need to change - & add the xpath requests and use more / different taging shemes...

see the results - we are gaining at the moment....:

i want to improve this...

#37158: ID:5243708521  [-3.6852719,33.4154523]  Buhangija primary school (no website) (no email)
#37159: ID:5243805321  [-1.5071460,31.1599459]  Kakiro Primary School (no website) (no email)
#37160: ID:5243883144  [-10.4578962,39.0935938]  Nangoo primary school (no website) (no email)
#37161: ID:5244163476  [-6.8637976,39.2586565]  PK Academic School (no website) (no email)
#37162: ID:5244163478  [-6.8603893,39.2564774]  Good Shepherd School (no website) (no email)
#37168: ID:5247155223  [-1.6856759,29.0159534]  Institut Miteetso (no website) (no email)
#37169: ID:5247165222  [-1.7063811,29.0168647]  Institut Lwanga-Bobandana (no website) (no email)
#37170: ID:5247312700  [9.0129509,38.7290080]  EiABC (Ethiopian Institute of Architecture Building Construction & City Devlopment) www.eiabc.edu.et (no email)
#37171: ID:5248364671  [-4.3973951,29.1373596]  École primaire Makama (no website) (no email)
#37172: ID:5248372022  [-1.7101942,29.0233846]  Institut Minova (no website) (no email)
#37173: ID:5248439027  [-4.2744570,35.7445025]  F . t . sumaye secondary school (no website) (no email)
#37177: ID:5248974492  [-4.5490651,29.1559410]  École primaire Kilicha (no website) (no email)
#37178: ID:5248974495  [-4.5476651,29.1508141]  École primaire Kazimia 2 (no website) (no email)
#37179: ID:5248974504  [-4.5543585,29.1479282]  École primaire Lwata (no website) (no email)

This post has been edited by sayhello: 17 February 2018 - 03:35 PM


Is This A Good Question/Topic? 0
  • +

Replies To: improve an request against OSM Overpass API with PHP SimpleXML

#2 Martyr2   User is offline

  • Programming Theoretician
  • member icon

Reputation: 5257
  • View blog
  • Posts: 14,069
  • Joined: 18-April 07

Re: improve an request against OSM Overpass API with PHP SimpleXML

Posted 17 February 2018 - 06:27 PM

I am not sure I understand. Just format the data however you want. Do it all in your printf, just use the right format specifiers...

printf("School Name:%s\nEmail:%s\nSchool's website: %s\n\n", $name, $email, $website);



I mean if you have all the data, all that is left is to format it how you like it. Here I add separate lines, add some labeling etc. I even double space between blocks.
Was This Post Helpful? 1
  • +
  • -

#3 sayhello   User is online

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 52
  • Joined: 12-November 17

Re: improve an request against OSM Overpass API with PHP SimpleXML

Posted 20 February 2018 - 05:32 PM

hello dear Martyr2

first of all - many many thanks for the quick reply. Yes i think youre right.


View PostMartyr2, on 17 February 2018 - 06:27 PM, said:

I am not sure I understand. Just format the data however you want.
Do it all in your printf, just use the right format specifiers...

printf("School Name:%s\nEmail:%s\nSchool's website: %s\n\n", $name, $email, $website);



i will do as adviced.


Quote

I mean if you have all the data, all that is left is to format it how you like
it. Here I add separate lines, add some labeling etc. I even double space between blocks.

great idea to add separte lines and labeling.

Again - many many thanks for your ideas / and for your encouraging!!!

i am glad to be in this great forums..
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1