Skip to content

Commit 1521965

Browse files
committed
Merge pull request #445 from nicolassing/opencage
[OpenCage] Locality
2 parents c5cb0e2 + 29b5743 commit 1521965

File tree

3 files changed

+192
-21
lines changed

3 files changed

+192
-21
lines changed

src/Geocoder/Provider/OpenCage.php

+74-21
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*
88
* @license MIT License
99
*/
10-
1110
namespace Geocoder\Provider;
1211

1312
use Geocoder\Exception\InvalidCredentials;
@@ -53,7 +52,7 @@ public function __construct(HttpAdapterInterface $adapter, $apiKey, $useSsl = fa
5352
}
5453

5554
/**
56-
* {@inheritDoc}
55+
* {@inheritdoc}
5756
*/
5857
public function geocode($address)
5958
{
@@ -66,31 +65,32 @@ public function geocode($address)
6665
throw new UnsupportedOperation('The OpenCage provider does not support IP addresses, only street addresses.');
6766
}
6867

69-
$query = sprintf(self::GEOCODE_ENDPOINT_URL, $this->scheme, $this->apiKey, urlencode($address), $this->getLimit() );
68+
$query = sprintf(self::GEOCODE_ENDPOINT_URL, $this->scheme, $this->apiKey, urlencode($address), $this->getLimit());
7069

7170
return $this->executeQuery($query);
7271
}
7372

7473
/**
75-
* {@inheritDoc}
74+
* {@inheritdoc}
7675
*/
7776
public function reverse($latitude, $longitude)
7877
{
79-
$address = sprintf("%f, %f", $latitude, $longitude);
78+
$address = sprintf('%f, %f', $latitude, $longitude);
8079

8180
return $this->geocode($address);
8281
}
8382

8483
/**
85-
* {@inheritDoc}
84+
* {@inheritdoc}
8685
*/
8786
public function getName()
8887
{
8988
return 'opencage';
9089
}
9190

9291
/**
93-
* @param string $query
92+
* @param $query
93+
* @return \Geocoder\Model\AddressCollection
9494
*/
9595
private function executeQuery($query)
9696
{
@@ -106,7 +106,7 @@ private function executeQuery($query)
106106

107107
$json = json_decode($content, true);
108108

109-
if (!isset($json['total_results']) || $json['total_results'] == 0 ) {
109+
if (!isset($json['total_results']) || $json['total_results'] == 0) {
110110
throw new NoResult(sprintf('Could not find results for query "%s".', $query));
111111
}
112112

@@ -122,9 +122,9 @@ private function executeQuery($query)
122122
if (isset($location['bounds'])) {
123123
$bounds = [
124124
'south' => $location['bounds']['southwest']['lat'],
125-
'west' => $location['bounds']['southwest']['lng'],
125+
'west' => $location['bounds']['southwest']['lng'],
126126
'north' => $location['bounds']['northeast']['lat'],
127-
'east' => $location['bounds']['northeast']['lng'],
127+
'east' => $location['bounds']['northeast']['lng'],
128128
];
129129
}
130130

@@ -138,21 +138,74 @@ private function executeQuery($query)
138138
}
139139

140140
$results[] = array_merge($this->getDefaults(), array(
141-
'latitude' => $location['geometry']['lat'],
142-
'longitude' => $location['geometry']['lng'],
143-
'bounds' => $bounds ?: [],
141+
'latitude' => $location['geometry']['lat'],
142+
'longitude' => $location['geometry']['lng'],
143+
'bounds' => $bounds ?: [],
144144
'streetNumber' => isset($comp['house_number']) ? $comp['house_number'] : null,
145-
'streetName' => isset($comp['road'] ) ? $comp['road'] : null,
146-
'subLocality' => isset($comp['suburb'] ) ? $comp['suburb'] : null,
147-
'locality' => isset($comp['city'] ) ? $comp['city'] : null,
148-
'postalCode' => isset($comp['postcode'] ) ? $comp['postcode'] : null,
149-
'adminLevels' => $adminLevels,
150-
'country' => isset($comp['country'] ) ? $comp['country'] : null,
151-
'countryCode' => isset($comp['country_code']) ? strtoupper($comp['country_code']) : null,
152-
'timezone' => isset($location['annotations']['timezone']['name']) ? $location['annotations']['timezone']['name'] : null,
145+
'streetName' => $this->guessStreetName($comp),
146+
'subLocality' => $this->guessSubLocality($comp),
147+
'locality' => $this->guessLocality($comp),
148+
'postalCode' => isset($comp['postcode']) ? $comp['postcode'] : null,
149+
'adminLevels' => $adminLevels,
150+
'country' => isset($comp['country']) ? $comp['country'] : null,
151+
'countryCode' => isset($comp['country_code']) ? strtoupper($comp['country_code']) : null,
152+
'timezone' => isset($location['annotations']['timezone']['name']) ? $location['annotations']['timezone']['name'] : null,
153153
));
154154
}
155155

