Pico Leaflet: using the geocoder-php library

le 16/10/2014 dans Pico CMS #dev#Leaflet#php#Pico CMS#plugin

Instead of using the basic geocode function that use the PHP file_get_contents() function, you can use "The almost missing Geocoder PHP library!" : geocoder-php.

First, you have to install and load this library.

Edit the composer.json and add to the require section this line :

"willdurand/geocoder": "3.0.*@dev"

If curl isn't available on your server, you can add this line :

"curl/curl": "dev-master"

Then you have to update the packages :

$ composer update

You shoud now have the vendor/willdurand/geocoder folder.

Finally you have to replace the osm_geocode function, line 106-128 :

public function osm_geocode(&$addresses,&$titleart,&$urlart,$thumb)
{
    // Using an alternative service based on OSM rather than
    // http://nominatim.openstreetmap.org/search?format=json&q=
    // because of usage policy causing issues on shared web hosting
    $nominatim_baseurl = 'http://open.mapquestapi.com/nominatim/v1/search.php?format=json&q=';
    foreach ($addresses as $key => $value) {
        $nominatim_query = urlencode($value);
        $data = file_get_contents( "{$nominatim_baseurl}{$nominatim_query}&limit=1" );
        $json = json_decode( $data );
        if (!empty($json)) {
            $this->marker_coordinates[] = $json[0]->lat.','.$json[0]->lon;
            $this->marker_title[] = $titleart;
            $this->marker_url[] = $urlart;
            if (isset($this->leaflet_thumb) && $this->leaflet_thumb === true && $thumb != '') {
                $this->marker_thumb[] = '<br><img src="\'/'.$thumb.'\'">';
            }
            else {
                $this->marker_thumb[] = '';
            }
        }
    }
}

by this version :

public function osm_geocode(&$addresses,&$titleart,&$urlart,$thumb)
{
    $rootUrl = 'http://open.mapquestapi.com/nominatim/v1/search.php?format=json&q=';
    $geocoder = new \Geocoder\Geocoder();
    $adapter = new \Geocoder\HttpAdapter\CurlHttpAdapter();
    $chain = new \Geocoder\Provider\ChainProvider(array(
        // new \Geocoder\Provider\GoogleMapsProvider($adapter),
        new \Geocoder\Provider\NominatimProvider($adapter,$rootUrl),
    ));
    $geocoder->registerProvider($chain);
    foreach ($addresses as $key => $value) {
        try {
            $geocode = $geocoder->geocode($value)->getCoordinates();
            if (!empty($geocode)) {
                $this->marker_coordinates[] = $geocode[0].','.$geocode[1];
                $this->marker_title[] = $titleart;
                $this->marker_url[] = $urlart;
                if (isset($this->leaflet_thumb) && $this->leaflet_thumb === true && $thumb != '') {
                    $this->marker_thumb[] = '<br /><img src=\'/'.$thumb.'\' />';
                }
                else {
                    $this->marker_thumb[] = '';
                }
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
}

You can simply download the pico_leaflet.php from the devel_geophp branch : https://github.com/bricebou/pico_leaflet/tree/devel_geophp.

WARNING: if your use a shared web hosting, there is a chance that you obtain errors, time outs, or that you don't get any response when trying to geocode addresses with some APIs like Google Maps, OpenStreetMap...
It is due to some restrictions of the geocoding services, but using the $rootUrl in the code above solves this issue.