Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0380943

Browse files
wivakuwivaku
and
wivaku
authored
[Google Places] fix + support both reverse modes: Search & Nearby (#1070)
* fix + support both reverse modes: Search & Nearby * style fix * clarifications of mode + defaults * updated for 1.1.0 * Update CHANGELOG.md Co-authored-by: wivaku <[email protected]>
1 parent 5a67c79 commit 0380943

9 files changed

+3854
-31
lines changed

src/Provider/GoogleMapsPlaces/CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
44

5+
## 1.2.0
6+
7+
### Added
8+
9+
- Adds support for reverse query `Nearby` mode (rankby `prominence` + `radius`, or `distance` + `type/keyword/name`)
10+
11+
### Fixed
12+
13+
- reverse query w/ `Search` mode checked for `type/keyword/name`, but only `type` is allowed
14+
515
## 1.1.0
616

717
### Removed
@@ -16,4 +26,4 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee
1626

1727
## 1.0.0
1828

19-
First release of this library.
29+
First release of this library.

src/Provider/GoogleMapsPlaces/GoogleMapsPlaces.php

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ final class GoogleMapsPlaces extends AbstractHttpProvider implements Provider
6262
*/
6363
const GEOCODE_MODE_SEARCH = 'search';
6464

65+
/**
66+
* @var string
67+
*/
68+
const GEOCODE_MODE_NEARBY = 'nearby';
69+
6570
/**
6671
* @var string
6772
*/
@@ -110,7 +115,7 @@ public function geocodeQuery(GeocodeQuery $query): Collection
110115
return $this->fetchUrl(self::SEARCH_ENDPOINT_URL_SSL, $this->buildPlaceSearchQuery($query));
111116
}
112117

113-
throw new InvalidArgument('Mode must be one of `%s, %s`', self::GEOCODE_MODE_FIND, self::GEOCODE_MODE_SEARCH);
118+
throw new InvalidArgument(sprintf('Mode must be one of `%s, %s`', self::GEOCODE_MODE_FIND, self::GEOCODE_MODE_SEARCH));
114119
}
115120

116121
/**
@@ -122,7 +127,14 @@ public function geocodeQuery(GeocodeQuery $query): Collection
122127
*/
123128
public function reverseQuery(ReverseQuery $query): Collection
124129
{
125-
return $this->fetchUrl(self::SEARCH_ENDPOINT_URL_SSL, $this->buildNearbySearchQuery($query));
130+
// for backward compatibility: use SEARCH as default mode (includes formatted_address)
131+
if (self::GEOCODE_MODE_SEARCH === $query->getData('mode', self::GEOCODE_MODE_SEARCH)) {
132+
$url = self::SEARCH_ENDPOINT_URL_SSL;
133+
} else {
134+
$url = self::NEARBY_ENDPOINT_URL_SSL;
135+
}
136+
137+
return $this->fetchUrl($url, $this->buildNearbySearchQuery($query));
126138
}
127139

