Skip to content

Commit 9f65578

Browse files
authored
[Google Maps] Fix issue with duplicated SubLocalityLevels (#1174)
* Update GoogleAddress.php * Add test * Update GoogleMapsTest.php * Update GoogleMapsTest.php * Update GoogleMapsTest.php
1 parent 13a0c4e commit 9f65578

File tree

3 files changed

+127
-21
lines changed

3 files changed

+127
-21
lines changed

src/Provider/GoogleMaps/Model/GoogleAddress.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -516,21 +516,26 @@ public function getSubLocalityLevels()
516516
*/
517517
public function withSubLocalityLevels(array $subLocalityLevel)
518518
{
519+
$levels = array_filter($subLocalityLevel, function ($level) {
520+
return !empty($level['level']) && (!empty($level['name']) || !empty($level['code']));
521+
});
522+
523+
$levelCount = array_count_values(array_column($levels, 'level'));
524+
519525
$subLocalityLevels = [];
520-
foreach ($subLocalityLevel as $level) {
521-
if (empty($level['level'])) {
522-
continue;
523-
}
526+
foreach ($levelCount as $level => $count) {
527+
$_levels = array_filter($levels, function ($l) use ($level) {
528+
return $l['level'] === $level;
529+
});
524530

525-
$name = $level['name'] ?? $level['code'] ?? '';
526-
if (empty($name)) {
527-
continue;
528-
}
531+
$names = array_filter(array_column($_levels, 'name'), function ($name) { return !empty($name); });
532+
$codes = array_filter(array_column($_levels, 'code'), function ($code) { return !empty($code); });
529533

530-
$subLocalityLevels[] = new AdminLevel($level['level'], $name, $level['code'] ?? null);
531-
}
534+
$name = count($names) > 0 ? implode(' / ', $names) : implode(' / ', $codes);
535+
$code = count($codes) > 0 ? implode(' / ', $codes) : null;
532536

533-
$subLocalityLevels = array_unique($subLocalityLevels);
537+
$subLocalityLevels[] = new AdminLevel($level, $name, $code);
538+
}
534539

535540
$new = clone $this;
536541
$new->subLocalityLevels = new AdminLevelCollection($subLocalityLevels);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
s:2655:"{
2+
"results" : [
3+
{
4+
"address_components" : [
5+
{
6+
"long_name" : "Rue de Pont-à-Migneloux",
7+
"short_name" : "Rue de Pont-à-Migneloux",
8+
"types" : [ "route" ]
9+
},
10+
{
11+
"long_name" : "Wayaux",
12+
"short_name" : "Wayaux",
13+
"types" : [ "political", "sublocality", "sublocality_level_1" ]
14+
},
15+
{
16+
"long_name" : "Les Bons Villers",
17+
"short_name" : "Les Bons Villers",
18+
"types" : [ "political", "sublocality", "sublocality_level_1" ]
19+
},
20+
{
21+
"long_name" : "Frasnes-lez-Gosselies",
22+
"short_name" : "Frasnes-lez-Gosselies",
23+
"types" : [ "locality", "political" ]
24+
},
25+
{
26+
"long_name" : "Hainaut",
27+
"short_name" : "HT",
28+
"types" : [ "administrative_area_level_2", "political" ]
29+
},
30+
{
31+
"long_name" : "Région Wallonne",
32+
"short_name" : "Région Wallonne",
33+
"types" : [ "administrative_area_level_1", "political" ]
34+
},
35+
{
36+
"long_name" : "Belgium",
37+
"short_name" : "BE",
38+
"types" : [ "country", "political" ]
39+
},
40+
{
41+
"long_name" : "6210",
42+
"short_name" : "6210",
43+
"types" : [ "postal_code" ]
44+
}
45+
],
46+
"formatted_address" : "Rue de Pont-à-Migneloux, 6210 Les Bons Villers, Belgium",
47+
"geometry" : {
48+
"bounds" : {
49+
"northeast" : {
50+
"lat" : 50.49571500000003,
51+
"lng" : 4.473629799999999
52+
},
53+
"southwest" : {
54+
"lat" : 50.48990779999998,
55+
"lng" : 4.4595167
56+
}
57+
},
58+
"location" : {
59+
"lat" : 50.4944514,
60+
"lng" : 4.4694362
61+
},
62+
"location_type" : "GEOMETRIC_CENTER",
63+
"viewport" : {
64+
"northeast" : {
65+
"lat" : 50.49571500000003,
66+
"lng" : 4.473629799999999
67+
},
68+
"southwest" : {
69+
"lat" : 50.48990779999998,
70+
"lng" : 4.4595167
71+
}
72+
}
73+
},
74+
"place_id" : "EjhSdWUgZGUgUG9udC3DoC1NaWduZWxvdXgsIDYyMTAgTGVzIEJvbnMgVmlsbGVycywgQmVsZ2l1bSIuKiwKFAoSCcPJx0xGKcJHEUw-Q8kfZcEeEhQKEgmHf2F_QCnCRxF02JKWsgNAAA",
75+
"types" : [ "route" ]
76+
}
77+
],
78+
"status" : "OK"
79+
}
80+
";

src/Provider/GoogleMaps/Tests/GoogleMapsTest.php

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
use Geocoder\Exception\InvalidServerResponse;
1616
use Geocoder\IntegrationTest\BaseTestCase;
17-
use Geocoder\Location;
1817
use Geocoder\Model\Address;
1918
use Geocoder\Model\AddressCollection;
2019
use Geocoder\Provider\GoogleMaps\Model\GoogleAddress;
@@ -94,7 +93,7 @@ public function testGeocodeWithRealAddress()
9493
$this->assertInstanceOf(AddressCollection::class, $results);
9594
$this->assertCount(1, $results);
9695

97-
/** @var Location $result */
96+
/** @var GoogleAddress $result */
9897
$result = $results->first();
9998
$this->assertInstanceOf(Address::class, $result);
10099
$this->assertEqualsWithDelta(48.8630462, $result->getCoordinates()->getLatitude(), 0.001);
@@ -128,7 +127,7 @@ public function testGeocodeBoundsWithRealAddressForNonRooftopLocation()
128127
$this->assertInstanceOf(AddressCollection::class, $results);
129128
$this->assertCount(1, $results);
130129

131-
/** @var Location $result */
130+
/** @var GoogleAddress $result */
132131
$result = $results->first();
133132
$this->assertInstanceOf(Address::class, $result);
134133
$this->assertNotNull($result->getBounds());
@@ -156,7 +155,7 @@ public function testReverseWithRealCoordinates()
156155
$this->assertInstanceOf(AddressCollection::class, $results);
157156
$this->assertCount(5, $results);
158157

159-
/** @var Location $result */
158+
/** @var GoogleAddress $result */
160159
$result = $results->first();
161160
$this->assertInstanceOf(Address::class, $result);
162161
$this->assertEquals(12, $result->getStreetNumber());
@@ -180,7 +179,7 @@ public function testReverseWithRealCoordinatesAndLocale()
180179
$this->assertInstanceOf(AddressCollection::class, $results);
181180
$this->assertCount(5, $results);
182181

183-
/** @var Location $result */
182+
/** @var GoogleAddress $result */
184183
$result = $results->first();
185184
$this->assertInstanceOf(Address::class, $result);
186185
$this->assertEquals(12, $result->getStreetNumber());
@@ -204,7 +203,7 @@ public function testGeocodeWithCityDistrict()
204203
$this->assertInstanceOf(AddressCollection::class, $results);
205204
$this->assertCount(1, $results);
206205

207-
/** @var Location $result */
206+
/** @var GoogleAddress $result */
208207
$result = $results->first();
209208
$this->assertInstanceOf(Address::class, $result);
210209
$this->assertEquals('Kalbach-Riedberg', $result->getSubLocality());
@@ -228,7 +227,7 @@ public function testGeocodeWithRealValidApiKey()
228227
$this->assertInstanceOf(AddressCollection::class, $results);
229228
$this->assertCount(1, $results);
230229

231-
/** @var Location $result */
230+
/** @var GoogleAddress $result */
232231
$result = $results->first();
233232
$this->assertInstanceOf(Address::class, $result);
234233
$this->assertNotNull($result->getCoordinates()->getLatitude());
@@ -251,7 +250,7 @@ public function testGeocodeWithComponentFiltering()
251250
$this->assertInstanceOf(AddressCollection::class, $results);
252251
$this->assertCount(1, $results);
253252

254-
/** @var Location $result */
253+
/** @var GoogleAddress $result */
255254
$result = $results->first();
256255
$this->assertInstanceOf(Address::class, $result);
257256
$this->assertEquals('Malmö', $result->getLocality());
@@ -340,7 +339,7 @@ public function testGeocodePostalTown()
340339
$this->assertInstanceOf(AddressCollection::class, $results);
341340
$this->assertCount(1, $results);
342341

343-
/** @var Location $result */
342+
/** @var GoogleAddress $result */
344343
$result = $results->first();
345344
$this->assertInstanceOf(Address::class, $result);
346345
$this->assertEquals('Pontypridd', $result->getLocality());
@@ -558,7 +557,7 @@ public function testGeocodeBoundsWithRealAddressWithViewportOnly()
558557
$this->assertInstanceOf(AddressCollection::class, $results);
559558
$this->assertCount(1, $results);
560559

561-
/** @var \Geocoder\Model\Address $result */
560+
/** @var GoogleAddress $result */
562561
$result = $results->first();
563562
$this->assertInstanceOf(Address::class, $result);
564563
$this->assertNotNull($result->getBounds());
@@ -569,6 +568,28 @@ public function testGeocodeBoundsWithRealAddressWithViewportOnly()
569568
$this->assertEquals(false, $result->isPartialMatch());
570569
}
571570

