17
17
use Geocoder \Exception \QuotaExceeded ;
18
18
use Geocoder \Exception \UnsupportedOperation ;
19
19
use Geocoder \Http \Provider \AbstractHttpProvider ;
20
- use Geocoder \Model \Address ;
20
+ use Geocoder \Model \AddressBuilder ;
21
21
use Geocoder \Model \AddressCollection ;
22
+ use Geocoder \Provider \Pelias \Model \PeliasAddress ;
22
23
use Geocoder \Provider \Provider ;
23
24
use Geocoder \Query \GeocodeQuery ;
24
25
use Geocoder \Query \ReverseQuery ;
@@ -60,14 +61,16 @@ protected function getGeocodeQueryUrl(GeocodeQuery $query, array $query_data = [
60
61
$ data = [
61
62
'text ' => $ address ,
62
63
'size ' => $ query ->getLimit (),
64
+ 'layers ' => null !== $ query ->getData ('layers ' ) ? implode (', ' , $ query ->getData ('layers ' )) : null ,
65
+ 'boundary.country ' => null !== $ query ->getData ('boundary.country ' ) ? implode (', ' , $ query ->getData ('boundary.country ' )) : null ,
63
66
];
64
67
65
68
return sprintf ('%s/search?%s ' , $ this ->root , http_build_query (array_merge ($ data , $ query_data )));
66
69
}
67
70
68
71
public function geocodeQuery (GeocodeQuery $ query ): Collection
69
72
{
70
- return $ this ->executeQuery ($ this ->getGeocodeQueryUrl ($ query ));
73
+ return $ this ->executeQuery ($ this ->getGeocodeQueryUrl ($ query ), $ query -> getLocale () );
71
74
}
72
75
73
76
/**
@@ -85,24 +88,32 @@ protected function getReverseQueryUrl(ReverseQuery $query, array $query_data = [
85
88
'point.lat ' => $ latitude ,
86
89
'point.lon ' => $ longitude ,
87
90
'size ' => $ query ->getLimit (),
91
+ 'layers ' => null !== $ query ->getData ('layers ' ) ? implode (', ' , $ query ->getData ('layers ' )) : null ,
92
+ 'boundary.country ' => null !== $ query ->getData ('boundary.country ' ) ? implode (', ' , $ query ->getData ('boundary.country ' )) : null ,
88
93
];
89
94
90
95
return sprintf ('%s/reverse?%s ' , $ this ->root , http_build_query (array_merge ($ data , $ query_data )));
91
96
}
92
97
93
98
public function reverseQuery (ReverseQuery $ query ): Collection
94
99
{
95
- return $ this ->executeQuery ($ this ->getReverseQueryUrl ($ query ));
100
+ return $ this ->executeQuery ($ this ->getReverseQueryUrl ($ query ), $ query -> getLocale () );
96
101
}
97
102
98
103
public function getName (): string
99
104
{
100
105
return 'pelias ' ;
101
106
}
102
107
103
- protected function executeQuery (string $ url ): AddressCollection
108
+ protected function executeQuery (string $ url, ? string $ locale ): AddressCollection
104
109
{
105
- $ content = $ this ->getUrlContents ($ url );
110
+ $ headers = [];
111
+ if (null !== $ locale ) {
112
+ $ headers ['Accept-Language ' ] = $ locale ;
113
+ }
114
+
115
+ $ request = $ this ->createRequest ('GET ' , $ url , $ headers );
116
+ $ content = $ this ->getParsedResponse ($ request );
106
117
$ json = json_decode ($ content , true );
107
118
108
119
if (isset ($ json ['meta ' ])) {
@@ -124,53 +135,53 @@ protected function executeQuery(string $url): AddressCollection
124
135
return new AddressCollection ([]);
125
136
}
126
137
127
- $ locations = $ json ['features ' ];
138
+ $ features = $ json ['features ' ];
128
139
129
- if (empty ($ locations )) {
140
+ if (empty ($ features )) {
130
141
return new AddressCollection ([]);
131
142
}
132
143
133
144
$ results = [];
134
- foreach ($ locations as $ location ) {
135
- if (isset ($ location ['bbox ' ])) {
136
- $ bounds = [
137
- 'south ' => $ location ['bbox ' ][3 ],
138
- 'west ' => $ location ['bbox ' ][2 ],
139
- 'north ' => $ location ['bbox ' ][1 ],
140
- 'east ' => $ location ['bbox ' ][0 ],
141
- ];
142
- } else {
143
- $ bounds = [
144
- 'south ' => null ,
145
- 'west ' => null ,
146
- 'north ' => null ,
147
- 'east ' => null ,
148
- ];
145
+ foreach ($ features as $ feature ) {
146
+ $ builder = new AddressBuilder ($ this ->getName ());
147
+ $ builder ->setCoordinates ($ feature ['geometry ' ]['coordinates ' ][1 ], $ feature ['geometry ' ]['coordinates ' ][0 ]);
148
+ $ builder ->setStreetNumber ($ feature ['properties ' ]['housenumber ' ] ?? null );
149
+ $ builder ->setStreetName ($ this ->guessStreetName ($ feature ['properties ' ]));
150
+ $ builder ->setSubLocality ($ this ->guessSubLocality ($ feature ['properties ' ]));
151
+ $ builder ->setLocality ($ this ->guessLocality ($ feature ['properties ' ]));
152
+ $ builder ->setPostalCode ($ feature ['properties ' ]['postalcode ' ] ?? null );
153
+ $ builder ->setCountry ($ feature ['properties ' ]['country ' ] ?? null );
154
+ $ builder ->setCountryCode (
155
+ isset ($ feature ['properties ' ]['country_code ' ]) ? strtoupper ($ feature ['properties ' ]['country_code ' ]) :
156
+ (isset ($ feature ['properties ' ]['country_a ' ]) ? strtoupper ($ feature ['properties ' ]['country_a ' ]) : null ));
157
+ $ builder ->setTimezone ($ feature ['properties ' ]['timezone ' ] ?? null );
158
+
159
+ if (isset ($ feature ['bbox ' ])) {
160
+ $ builder ->setBounds ($ feature ['bbox ' ][3 ], $ feature ['bbox ' ][2 ], $ feature ['bbox ' ][1 ], $ feature ['bbox ' ][0 ]);
149
161
}
150
162
151
- $ props = $ location ['properties ' ];
152
-
153
- $ adminLevels = [];
154
- foreach (['region ' , 'county ' , 'locality ' , 'macroregion ' , 'country ' ] as $ i => $ component ) {
155
- if (isset ($ props [$ component ])) {
156
- $ adminLevels [] = ['name ' => $ props [$ component ], 'level ' => $ i + 1 ];
163
+ $ level = 1 ;
164
+ foreach (['macroregion ' , 'region ' , 'macrocounty ' , 'county ' , 'locality ' , 'localadmin ' , 'borough ' ] as $ component ) {
165
+ if (isset ($ feature ['properties ' ][$ component ])) {
166
+ $ builder ->addAdminLevel ($ level ++, $ feature ['properties ' ][$ component ], $ feature ['properties ' ][$ component .'_a ' ] ?? null );
167
+ }
168
+ // Administrative level should be an integer in [1,5].
169
+ if ($ level > 5 ) {
170
+ break ;
157
171
}
158
172
}
159
173
160
- $ results [] = Address::createFromArray ([
161
- 'providedBy ' => $ this ->getName (),
162
- 'latitude ' => $ location ['geometry ' ]['coordinates ' ][1 ],
163
- 'longitude ' => $ location ['geometry ' ]['coordinates ' ][0 ],
164
- 'bounds ' => $ bounds ,
165
- 'streetNumber ' => isset ($ props ['housenumber ' ]) ? $ props ['housenumber ' ] : null ,
166
- 'streetName ' => isset ($ props ['street ' ]) ? $ props ['street ' ] : null ,
167
- 'subLocality ' => isset ($ props ['neighbourhood ' ]) ? $ props ['neighbourhood ' ] : null ,
168
- 'locality ' => isset ($ props ['locality ' ]) ? $ props ['locality ' ] : null ,
169
- 'postalCode ' => isset ($ props ['postalcode ' ]) ? $ props ['postalcode ' ] : null ,
170
- 'adminLevels ' => $ adminLevels ,
171
- 'country ' => isset ($ props ['country ' ]) ? $ props ['country ' ] : null ,
172
- 'countryCode ' => isset ($ props ['country_a ' ]) ? strtoupper ($ props ['country_a ' ]) : null ,
173
- ]);
174
+ /** @var PeliasAddress $location */
175
+ $ location = $ builder ->build (PeliasAddress::class);
176
+
177
+ $ location = $ location ->withId ($ feature ['properties ' ]['id ' ] ?? null );
178
+ $ location = $ location ->withLayer ($ feature ['properties ' ]['layer ' ] ?? null );
179
+ $ location = $ location ->withSource ($ feature ['properties ' ]['source ' ] ?? null );
180
+ $ location = $ location ->withName ($ feature ['properties ' ]['name ' ] ?? null );
181
+ $ location = $ location ->withConfidence ($ feature ['properties ' ]['confidence ' ] ?? null );
182
+ $ location = $ location ->withAccuracy ($ feature ['properties ' ]['accuracy ' ] ?? null );
183
+
184
+ $ results [] = $ location ;
174
185
}
175
186
176
187
return new AddressCollection ($ results );
@@ -181,35 +192,35 @@ protected function executeQuery(string $url): AddressCollection
181
192
*
182
193
* @return string|null
183
194
*/
184
- protected function guessLocality (array $ components )
195
+ protected static function guessLocality (array $ components )
185
196
{
186
- $ localityKeys = ['city ' , 'town ' , 'village ' , 'hamlet ' ];
197
+ $ localityKeys = ['locality ' , ' localadmin ' , ' city ' , 'town ' , 'village ' , 'hamlet ' ];
187
198
188
- return $ this -> guessBestComponent ($ components , $ localityKeys );
199
+ return self :: guessBestComponent ($ components , $ localityKeys );
189
200
}
190
201
191
202
/**
192
203
* @param array<string, mixed> $components
193
204
*
194
205
* @return string|null
195
206
*/
196
- protected function guessStreetName (array $ components )
207
+ protected static function guessSubLocality (array $ components )
197
208
{
198
- $ streetNameKeys = ['road ' , 'street ' , ' street_name ' , ' residential ' ];
209
+ $ subLocalityKeys = ['neighbourhood ' , 'city_district ' ];
199
210
200
- return $ this -> guessBestComponent ($ components , $ streetNameKeys );
211
+ return self :: guessBestComponent ($ components , $ subLocalityKeys );
201
212
}
202
213
203
214
/**
204
215
* @param array<string, mixed> $components
205
216
*
206
217
* @return string|null
207
218
*/
208
- protected function guessSubLocality (array $ components )
219
+ protected static function guessStreetName (array $ components )
209
220
{
210
- $ subLocalityKeys = ['neighbourhood ' , 'city_district ' ];
221
+ $ streetNameKeys = ['road ' , 'street ' , ' street_name ' , ' residential ' ];
211
222
212
- return $ this -> guessBestComponent ($ components , $ subLocalityKeys );
223
+ return self :: guessBestComponent ($ components , $ streetNameKeys );
213
224
}
214
225
215
226
/**
@@ -218,7 +229,7 @@ protected function guessSubLocality(array $components)
218
229
*
219
230
* @return string|null
220
231
*/
221
- protected function guessBestComponent (array $ components , array $ keys )
232
+ protected static function guessBestComponent (array $ components , array $ keys )
222
233
{
223
234
foreach ($ keys as $ key ) {
224
235
if (isset ($ components [$ key ]) && !empty ($ components [$ key ])) {
0 commit comments