128140
/**
@@ -212,35 +224,65 @@ private function buildPlaceSearchQuery(GeocodeQuery $geocodeQuery): array
212224
*/
213225
private function buildNearbySearchQuery(ReverseQuery $reverseQuery): array
214226
{
227+
// for backward compatibility: use SEARCH as default mode (includes formatted_address)
228+
$mode = $reverseQuery->getData('mode', self::GEOCODE_MODE_SEARCH);
229+
215230
$query = [
216231
'location' => sprintf(
217232
'%s,%s',
218233
$reverseQuery->getCoordinates()->getLatitude(),
219234
$reverseQuery->getCoordinates()->getLongitude()
220235
),
221-
'rankby' => 'distance',
236+
'rankby' => 'prominence',
222237
];
223238

224239
if (null !== $reverseQuery->getLocale()) {
225240
$query['language'] = $reverseQuery->getLocale();
226241
}
227242

228-
$query = $this->applyDataFromQuery($reverseQuery, $query, [
243+
$validParameters = [
229244
'keyword',
230245
'type',
231246
'name',
232247
'minprice',
233248
'maxprice',
234249
'name',
235250
'opennow',
236-
]);
251+
'radius',
252+
];
253+
254+
if (self::GEOCODE_MODE_NEARBY === $mode) {
255+
$validParameters[] = 'rankby';
256+
}
237257

238-
$requiredParameters = array_filter(array_keys($query), function (string $key) {
239-
return in_array($key, ['keyword', 'type', 'name'], true);
240-
});
258+
$query = $this->applyDataFromQuery($reverseQuery, $query, $validParameters);
241259

242-
if (1 !== count($requiredParameters)) {
243-
throw new InvalidArgument('One of `type`, `keyword`, `name` is required to be set in the Query data for Reverse Geocoding');
260+
if (self::GEOCODE_MODE_NEARBY === $mode) {
261+
// mode:nearby, rankby:prominence, parameter:radius
262+
if ('prominence' === $query['rankby'] && !isset($query['radius'])) {
263+
throw new InvalidArgument('`radius` is required to be set in the Query data for Reverse Geocoding when ranking by prominence');
264+
}
265+
266+
// mode:nearby, rankby:distance, parameter:type/keyword/name
267+
if ('distance' === $query['rankby']) {
268+
if (isset($query['radius'])) {
269+
unset($query['radius']);
270+
}
271+
272+
$requiredParameters = array_intersect(['keyword', 'type', 'name'], array_keys($query));
273+
274+
if (1 !== count($requiredParameters)) {
275+
throw new InvalidArgument('One of `type`, `keyword`, `name` is required to be set in the Query data for Reverse Geocoding when ranking by distance');
276+
}
277+
}
278+
}
279+
280+
if (self::GEOCODE_MODE_SEARCH === $mode) {
281+
// mode:search, parameter:type
282+
283+
if (!isset($query['type'])) {
284+
throw new InvalidArgument('`type` is required to be set in the Query data for Reverse Geocoding when using search mode');
285+
}
244286
}
245287

246288
return $query;
@@ -309,6 +351,10 @@ private function fetchUrl(string $url, array $query): AddressCollection
309351
$address = $address->withFormattedAddress($result->formatted_address);
310352
}
311353

354+
if (isset($result->vicinity)) {
355+
$address = $address->withVicinity($result->vicinity);
356+
}
357+
312358
if (isset($result->types)) {
313359
$address = $address->withType($result->types);
314360
}

src/Provider/GoogleMapsPlaces/Model/GooglePlace.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ final class GooglePlace extends Address
3939
*/
4040
private $formattedAddress;
4141

42+
/**
43+
* @var string|null
44+
*/
45+
private $vicinity;
46+
4247
/**
4348
* @var string|null
4449
*/
@@ -175,6 +180,27 @@ public function withFormattedAddress(string $formattedAddress = null)
175180
return $new;
176181
}
177182

