Skip to content

Commit 201e54f

Browse files
mariusasensijbelien
authored andcommitted
Here provider: additionalData field. (#956)
* Here Provider: Special field "additionalData" in provider address model and fill adminLevels of Address base model with the data from that field. (https://developer.here.com/documentation/geocoder/topics/resource-type-response-geocode.html#resource-type-response-geocode__address) * Here Provider: Add cached response for test. * Here provider: additionalData field in adminlevels without restrictions * Here provider: New extra filters: country, state, county and city * Fixes code style. * Additional Data filters for Here provider * Additional Data filters for Here provider - Style * Additional Data filters for Here provider - Cached responses * Additional Data filters for Here provider - Cached responses
1 parent 37a9a78 commit 201e54f

File tree

37 files changed

+472
-2
lines changed

37 files changed

+472
-2
lines changed

src/Provider/Here/Here.php

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
namespace Geocoder\Provider\Here;
1414

1515
use Geocoder\Collection;
16+
use Geocoder\Exception\InvalidArgument;
1617
use Geocoder\Exception\InvalidCredentials;
18+
use Geocoder\Exception\QuotaExceeded;
1719
use Geocoder\Exception\UnsupportedOperation;
1820
use Geocoder\Model\AddressBuilder;
1921
use Geocoder\Model\AddressCollection;
@@ -94,10 +96,97 @@ public function geocodeQuery(GeocodeQuery $query): Collection
9496

9597
$url = sprintf($this->useCIT ? self::GEOCODE_CIT_ENDPOINT_URL : self::GEOCODE_ENDPOINT_URL, $this->appId, $this->appCode, rawurlencode($query->getText()));
9698

99+
if (null !== $query->getData('country')) {
100+
$url = sprintf('%s&country=%s', $url, rawurlencode($query->getData('country')));
101+
}
102+
103+
if (null !== $query->getData('state')) {
104+
$url = sprintf('%s&state=%s', $url, rawurlencode($query->getData('state')));
105+
}
106+
107+
if (null !== $query->getData('county')) {
108+
$url = sprintf('%s&county=%s', $url, rawurlencode($query->getData('county')));
109+
}
110+
111+
if (null !== $query->getData('city')) {
112+
$url = sprintf('%s&city=%s', $url, rawurlencode($query->getData('city')));
113+
}
114+
97115
if (null !== $query->getLocale()) {
98116
$url = sprintf('%s&language=%s', $url, $query->getLocale());
99117
}
100118

119+
$additionalDataParam = [];
120+
if (null !== $query->getData('CrossingStreets')) {
121+
$additionalDataParam['CrossingStreets'] = $query->getData('CrossingStreets');
122+
}
123+
124+
if (null !== $query->getData('PreserveUnitDesignators')) {
125+
$additionalDataParam['PreserveUnitDesignators'] = $query->getData('PreserveUnitDesignators');
126+
}
127+
128+
if (null !== $query->getData('Country2')) {
129+
$additionalDataParam['Country2'] = $query->getData('Country2');
130+
}
131+
132+
if (null !== $query->getData('IncludeChildPOIs')) {
133+
$additionalDataParam['IncludeChildPOIs'] = $query->getData('IncludeChildPOIs');
134+
}
135+
136+
if (null !== $query->getData('IncludeRoutingInformation')) {
137+
$additionalDataParam['IncludeRoutingInformation'] = $query->getData('IncludeRoutingInformation');
138+
}
139+
140+
if (null !== $query->getData('AdditionalAddressProvider')) {
141+
$additionalDataParam['AdditionalAddressProvider'] = $query->getData('AdditionalAddressProvider');
142+
}
143+
144+
if (null !== $query->getData('HouseNumberMode')) {
145+
$additionalDataParam['HouseNumberMode'] = $query->getData('HouseNumberMode');
146+
}
147+
148+
if (null !== $query->getData('FlexibleAdminValues')) {
149+
$additionalDataParam['FlexibleAdminValues'] = $query->getData('FlexibleAdminValues');
150+
}
151+
152+
if (null !== $query->getData('IntersectionSnapTolerance')) {
153+
$additionalDataParam['IntersectionSnapTolerance'] = $query->getData('IntersectionSnapTolerance');
154+
}
155+
156+
if (null !== $query->getData('AddressRangeSqueezeOffset')) {
157+
$additionalDataParam['AddressRangeSqueezeOffset'] = $query->getData('AddressRangeSqueezeOffset');
158+
}
159+
160+
if (null !== $query->getData('AddressRangeSqueezeFactor')) {
161+
$additionalDataParam['AddressRangeSqueezeFactor'] = $query->getData('AddressRangeSqueezeFactor');
162+
}
163+
164+
if (null !== $query->getData('IncludeShapeLevel')) {
165+
$additionalDataParam['IncludeShapeLevel'] = $query->getData('IncludeShapeLevel');
166+
}
167+
168+
if (null !== $query->getData('RestrictLevel')) {
169+
$additionalDataParam['RestrictLevel'] = $query->getData('RestrictLevel');
170+
}
171+
172+
if (null !== $query->getData('SuppressStreetType')) {
173+
$additionalDataParam['SuppressStreetType'] = $query->getData('SuppressStreetType');
174+
}
175+
176+
if (null !== $query->getData('NormalizeNames')) {
177+
$additionalDataParam['NormalizeNames'] = $query->getData('NormalizeNames');
178+
}
179+
180+
if (null !== $query->getData('IncludeMicroPointAddresses')) {
181+
$additionalDataParam['IncludeMicroPointAddresses'] = $query->getData('IncludeMicroPointAddresses');
182+
}
183+
184+
$additionalDataParam['IncludeShapeLevel'] = 'country';
185+
186+
if (!empty($additionalDataParam)) {
187+
$url = sprintf('%s&additionaldata=%s', $url, $this->serializeComponents($additionalDataParam));
188+
}
189+
101190
return $this->executeQuery($url, $query->getLimit());
102191
}
103192

@@ -116,7 +205,7 @@ public function reverseQuery(ReverseQuery $query): Collection
116205
* @param string $url
117206
* @param int $limit
118207
*
119-
* @return \Geocoder\Collection
208+
* @return Collection
120209
*/
121210
private function executeQuery(string $url, int $limit): Collection
122211
{
@@ -157,12 +246,23 @@ private function executeQuery(string $url, int $limit): Collection
157246
$builder->setPostalCode($location['Address']['PostalCode'] ?? null);
158247
$builder->setLocality($location['Address']['City'] ?? null);
159248
$builder->setSubLocality($location['Address']['District'] ?? null);
160-
$builder->setCountry($location['Address']['AdditionalData'][0]['value'] ?? null);
161249
$builder->setCountryCode($location['Address']['Country'] ?? null);
162250

251+
// The name of the country can be found in the AdditionalData.
252+
$additionalData = $location['Address']['AdditionalData'] ?? null;
253+
if (!empty($additionalData)) {
254+
$builder->setCountry($additionalData[array_search('CountryName', array_column($additionalData, 'key'))]['value'] ?? null);
255+
}
256+
257+
// There may be a second AdditionalData. For example if "IncludeRoutingInformation" parameter is added
258+
$extraAdditionalData = $loc['AdditionalData'] ?? [];
259+
260+
/** @var HereAddress $address */
163261
$address = $builder->build(HereAddress::class);
164262
$address = $address->withLocationId($location['LocationId']);
165263
$address = $address->withLocationType($location['LocationType']);
264+
$address = $address->withAdditionalData(array_merge($additionalData, $extraAdditionalData));
265+
$address = $address->withShape($location['Shape'] ?? null);
166266
$results[] = $address;
167267

168268
if (count($results) >= $limit) {
@@ -180,4 +280,18 @@ public function getName(): string
180280
{
181281
return 'Here';
182282
}
283+
284+
/**
285+
* Serialize the component query parameter.
286+
*
287+
* @param array $components
288+
*
289+
* @return string
290+
*/
291+
private function serializeComponents(array $components): string
292+
{
293+
return implode(';', array_map(function ($name, $value) {
294+
return sprintf('%s,%s', $name, $value);
295+
}, array_keys($components), $components));
296+
}
183297
}

src/Provider/Here/Model/HereAddress.php

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ final class HereAddress extends Address
3434
*/
3535
private $locationName;
3636

37+
/**
38+
* @var array|null
39+
*/
40+
private $additionalData;
41+
42+
/**
43+
* @var array|null
44+
*/
45+
private $shape;
46+
3747
/**
3848
* @return null|string
3949
*/
@@ -96,4 +106,118 @@ public function withLocationName(string $locationName = null): self
96106

97107
return $new;
98108
}
109+
110+
/**
111+
* @return null|array
112+
*/
113+
public function getAdditionalData()
114+
{
115+
return $this->additionalData;
116+
}
117+
118+
/**
119+
* @param null|array $additionalData
120+
*
121+
* @return HereAddress
122+
*/
123+
public function withAdditionalData(array $additionalData = null): self
124+
{
125+
$new = clone $this;
126+
127+
foreach ($additionalData as $data) {
128+
$new = $new->addAdditionalData($data['key'], $data['value']);
129+
}
130+
131+
return $new;
132+
}
133+
134+
/**
135+
* @param string $name
136+
* @param null|mixed $value
137+
*
138+
* @return HereAddress
139+
*/
140+
public function addAdditionalData(string $name, $value = null): self
141+
{
142+
$new = clone $this;
143+
$new->additionalData[$name] = $value;
144+
145+
return $new;
146+
}
147+
148+
/**
149+
* @param string $name
150+
* @param null|mixed $default
151+
*
152+
* @return mixed
153+
*/
154+
public function getAdditionalDataValue(string $name, $default = null)
155+
{
156+
if ($this->hasAdditionalDataValue($name)) {
157+
return $this->additionalData[$name];
158+
}
159+
160+
return $default;
161+
}
162+
163+
/**
164+
* @param string $name
165+
*
166+
* @return bool
167+
*/
168+
public function hasAdditionalDataValue(string $name): bool
169+
{
170+
return array_key_exists($name, $this->additionalData);
171+
}
172+
173+
/**
174+
* @param array|null $shape
175+
*
176+
* @return HereAddress
177+
*/
178+
public function withShape(array $shape = null): self
179+
{
180+
$new = clone $this;
181+
182+
if (!empty($shape)) {
183+
foreach ($shape as $key => $data) {
184+
$new = $new->addShape($key, $data);
185+
}
186+
}
187+
188+
return $new;
189+
}
190+
191+
/**
192+
* @param string $name
193+
* @param null|mixed $value
194+
*
195+
* @return HereAddress
196+
*/
197+
public function addShape(string $name, $value = null): self
198+
{
199+
$new = clone $this;
200+
$new->shape[$name] = $value;
201+
202+
return $new;
203+
}
204+
205+
public function getShapeValue(string $name, $default = null)
206+
{
207+
if ($this->hasShapeValue($name)) {
208+
return $this->shape[$name];
209+
}
210+
211+
return $default;
212+
}
213+
214+
/**
215+
* @param string $name
216+
*
217+
* @return bool
218+
*/
219+
public function hasShapeValue(string $name): bool
220+
{
221+
return array_key_exists($name, $this->shape);
222+
}
99223
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:813:"{"Response":{"MetaInfo":{"Timestamp":"2019-05-17T19:29:02.446+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"city","MatchQuality":{"County":1.0,"City":1.0},"Location":{"LocationId":"NT_KtE5o12jR0XYcWkzHeISkC","LocationType":"area","DisplayPosition":{"Latitude":42.30782,"Longitude":2.97809},"NavigationPosition":[{"Latitude":42.30782,"Longitude":2.97809}],"MapView":{"TopLeft":{"Latitude":42.33181,"Longitude":2.9432},"BottomRight":{"Latitude":42.27725,"Longitude":2.99618}},"Address":{"Label":"Cabanes, Catalunya, Espanya","Country":"ESP","State":"Catalunya","County":"Girona","City":"Cabanes","PostalCode":"17761","AdditionalData":[{"value":"Espanya","key":"CountryName"},{"value":"Catalunya","key":"StateName"},{"value":"Girona","key":"CountyName"}]}}}]}]}}";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:908:"{"Response":{"MetaInfo":{"Timestamp":"2019-05-14T13:01:20.425+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"district","MatchQuality":{"Country":1.0,"City":1.0,"District":1.0},"Location":{"LocationId":"NT_TzyupfxmTFN0Rh1TXEMqSA","LocationType":"area","DisplayPosition":{"Latitude":41.37854,"Longitude":2.01196},"NavigationPosition":[{"Latitude":41.37854,"Longitude":2.01196}],"MapView":{"TopLeft":{"Latitude":41.39203,"Longitude":1.99398},"BottomRight":{"Latitude":41.36505,"Longitude":2.02994}},"Address":{"Label":"Sant Roc, Santa Coloma de Cervelló, Catalunya, Espanya","Country":"ESP","State":"Catalunya","County":"Barcelona","City":"Santa Coloma de Cervelló","District":"Sant Roc","PostalCode":"08690","AdditionalData":[{"value":"Espanya","key":"CountryName"},{"value":"Catalunya","key":"StateName"},{"value":"Barcelona","key":"CountyName"}]}}}]}]}}";

src/Provider/Here/Tests/.cached_responses/geocoder.api.here.com_229c421e5db81a41b4f0de532b9195ca167839fc

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:823:"{"Response":{"MetaInfo":{"Timestamp":"2019-05-17T18:50:14.499+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"city","MatchQuality":{"Country":1.0,"City":1.0},"Location":{"LocationId":"NT_rEmofR12M9KayEWS0Xvk6C","LocationType":"area","DisplayPosition":{"Latitude":41.38804,"Longitude":2.17001},"NavigationPosition":[{"Latitude":41.38804,"Longitude":2.17001}],"MapView":{"TopLeft":{"Latitude":41.4686,"Longitude":2.05238},"BottomRight":{"Latitude":41.3204,"Longitude":2.22729}},"Address":{"Label":"Barcelona, Catalunya, Espanya","Country":"ESP","State":"Catalunya","County":"Barcelona","City":"Barcelona","PostalCode":"08007","AdditionalData":[{"value":"Espanya","key":"CountryName"},{"value":"Catalunya","key":"StateName"},{"value":"Barcelona","key":"CountyName"}]}}}]}]}}";

