Skip to content

Commit af24d70

Browse files
authored
Extend Geocode Earth provider from Pelias provider (#1005)
* Extend Geocode Earth provider from Pelias provider Related to #1004 * Apply fixes from StyleCI * Update GeocodeEarth.php Make url and version constants. * Apply fixes from StyleCI * Add Pelias provider dependency * Update GeocodeEarthTest.php Fix provider name in exception. * Update cached responses
1 parent 85ee1bb commit af24d70

15 files changed

+27
-168
lines changed

src/Provider/GeocodeEarth/GeocodeEarth.php

Lines changed: 11 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,17 @@
1414

1515
use Geocoder\Collection;
1616
use Geocoder\Exception\InvalidCredentials;
17-
use Geocoder\Exception\QuotaExceeded;
18-
use Geocoder\Exception\UnsupportedOperation;
19-
use Geocoder\Model\Address;
20-
use Geocoder\Model\AddressCollection;
2117
use Geocoder\Query\GeocodeQuery;
2218
use Geocoder\Query\ReverseQuery;
23-
use Geocoder\Http\Provider\AbstractHttpProvider;
19+
use Geocoder\Provider\Pelias\Pelias;
2420
use Geocoder\Provider\Provider;
2521
use Http\Client\HttpClient;
2622

27-
final class GeocodeEarth extends AbstractHttpProvider implements Provider
23+
final class GeocodeEarth extends Pelias implements Provider
2824
{
29-
/**
30-
* @var string
31-
*/
32-
const GEOCODE_ENDPOINT_URL = 'https://api.geocode.earth/v1/search?text=%s&api_key=%s&size=%d';
25+
const API_URL = 'https://api.geocode.earth/';
3326

34-
/**
35-
* @var string
36-
*/
37-
const REVERSE_ENDPOINT_URL = 'https://api.geocode.earth/v1/reverse?point.lat=%f&point.lon=%f&api_key=%s&size=%d';
27+
const API_VERSION = 1;
3828

3929
/**
4030
* @var string
@@ -52,22 +42,17 @@ public function __construct(HttpClient $client, string $apiKey)
5242
}
5343

5444
$this->apiKey = $apiKey;
55-
parent::__construct($client);
45+
parent::__construct($client, self::API_URL, self::API_VERSION);
5646
}
5747

5848
/**
5949
* {@inheritdoc}
6050
*/
6151
public function geocodeQuery(GeocodeQuery $query): Collection
6252
{
63-
$address = $query->getText();
64-
65-
// This API doesn't handle IPs
66-
if (filter_var($address, FILTER_VALIDATE_IP)) {
67-
throw new UnsupportedOperation('The GeocodeEarth provider does not support IP addresses, only street addresses.');
68-
}
69-
70-
$url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address), $this->apiKey, $query->getLimit());
53+
$url = $this->getGeocodeQueryUrl($query, [
54+
'api_key' => $this->apiKey,
55+
]);
7156

7257
return $this->executeQuery($url);
7358
}
@@ -77,10 +62,9 @@ public function geocodeQuery(GeocodeQuery $query): Collection
7762
*/
7863
public function reverseQuery(ReverseQuery $query): Collection
7964
{
80-
$coordinates = $query->getCoordinates();
81-
$longitude = $coordinates->getLongitude();
82-
$latitude = $coordinates->getLatitude();
83-
$url = sprintf(self::REVERSE_ENDPOINT_URL, $latitude, $longitude, $this->apiKey, $query->getLimit());
65+
$url = $this->getReverseQueryUrl($query, [
66+
'api_key' => $this->apiKey,
67+
]);
8468

8569
return $this->executeQuery($url);
8670
}
@@ -92,131 +76,4 @@ public function getName(): string
9276
{
9377
return 'geocode_earth';
9478
}
95-
96-
/**
97-
* @param $url
98-
*
99-
* @return Collection
100-
*/
101-
private function executeQuery(string $url): AddressCollection
102-
{
103-
$content = $this->getUrlContents($url);
104-
$json = json_decode($content, true);
105-
106-
if (isset($json['meta'])) {
107-
switch ($json['meta']['status_code']) {
108-
case 403:
109-
throw new InvalidCredentials('Invalid or missing api key.');
110-
case 429:
111-
throw new QuotaExceeded('Valid request but quota exceeded.');
112-
}
113-
}
114-
115-
if (!isset($json['type']) || 'FeatureCollection' !== $json['type'] || !isset($json['features']) || 0 === count($json['features'])) {
116-
return new AddressCollection([]);
117-
}
118-
119-
$locations = $json['features'];
120-
121-
if (empty($locations)) {
122-
return new AddressCollection([]);
123-
}
124-
125-
$results = [];
126-
foreach ($locations as $location) {
127-
$bounds = [
128-
'south' => null,
129-
'west' => null,
130-
'north' => null,
131-
'east' => null,
132-
];
133-
if (isset($location['bbox'])) {
134-
$bounds = [
135-
'south' => $location['bbox'][3],
136-
'west' => $location['bbox'][2],
137-
'north' => $location['bbox'][1],
138-
'east' => $location['bbox'][0],
139-
];
140-
}
141-
142-
$props = $location['properties'];
143-
144-
$adminLevels = [];
145-
foreach (['region', 'county', 'locality', 'macroregion', 'country'] as $i => $component) {
146-
if (isset($props[$component])) {
147-
$adminLevels[] = ['name' => $props[$component], 'level' => $i + 1];
148-
}
149-
}
150-
151-
$results[] = Address::createFromArray([
152-
'providedBy' => $this->getName(),
153-
'latitude' => $location['geometry']['coordinates'][1],
154-
'longitude' => $location['geometry']['coordinates'][0],
155-
'bounds' => $bounds,
156-
'streetNumber' => isset($props['housenumber']) ? $props['housenumber'] : null,
157-
'streetName' => isset($props['street']) ? $props['street'] : null,
158-
'subLocality' => isset($props['neighbourhood']) ? $props['neighbourhood'] : null,
159-
'locality' => isset($props['locality']) ? $props['locality'] : null,
160-
'postalCode' => isset($props['postalcode']) ? $props['postalcode'] : null,
161-
'adminLevels' => $adminLevels,
162-
'country' => isset($props['country']) ? $props['country'] : null,
163-
'countryCode' => isset($props['country_a']) ? strtoupper($props['country_a']) : null,
164-
]);
165-
}
166-
167-
return new AddressCollection($results);
168-
}
169-
170-
/**
171-
* @param array $components
172-
*
173-
* @return null|string
174-
*/
175-
protected function guessLocality(array $components)
176-
{
177-
$localityKeys = ['city', 'town', 'village', 'hamlet'];
178-
179-
return $this->guessBestComponent($components, $localityKeys);
180-
}
181-
182-
/**
183-
* @param array $components
184-
*
185-
* @return null|string
186-
*/
187-
protected function guessStreetName(array $components)
188-
{
189-
$streetNameKeys = ['road', 'street', 'street_name', 'residential'];
190-
191-
return $this->guessBestComponent($components, $streetNameKeys);
192-
}
193-
194-
/**
195-
* @param array $components
196-
*
197-
* @return null|string
198-
*/
199-
protected function guessSubLocality(array $components)
200-
{
201-
$subLocalityKeys = ['neighbourhood', 'city_district'];
202-
203-
return $this->guessBestComponent($components, $subLocalityKeys);
204-
}
205-
206-
/**
207-
* @param array $components
208-
* @param array $keys
209-
*
210-
* @return null|string
211-
*/
212-
protected function guessBestComponent(array $components, array $keys)
213-
{
214-
foreach ($keys as $key) {
215-
if (isset($components[$key]) && !empty($components[$key])) {
216-
return $components[$key];
217-
}
218-
}
219-
220-
return null;
221-
}
22279
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:4642:"{"geocoding":{"version":"0.2","attribution":"https://geocode.earth/guidelines","query":{"size":5,"private":false,"point.lat":54.0484068,"point.lon":-2.7990345,"boundary.circle.lat":54.0484068,"boundary.circle.lon":-2.7990345,"lang":{"name":"English","iso6391":"en","iso6393":"eng","defaulted":true},"querySize":10},"engine":{"name":"Pelias","author":"Mapzen","version":"1.0"},"timestamp":1569514974986},"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-2.798964,54.04843]},"properties":{"id":"way/568787583","gid":"openstreetmap:venue:way/568787583","layer":"venue","source":"openstreetmap","source_id":"way/568787583","name":"Collegian W.M.C","housenumber":"1","street":"Gage Street","postalcode":"LA1 1UH","confidence":0.9,"distance":0.005,"accuracy":"point","country":"United Kingdom","country_gid":"whosonfirst:country:85633159","country_a":"GBR","macroregion":"England","macroregion_gid":"whosonfirst:macroregion:404227469","region":"Lancashire","region_gid":"whosonfirst:region:85683853","region_a":"LAN","locality":"Lancaster","locality_gid":"whosonfirst:locality:101873271","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"Collegian W.M.C, Lancaster, England, United Kingdom"},"bbox":[-2.7991111,54.0483534,-2.798818,54.0485068]},{"type":"Feature","geometry":{"type":"Point","coordinates":[-2.798964,54.04843]},"properties":{"id":"way/568787583","gid":"openstreetmap:address:way/568787583","layer":"address","source":"openstreetmap","source_id":"way/568787583","name":"1 Gage Street","housenumber":"1","street":"Gage Street","postalcode":"LA1 1UH","confidence":0.9,"distance":0.005,"accuracy":"point","country":"United Kingdom","country_gid":"whosonfirst:country:85633159","country_a":"GBR","macroregion":"England","macroregion_gid":"whosonfirst:macroregion:404227469","region":"Lancashire","region_gid":"whosonfirst:region:85683853","region_a":"LAN","locality":"Lancaster","locality_gid":"whosonfirst:locality:101873271","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"1 Gage Street, Lancaster, England, United Kingdom"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-2.79913,54.048378]},"properties":{"id":"node/3930587961","gid":"openstreetmap:venue:node/3930587961","layer":"venue","source":"openstreetmap","source_id":"node/3930587961","name":"Stable End Curio's","confidence":0.9,"distance":0.007,"accuracy":"point","country":"United Kingdom","country_gid":"whosonfirst:country:85633159","country_a":"GBR","macroregion":"England","macroregion_gid":"whosonfirst:macroregion:404227469","region":"Lancashire","region_gid":"whosonfirst:region:85683853","region_a":"LAN","locality":"Lancaster","locality_gid":"whosonfirst:locality:101873271","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"Stable End Curio's, Lancaster, England, United Kingdom"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-2.79931,54.048391]},"properties":{"id":"node/6592154385","gid":"openstreetmap:venue:node/6592154385","layer":"venue","source":"openstreetmap","source_id":"node/6592154385","name":"Diggles","housenumber":"5-7","street":"Ffrances Passage","postalcode":"LA1 1UG","confidence":0.8,"distance":0.018,"accuracy":"point","country":"United Kingdom","country_gid":"whosonfirst:country:85633159","country_a":"GBR","macroregion":"England","macroregion_gid":"whosonfirst:macroregion:404227469","region":"Lancashire","region_gid":"whosonfirst:region:85683853","region_a":"LAN","locality":"Lancaster","locality_gid":"whosonfirst:locality:101873271","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"Diggles, Lancaster, England, United Kingdom"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-2.79931,54.048391]},"properties":{"id":"node/6592154385","gid":"openstreetmap:address:node/6592154385","layer":"address","source":"openstreetmap","source_id":"node/6592154385","name":"5-7 Ffrances Passage","housenumber":"5-7","street":"Ffrances Passage","postalcode":"LA1 1UG","confidence":0.8,"distance":0.018,"accuracy":"point","country":"United Kingdom","country_gid":"whosonfirst:country:85633159","country_a":"GBR","macroregion":"England","macroregion_gid":"whosonfirst:macroregion:404227469","region":"Lancashire","region_gid":"whosonfirst:region:85683853","region_a":"LAN","locality":"Lancaster","locality_gid":"whosonfirst:locality:101873271","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"5-7 Ffrances Passage, Lancaster, England, United Kingdom"}}],"bbox":[-2.79931,54.0483534,-2.798818,54.0485068]}";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:6384:"{"geocoding":{"version":"0.2","attribution":"https://geocode.earth/guidelines","query":{"size":5,"private":false,"point.lat":49.1390924,"point.lon":1.6572462,"boundary.circle.lat":49.1390924,"boundary.circle.lon":1.6572462,"lang":{"name":"English","iso6391":"en","iso6393":"eng","defaulted":true},"querySize":10},"engine":{"name":"Pelias","author":"Mapzen","version":"1.0"},"timestamp":1569514975455},"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[1.657246,49.139092]},"properties":{"id":"node/1564292039","gid":"openstreetmap:venue:node/1564292039","layer":"venue","source":"openstreetmap","source_id":"node/1564292039","name":"Les Jardins d'Épicure","confidence":1,"distance":0,"accuracy":"point","country":"France","country_gid":"whosonfirst:country:85633147","country_a":"FRA","macroregion":"Ile-of-France","macroregion_gid":"whosonfirst:macroregion:404227465","macroregion_a":"IF","region":"Val-d'Oise","region_gid":"whosonfirst:region:85683451","region_a":"VO","macrocounty":"arrondissement of Pontoise","macrocounty_gid":"whosonfirst:macrocounty:404228193","county":"Magny-en-Vexin","county_gid":"whosonfirst:county:102067333","localadmin":"Bray-Et-Lu","localadmin_gid":"whosonfirst:localadmin:404408311","locality":"Bray-et-Lû","locality_gid":"whosonfirst:locality:1125876391","neighbourhood":"Bus-Saint-Rémy","neighbourhood_gid":"whosonfirst:neighbourhood:1360698119","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"Les Jardins d'Épicure, Bray-et-Lû, France"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1.657114,49.13946]},"properties":{"id":"fr/val_doise:70360ba1564d68eb","gid":"openaddresses:address:fr/val_doise:70360ba1564d68eb","layer":"address","source":"openaddresses","source_id":"fr/val_doise:70360ba1564d68eb","name":"16 Grande Rue","housenumber":"16","street":"Grande Rue","confidence":0.8,"distance":0.042,"accuracy":"point","country":"France","country_gid":"whosonfirst:country:85633147","country_a":"FRA","macroregion":"Ile-of-France","macroregion_gid":"whosonfirst:macroregion:404227465","macroregion_a":"IF","region":"Val-d'Oise","region_gid":"whosonfirst:region:85683451","region_a":"VO","macrocounty":"arrondissement of Pontoise","macrocounty_gid":"whosonfirst:macrocounty:404228193","county":"Magny-en-Vexin","county_gid":"whosonfirst:county:102067333","localadmin":"Bray-Et-Lu","localadmin_gid":"whosonfirst:localadmin:404408311","locality":"Bray-et-Lû","locality_gid":"whosonfirst:locality:1125876391","neighbourhood":"Bus-Saint-Rémy","neighbourhood_gid":"whosonfirst:neighbourhood:1360698119","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"16 Grande Rue, Bray-et-Lû, France"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1.658166,49.139008]},"properties":{"id":"fr/val_doise:a1d4989dfd60274d","gid":"openaddresses:address:fr/val_doise:a1d4989dfd60274d","layer":"address","source":"openaddresses","source_id":"fr/val_doise:a1d4989dfd60274d","name":"2 Rue Des Pres","housenumber":"2","street":"Rue Des Pres","confidence":0.8,"distance":0.068,"accuracy":"point","country":"France","country_gid":"whosonfirst:country:85633147","country_a":"FRA","macroregion":"Ile-of-France","macroregion_gid":"whosonfirst:macroregion:404227465","macroregion_a":"IF","region":"Val-d'Oise","region_gid":"whosonfirst:region:85683451","region_a":"VO","macrocounty":"arrondissement of Pontoise","macrocounty_gid":"whosonfirst:macrocounty:404228193","county":"Magny-en-Vexin","county_gid":"whosonfirst:county:102067333","localadmin":"Bray-Et-Lu","localadmin_gid":"whosonfirst:localadmin:404408311","locality":"Bray-et-Lû","locality_gid":"whosonfirst:locality:1125876391","neighbourhood":"Bus-Saint-Rémy","neighbourhood_gid":"whosonfirst:neighbourhood:1360698119","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"2 Rue Des Pres, Bray-et-Lû, France"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1.658165,49.139241]},"properties":{"id":"fr/val_doise:ff284c2f4f90a313","gid":"openaddresses:address:fr/val_doise:ff284c2f4f90a313","layer":"address","source":"openaddresses","source_id":"fr/val_doise:ff284c2f4f90a313","name":"3 Rue Des Pres","housenumber":"3","street":"Rue Des Pres","confidence":0.8,"distance":0.069,"accuracy":"point","country":"France","country_gid":"whosonfirst:country:85633147","country_a":"FRA","macroregion":"Ile-of-France","macroregion_gid":"whosonfirst:macroregion:404227465","macroregion_a":"IF","region":"Val-d'Oise","region_gid":"whosonfirst:region:85683451","region_a":"VO","macrocounty":"arrondissement of Pontoise","macrocounty_gid":"whosonfirst:macrocounty:404228193","county":"Magny-en-Vexin","county_gid":"whosonfirst:county:102067333","localadmin":"Bray-Et-Lu","localadmin_gid":"whosonfirst:localadmin:404408311","locality":"Bray-et-Lû","locality_gid":"whosonfirst:locality:1125876391","neighbourhood":"Bus-Saint-Rémy","neighbourhood_gid":"whosonfirst:neighbourhood:1360698119","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"3 Rue Des Pres, Bray-et-Lû, France"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[1.657443,49.1397]},"properties":{"id":"fr/val_doise:e0ab41d7033ce285","gid":"openaddresses:address:fr/val_doise:e0ab41d7033ce285","layer":"address","source":"openaddresses","source_id":"fr/val_doise:e0ab41d7033ce285","name":"23 Grande Rue","housenumber":"23","street":"Grande Rue","confidence":0.8,"distance":0.069,"accuracy":"point","country":"France","country_gid":"whosonfirst:country:85633147","country_a":"FRA","macroregion":"Ile-of-France","macroregion_gid":"whosonfirst:macroregion:404227465","macroregion_a":"IF","region":"Val-d'Oise","region_gid":"whosonfirst:region:85683451","region_a":"VO","macrocounty":"arrondissement of Pontoise","macrocounty_gid":"whosonfirst:macrocounty:404228193","county":"Magny-en-Vexin","county_gid":"whosonfirst:county:102067333","localadmin":"Bray-Et-Lu","localadmin_gid":"whosonfirst:localadmin:404408311","locality":"Bray-et-Lû","locality_gid":"whosonfirst:locality:1125876391","neighbourhood":"Bus-Saint-Rémy","neighbourhood_gid":"whosonfirst:neighbourhood:1360698119","continent":"Europe","continent_gid":"whosonfirst:continent:102191581","label":"23 Grande Rue, Bray-et-Lû, France"}}],"bbox":[1.657114,49.139008,1.658166,49.1397]}";

0 commit comments

Comments
 (0)