183+
/**
184+
* @return null|string
185+
*/
186+
public function getVicinity()
187+
{
188+
return $this->vicinity;
189+
}
190+
191+
/**
192+
* @param string|null $vicinity
193+
*
194+
* @return GooglePlace
195+
*/
196+
public function withVicinity(string $vicinity = null)
197+
{
198+
$new = clone $this;
199+
$new->vicinity = $vicinity;
200+
201+
return $new;
202+
}
203+
178204
/**
179205
* @return string|null
180206
*/
Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Google Maps Geocoder provider
1+
# Google Places Geocoder provider
22
[![Build Status](https://travis-ci.org/geocoder-php/google-maps-places-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/google-maps-places-provider)
33
[![Latest Stable Version](https://poser.pugx.org/geocoder-php/google-maps-places-provider/v/stable)](https://packagist.org/packages/geocoder-php/google-maps-places-provider)
44
[![Total Downloads](https://poser.pugx.org/geocoder-php/google-maps-places-provider/downloads)](https://packagist.org/packages/geocoder-php/google-maps-places-provider)
@@ -7,11 +7,10 @@
77
[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/google-maps-places-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/google-maps-places-provider)
88
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
99

10-
This is the Google Maps Places provider from the PHP Geocoder. This is a **READ ONLY** repository. See the
11-
[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation.
10+
This is the Google Places provider from the PHP Geocoder. This is a **READ ONLY** repository. See the
11+
[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation.
1212

1313
## Install
14-
1514
```bash
1615
composer require geocoder-php/google-maps-places-provider
1716
```
@@ -20,34 +19,87 @@ composer require geocoder-php/google-maps-places-provider
2019
https://developers.google.com/places/web-service
2120

2221
## Usage
23-
This provider often requires extra data when making queries, due to requirements of the underlying places API.
22+
This provider often requires extra data when making queries, due to requirements of the underlying Places API.
2423

2524
### Geocoding
2625
This provider supports two different modes of geocoding by text.
2726

2827
#### Find Mode
2928
This is the default mode. It required an exact places name. It's not very forgiving, and generally only returns a single result
3029

30+
```php
31+
$results = $provider->geocodeQuery(
32+
GeocodeQuery::create('Museum of Contemporary Art Australia')
33+
);
34+
```
35+
3136
#### Search Mode
32-
This mode will perform a search based on the input text.
37+
This mode will perform a search based on the input text.
3338
It's a lot more forgiving that the `find` mode, but results will contain all fields and thus be billed at the highest rate.
3439

3540
```php
36-
$findResults = $provider->geocodeQuery(GeocodeQuery::create('Museum of Contemporary Art Australia')); // One Result
41+
$results = $provider->geocodeQuery(
42+
GeocodeQuery::create('art museum sydney')
43+
->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH)
44+
);
45+
```
3746

38-
$searchResults = $provider->geocodeQuery(GeocodeQuery::create('art museum sydney'))
39-
->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH); // 20 Results
47+
around location (which is similar to reverse geocoding, see below):
48+
49+
```php
50+
$results = $provider->geocodeQuery(
51+
GeocodeQuery::create('bar')
52+
->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH)
53+
->withData('location', '-32.926642, 151.783026')
54+
);
4055
```
4156

4257
### Reverse Geocoding
43-
When reverse geocoding, you are required to supply either a `keyword`, `type` or `name`.
44-
See https://developers.google.com/places/web-service/search#PlaceSearchRequests
58+
Three options available for reverse geocoding of latlon coordinates:
59+
60+
- mode `search` + type (e.g.) `bar`: uses Google Place API [Text search](https://developers.google.com/places/web-service/search#TextSearchRequests), requires `type`
61+
- is similar to: Search around location (see previous section)
62+
- mode `nearby` + rankby `distance`: uses Google Place API [Nearby search](https://developers.google.com/places/web-service/search#PlaceSearchRequests), requires `type/keyword/name`
63+
- mode `nearby` + rankby `prominence`: uses Google Place API [Nearby search](https://developers.google.com/places/web-service/search#PlaceSearchRequests), requires `radius`
64+
65+
Default mode: `search` (because of backward compatibility). When using mode `nearby` default rankby: `prominence`.
66+
Mode `search` + type and mode `nearby` + type/keyword/name are very similar.
67+
Mode `search` gives formatted_address, mode `nearby` gives vicinity instead. E.g.:
68+
69+
- `search`: has "formatted_address": "7 Cope St, Redfern NSW 2016"
70+
- `nearby`: has "vicinity" instead: "7 Cope St, Redfern"
71+
72+
Examples
73+
74+
```php
75+
$results = $provider->reverseQuery(
76+
ReverseQuery::fromCoordinates(-33.892674, 151.200727)
77+
// ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH) // =default
78+
->withData('type', 'bar') // requires type
79+
);
80+
$address = $results->first()->getFormattedAddress();
81+
```
82+
83+
```php
84+
$results = $provider->reverseQuery(
85+
ReverseQuery::fromCoordinates(-33.892674, 151.200727)
86+
->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
87+
//->withData('rankby','prominence'); // =default
88+
->withData('radius', 500) // requires radius (meters)
89+
);
90+
$vicinity = $results->first()->getVicinity();
91+
```
4592

4693
```php
47-
$results = $provider->reverseQuery(ReverseQuery::fromCoordinates(-33.892674, 151.200727)->withData('type', 'bar'));
94+
$results = $provider->reverseQuery(
95+
ReverseQuery::fromCoordinates(-33.892674, 151.200727)
96+
->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
97+
->withData('rankby','distance');
98+
->withData('keyword', 'bar') // requires type/keyword/name
99+
);
48100
```
49101

50102
### Contribute
51103

52-
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or
104+
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or
53105
report any issues you find on the [issue tracker](https://github.com/geocoder-php/Geocoder/issues).

0 commit comments

Comments
 (0)