src/Provider/Here/Tests/.cached_responses/geocoder.api.here.com_36a5582aaebc9d6af6dc1a7f777ccc81567d734c

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

src/Provider/Here/Tests/.cached_responses/geocoder.api.here.com_5231ce19ffb0c5b984c6dcb36d9aaca333306f9b

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:888:"{"Response":{"MetaInfo":{"Timestamp":"2019-05-17T18:59:41.886+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"street","MatchQuality":{"City":1.0,"Street":[1.0]},"Location":{"LocationId":"NT_KB88EDyK54GvYS-jPUrObB","LocationType":"address","DisplayPosition":{"Latitude":41.41829,"Longitude":1.99677},"NavigationPosition":[{"Latitude":41.41829,"Longitude":1.99677}],"MapView":{"TopLeft":{"Latitude":41.42741,"Longitude":1.99481},"BottomRight":{"Latitude":41.41521,"Longitude":1.99817}},"Address":{"Label":"Carrer de Barcelona, 08780 Pallejà (Barcelona), Espanya","Country":"ESP","State":"Catalunya","County":"Barcelona","City":"Pallejà","Street":"Carrer de Barcelona","PostalCode":"08780","AdditionalData":[{"value":"Espanya","key":"CountryName"},{"value":"Catalunya","key":"StateName"},{"value":"Barcelona","key":"CountyName"}]}}}]}]}}";

src/Provider/Here/Tests/.cached_responses/geocoder.api.here.com_568e9a86ad0ea25a7d96879480b8d739a407ddf4

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)