server/src/app/Services/GeonamesResolver.php
author ymh <ymh.work@gmail.com>
Tue, 27 Sep 2016 23:43:29 +0200
changeset 304 20071981ba2a
child 308 e032d686d88e
permissions -rw-r--r--
add location and geonames resolvers and api
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
304
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
namespace CorpusParole\Services;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
use CorpusParole\Services\GeonamesResolverInterface;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
use Cache;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
use Config;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
use EasyRdf\Graph;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
use GuzzleHttp\Client;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
use GuzzleHttp\Exception\RequestException;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
use GuzzleHttp\Exception\ClientException;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
use GuzzleHttp\Exception\GuzzleException;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
use Illuminate\Contracts\Cache\Repository as CacheRepository;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
class GeonamesResolver implements GeonamesResolverInterface {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
    private $client = null;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
    public function __construct(Client $httpClient) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
        $this->client = $httpClient;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    /**
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
     * make the Geonames query.
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
     */
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
    public function queryLabel($id) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        $url = config('corpusparole.geonames_base_url').$id."/";
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
        try {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
            $response = $this->client->get($url, ['headers'=>['Accept' => 'application/rdf+xml'],]);
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
        catch(ClientException $e) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
            if($e->getResponse()->getStatusCode() === 404) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
                return null;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
            } else {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
                throw new GeonamesResolverException(
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
                    $e->getMessage(),
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
                    $e->getResponse()->getStatusCode(),
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
                    $e
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
                );
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
            }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        catch(RequestException $e) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
            throw new GeonamesResolverException(
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
                $e->getMessage(),
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
                $e->hasResponse()?$e->getResponse()->getStatusCode():500,
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
                $e
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
            );
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        $graph = new Graph($url, $response->getBody());
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        $labels = [];
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
        // search First offficial name in fr then name
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
        foreach ($graph->allLiterals("<$url>", "<http://www.geonames.org/ontology#officialName>") as $labelLit) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
            $lang = $labelLit->getLang();
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
            if(!$lang && !isset($labels[''])) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
                $labels[''] = $labelLit->getvalue();
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
            }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
            elseif (strpos($lang, 'fr') === 0 && !isset($labels['fr'])) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
                $labels['fr'] = $labelLit->getvalue();
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
            }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        $label = isset($labels['fr']) ? $labels['fr'] : ( isset($labels[''])? $labels['']: null) ;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
        if(is_null($label)) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
            $labelLit = $graph->getLiteral("<$url>", "<http://www.geonames.org/ontology#name>");            
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
            $label = (!is_null($labelLit)) ? $labelLit->getValue() : null;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        return $label;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
    /**
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
     * Check Geonames id format
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
     */
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    private function checkGeonamesIdFormat($geonamesid) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        return ctype_digit($geonamesid);
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
    }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
    /**
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
     * Get name from Geonames id
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
     * @param string $id The id to resolve. Can be an url starting with http://sws.geonames.org/
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
     * @return a string with the name
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
     */
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
    public function getLabel($id) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        $geonamesid = $id;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
        if(strpos($id, config('corpusparole.geonames_base_url')) === 0) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
            $geonamesid = substr($id, strlen(config('corpusparole.geonames_base_url')));
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
        $geonamesid = rtrim($geonamesid, '/');
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        if(!$this->checkGeonamesIdFormat($geonamesid)) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
            throw new GeonamesResolverException("GeonamesId not in correct format", 400);
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
        $that = $this;
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        return Cache::remember("geonames:$geonamesid", config('corpusparole.geonames_cache_expiration'), function() use ($that, $geonamesid)  {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
            return $that->queryLabel($geonamesid);
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        });
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
    }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
    /**
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
     * Get a list of names from an array of geonames ids.
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
     * @param array $ids The array of ids to resolve.
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
     *                   Each id can be an url starting with http://geonames.org/geonames/
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
     */
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
    public function getLabels(array $ids) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        if(count($ids) > config('corpusparole.geonames_max_ids')) {
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
            throw new GeonamesResolverException("Too manys ids provided");
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        return array_combine($ids, array_map([$this,'getLabel'], $ids));
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
    }
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
20071981ba2a add location and geonames resolvers and api
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
}