How to use Nominatim API through PHP to retrieve latitude and longitude?

Osman picture Osman · Jun 8, 2017 · Viewed 7.6k times · Source

Below is the code that I am currently using in which I pass an address to the function and the Nominatim API should return a JSON from which I could retrieve the latitude and longitude of the address from.

function geocode($address){

    // url encode the address
    $address = urlencode($address);

    $url = 'http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1';


    // get the json response
    $resp_json = file_get_contents($url);

    // decode the json
    $resp = json_decode($resp_json, true);


        // get the important data
        $lati = $resp['lat'];
        $longi = $resp['lon'];

            // put the data in the array
            $data_arr = array();            

            array_push(
                $data_arr, 
                    $lati, 
                    $longi
                );

            return $data_arr;

}

The problem with it is that I always end up with an Internal Server Error. I have checked the Logs and this constantly gets repeated:

[[DATE] America/New_York] PHP Notice: Undefined index: title in [...php] on line [...]

[[DATE] America/New_York] PHP Notice: Undefined variable: area in [...php] on line [...]

What could be the issue here? Is it because of the _ in New_York? I have tried using str_replace to swap that with a + but that doesn't seem to work and the same error is still returned.

Also, the URL works fine since I have tested it out through JavaScript and manually (though {$address} was replaced with an actual address).

Would really appreciate any help with this, thank you!

Edit

This has now been fixed. The problem seems to be with Nominatim not being able to pickup certain values and so returns an error as a result

Answer

John C picture John C · Jun 8, 2017

The errors you have mentioned don't appear to relate to the code you posted given the variables title and area are not present. I can provide some help for the geocode function you posted.

The main issue is that there are single quotes around the $url string - this means that $address is not injected into the string and the requests is for the lat/long of "$address". Using double quotes resolves this issue:

$url = "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1";

Secondly, the response contains an array of arrays (if were not for the limit parameter more than one result might be expected). So when fetch the details out of the response, look in $resp[0] rather than just $resp.

// get the important data
$lati = $resp[0]['lat'];
$longi = $resp[0]['lon'];

In full, with some abbreviation of the array building at the end for simplicity:

function geocode($address){

    // url encode the address
    $address = urlencode($address);

    $url = "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1";

    // get the json response
    $resp_json = file_get_contents($url);

    // decode the json
    $resp = json_decode($resp_json, true);

    return array($resp[0]['lat'], $resp[0]['lon']);

}

Once you are happy it works, I'd recommend adding in some error handling for both the http request and decoding/returning of the response.