571+
public function testGeocodeDuplicateSubLocalityLevel()
572+
{
573+
$provider = $this->getGoogleMapsProvider();
574+
$results = $provider->geocodeQuery(GeocodeQuery::create('Rue de Pont-A-Migneloux, 6210 Wayaux, Belgique'));
575+
576+
$this->assertInstanceOf(AddressCollection::class, $results);
577+
$this->assertCount(1, $results);
578+
579+
/** @var GoogleAddress $result */
580+
$result = $results->first();
581+
$this->assertInstanceOf(Address::class, $result);
582+
$this->assertEquals('Rue de Pont-à-Migneloux, 6210 Les Bons Villers, Belgium', $result->getFormattedAddress());
583+
$this->assertEquals('Les Bons Villers', $result->getSubLocality());
584+
$this->assertCount(2, $result->getAdminLevels());
585+
$this->assertEquals('Région Wallonne', $result->getAdminLevels()->get(1)->getName());
586+
$this->assertEquals('Hainaut', $result->getAdminLevels()->get(2)->getName());
587+
$this->assertInstanceOf('\Geocoder\Model\AdminLevelCollection', $result->getSubLocalityLevels());
588+
$this->assertEquals(1, $result->getSubLocalityLevels()->get(1)->getLevel());
589+
$this->assertEquals('Wayaux / Les Bons Villers', $result->getSubLocalityLevels()->get(1)->getName());
590+
$this->assertEquals('Wayaux / Les Bons Villers', $result->getSubLocalityLevels()->get(1)->getCode());
591+
}
592+
572593
private function getGoogleMapsProvider(): GoogleMaps
573594
{
574595
if (!isset($_SERVER['GOOGLE_GEOCODING_KEY'])) {

0 commit comments

Comments
 (0)