156156
return $this->returnResults($results);
157157
}
158+
159+
/**
160+
* @param array $components
161+
*
162+
* @return null|string
163+
*/
164+
protected function guessLocality(array $components)
165+
{
166+
$localityKeys = array('city', 'town' , 'village', 'hamlet');
167+
168+
return $this->guessBestComponent($components, $localityKeys);
169+
}
170+
171+
/**
172+
* @param array $components
173+
*
174+
* @return null|string
175+
*/
176+
protected function guessStreetName(array $components)
177+
{
178+
$streetNameKeys = array('road', 'street', 'street_name', 'residential');
179+
180+
return $this->guessBestComponent($components, $streetNameKeys);
181+
}
182+
183+
/**
184+
* @param array $components
185+
*
186+
* @return null|string
187+
*/
188+
protected function guessSubLocality(array $components)
189+
{
190+
$subLocalityKeys = array('suburb', 'neighbourhood', 'city_district');
191+
192+
return $this->guessBestComponent($components, $subLocalityKeys);
193+
}
194+
195+
/**
196+
* @param array $components
197+
* @param array $keys
198+
*
199+
* @return null|string
200+
*/
201+
protected function guessBestComponent(array $components, array $keys)
202+
{
203+
foreach ($keys as $key) {
204+
if (isset($components[$key]) && !empty($components[$key])) {
205+
return $components[$key];
206+
}
207+
}
208+
209+
return null;
210+
}
158211
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
s:2884:"{
2+
"licenses" : [
3+
{
4+
"name" : "CC-BY-SA",
5+
"url" : "http://creativecommons.org/licenses/by-sa/3.0/"
6+
},
7+
{
8+
"name" : "ODbL",
9+
"url" : "http://opendatacommons.org/licenses/odbl/summary/"
10+
}
11+
],
12+
"rate" : {
13+
"limit" : 2500,
14+
"remaining" : 2496,
15+
"reset" : 1439856000
16+
},
17+
"results" : [
18+
{
19+
"annotations" : {
20+
"DMS" : {
21+
"lat" : "49\u00b0 8' 20.73264'' N",
22+
"lng" : "1\u00b0 39' 26.08632'' E"
23+
},
24+
"MGRS" : "31UDQ0206243786",
25+
"Maidenhead" : "JN09td83uj",
26+
"Mercator" : {
27+
"x" : 184483.803,
28+
"y" : 6266161.941
29+
},
30+
"OSM" : {
31+
"url" : "http://www.openstreetmap.org/?mlat=49.13909&mlon=1.65725#map=17/49.13909/1.65725"
32+
},
33+
"callingcode" : 33,
34+
"geohash" : "u09pt9qzbwsrft58uhm6",
35+
"sun" : {
36+
"rise" : {
37+
"astronomical" : 1439779140,
38+
"civil" : 1439784780,
39+
"nautical" : 1439782200
40+
},
41+
"set" : {
42+
"astronomical" : 1439845980,
43+
"civil" : 1439840400,
44+
"nautical" : 1439843040
45+
}
46+
},
47+
"timezone" : {
48+
"name" : "Europe/Paris",
49+
"now_in_dst" : 1,
50+
"offset_sec" : 7200,
51+
"offset_string" : 200,
52+
"short_name" : "CEST"
53+
},
54+
"what3words" : {
55+
"words" : "cocotier.maniable.arabesque"
56+
}
57+
},
58+
"bounds" : {
59+
"northeast" : {
60+
"lat" : 49.1391424,
61+
"lng" : 1.6572962
62+
},
63+
"southwest" : {
64+
"lat" : 49.1390424,
65+
"lng" : 1.6571962
66+
}
67+
},
68+
"components" : {
69+
"country" : "France",
70+
"country_code" : "fr",
71+
"county" : "Pontoise",
72+
"hotel" : "Les Jardins d'\u00c9picure",
73+
"postcode" : "95710",
74+
"road" : "Grande Rue",
75+
"state" : "\u00cele-de-France",
76+
"village" : "Bray-et-L\u00fb"
77+
},
78+
"confidence" : 10,
79+
"formatted" : "Les Jardins d'\u00c9picure, Grande Rue, 95710 Bray-et-L\u00fb, France",
80+
"geometry" : {
81+
"lat" : 49.1390924,
82+
"lng" : 1.6572462
83+
}
84+
}
85+
],
86+
"status" : {
87+
"code" : 200,
88+
"message" : "OK"
89+
},
90+
"stay_informed" : {
91+
"blog" : "http://blog.opencagedata.com",
92+
"twitter" : "https://twitter.com/opencagedata"
93+
},
94+
"thanks" : "For using an OpenCage Data API",
95+
"timestamp" : {
96+
"created_http" : "Mon, 17 Aug 2015 14:29:15 GMT",
97+
"created_unix" : 1439821755
98+
},
99+
"total_results" : 1
100+
}";

tests/Geocoder/Tests/Provider/OpenCageTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,24 @@ public function testReverseWithRealCoordinates()
127127
$this->assertEquals('Europe/London' , $result->getTimezone());
128128
}
129129

130+
public function testReverseWithVillage()
131+
{
132+
if (!isset($_SERVER['OPENCAGE_API_KEY'])) {
133+
$this->markTestSkipped('You need to configure the OPENCAGE_API_KEY value in phpunit.xml');
134+
}
135+
136+
$provider = new OpenCage($this->getAdapter($_SERVER['OPENCAGE_API_KEY']), $_SERVER['OPENCAGE_API_KEY']);
137+
$results = $provider->reverse(49.1390924, 1.6572462);
138+
139+
$this->assertInstanceOf('Geocoder\Model\AddressCollection', $results);
140+
$this->assertCount(1, $results);
141+
142+
/** @var \Geocoder\Model\Address $result */
143+
$result = $results->first();
144+
$this->assertInstanceOf('\Geocoder\Model\Address', $result);
145+
$this->assertEquals('Bray-et-Lû', $result->getLocality());
146+
}
147+
130148
public function testGeocodeWithCity()
131149
{
132150
if (!isset($_SERVER['OPENCAGE_API_KEY'])) {

0 commit comments

Comments
 (0)