From e68be475e227f24018a4144ec1720962f85e4c31 Mon Sep 17 00:00:00 2001 From: fbuchlak <30214087+fbuchlak@users.noreply.github.com> Date: Sun, 23 Mar 2025 11:12:28 +0100 Subject: [PATCH 1/3] feat: [Photon] support multiple layers --- src/Provider/Photon/Photon.php | 16 ++++++++++-- ...o_4d9e19f668373f9804a90f41f1a499a74ded2594 | 1 + ..._6ab584da133fb849cb0cffafad872b65d3da3de1} | 0 ...o_ed91365025e794205300bed4ad45119eeeed5f3f | 1 + src/Provider/Photon/Tests/PhotonTest.php | 26 +++++++++++++++++++ 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_4d9e19f668373f9804a90f41f1a499a74ded2594 rename src/Provider/Photon/Tests/.cached_responses/{photon.komoot.io_1452fda1b72428b0f5de90de04038275fd7f7e7e => photon.komoot.io_6ab584da133fb849cb0cffafad872b65d3da3de1} (100%) create mode 100644 src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_ed91365025e794205300bed4ad45119eeeed5f3f diff --git a/src/Provider/Photon/Photon.php b/src/Provider/Photon/Photon.php index c8efa767f..6acc4345f 100644 --- a/src/Provider/Photon/Photon.php +++ b/src/Provider/Photon/Photon.php @@ -68,12 +68,12 @@ public function geocodeQuery(GeocodeQuery $query): Collection .'/api?' .http_build_query([ 'q' => $address, - 'layer' => $query->getData('layer'), 'limit' => $query->getLimit(), 'lang' => $query->getLocale(), 'lat' => $query->getData('lat'), 'lon' => $query->getData('lon'), ]); + $url .= $this->buildLayerFilterQuery($query->getData('layer')); $osmTagFilters = $this->buildOsmTagFilterQuery($query->getData('osm_tag')); if (!empty($osmTagFilters)) { $url .= $osmTagFilters; @@ -109,11 +109,11 @@ public function reverseQuery(ReverseQuery $query): Collection .http_build_query([ 'lat' => $latitude, 'lon' => $longitude, - 'layer' => $query->getData('layer'), 'radius' => $query->getData('radius'), 'limit' => $query->getLimit(), 'lang' => $query->getLocale(), ]); + $url .= $this->buildLayerFilterQuery($query->getData('layer')); $osmTagFilters = $this->buildOsmTagFilterQuery($query->getData('osm_tag')); if (!empty($osmTagFilters)) { $url .= $osmTagFilters; @@ -177,6 +177,18 @@ public function getName(): string return 'photon'; } + private function buildLayerFilterQuery(mixed $layers): string + { + if (!is_iterable($layers)) { + $layers = [$layers]; + } + + return implode('', array_map( + static fn ($layer) => sprintf('&layer=%s', $layer), + array_filter(iterator_to_array($layers), is_scalar(...)), + )); + } + /** * @param string|array|null $filters */ diff --git a/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_4d9e19f668373f9804a90f41f1a499a74ded2594 b/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_4d9e19f668373f9804a90f41f1a499a74ded2594 new file mode 100644 index 000000000..bc7c5a595 --- /dev/null +++ b/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_4d9e19f668373f9804a90f41f1a499a74ded2594 @@ -0,0 +1 @@ +s:359:"{"features":[{"geometry":{"coordinates":[21.2392122,49.0000074],"type":"Point"},"type":"Feature","properties":{"osm_type":"R","osm_id":388255,"extent":[20.870461,49.185185,21.485864,48.810739],"country":"Slovensko","osm_key":"place","countrycode":"SK","osm_value":"city","name":"Prešov","state":"Prešovský kraj","type":"city"}}],"type":"FeatureCollection"}"; \ No newline at end of file diff --git a/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_1452fda1b72428b0f5de90de04038275fd7f7e7e b/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_6ab584da133fb849cb0cffafad872b65d3da3de1 similarity index 100% rename from src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_1452fda1b72428b0f5de90de04038275fd7f7e7e rename to src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_6ab584da133fb849cb0cffafad872b65d3da3de1 diff --git a/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_ed91365025e794205300bed4ad45119eeeed5f3f b/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_ed91365025e794205300bed4ad45119eeeed5f3f new file mode 100644 index 000000000..19cda6b8d --- /dev/null +++ b/src/Provider/Photon/Tests/.cached_responses/photon.komoot.io_ed91365025e794205300bed4ad45119eeeed5f3f @@ -0,0 +1 @@ +s:703:"{"features":[{"geometry":{"coordinates":[21.2392122,49.0000074],"type":"Point"},"type":"Feature","properties":{"osm_type":"R","osm_id":388255,"extent":[20.870461,49.185185,21.485864,48.810739],"country":"Slovensko","osm_key":"place","countrycode":"SK","osm_value":"city","name":"Prešov","state":"Prešovský kraj","type":"city"}},{"geometry":{"coordinates":[21.2392122,49.0000074],"type":"Point"},"type":"Feature","properties":{"osm_type":"R","osm_id":2320257,"extent":[21.1569866,49.0468381,21.3354271,48.9449997],"country":"Slovensko","osm_key":"place","city":"Prešov","countrycode":"SK","osm_value":"city","name":"Prešov","state":"Prešovský kraj","type":"district"}}],"type":"FeatureCollection"}"; \ No newline at end of file diff --git a/src/Provider/Photon/Tests/PhotonTest.php b/src/Provider/Photon/Tests/PhotonTest.php index 58466bcba..3afd74861 100644 --- a/src/Provider/Photon/Tests/PhotonTest.php +++ b/src/Provider/Photon/Tests/PhotonTest.php @@ -213,6 +213,32 @@ public function testReverseQueryWithLayerCityAndRadiusFilter(): void $this->assertEquals('Berlin', $result->getLocality()); } + public function testReverseQueryWithMultipleLayers(): void + { + $provider = Photon::withKomootServer($this->getHttpClient()); + $reverseQuery = ReverseQuery::fromCoordinates(49.001831, 21.239311) + ->withData('layer', 'city') + ->withLimit(2); + + $results = $provider->reverseQuery($reverseQuery); + $this->assertInstanceOf(AddressCollection::class, $results); + $this->assertCount(1, $results); + $result0 = $results->get(0); + $this->assertInstanceOf(PhotonAddress::class, $result0); + $this->assertEquals('city', $result0->getType()); + + $reverseQuery = $reverseQuery->withData('layer', ['city', 'district']); + $results = $provider->reverseQuery($reverseQuery); + $this->assertInstanceOf(AddressCollection::class, $results); + $this->assertCount(2, $results); + $result0 = $results->get(0); + $this->assertInstanceOf(PhotonAddress::class, $result0); + $this->assertEquals('city', $result0->getType()); + $result1 = $results->get(1); + $this->assertInstanceOf(PhotonAddress::class, $result1); + $this->assertEquals('district', $result1->getType()); + } + public function testGeocodeQueryWithBbox(): void { // Germany From 02ede6be983ac9807181f32d00a083bd0e54fbb5 Mon Sep 17 00:00:00 2001 From: fbuchlak <30214087+fbuchlak@users.noreply.github.com> Date: Sun, 23 Mar 2025 11:34:53 +0100 Subject: [PATCH 2/3] fix: support php 8.0, 8.1 --- src/Provider/Photon/Photon.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Provider/Photon/Photon.php b/src/Provider/Photon/Photon.php index 6acc4345f..7df700bdc 100644 --- a/src/Provider/Photon/Photon.php +++ b/src/Provider/Photon/Photon.php @@ -183,9 +183,13 @@ private function buildLayerFilterQuery(mixed $layers): string $layers = [$layers]; } + if (!is_array($layers)) { + $layers = iterator_to_array($layers); + } + return implode('', array_map( static fn ($layer) => sprintf('&layer=%s', $layer), - array_filter(iterator_to_array($layers), is_scalar(...)), + array_filter($layers, static fn ($layer) => is_scalar($layer)), )); } From 71da9b71032c07c90dc7dd4e990cc973dc6e3dc6 Mon Sep 17 00:00:00 2001 From: fbuchlak <30214087+fbuchlak@users.noreply.github.com> Date: Sun, 23 Mar 2025 12:14:52 +0100 Subject: [PATCH 3/3] style: fix readability of buildLayerFilterQuery --- src/Provider/Photon/Photon.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Provider/Photon/Photon.php b/src/Provider/Photon/Photon.php index 7df700bdc..d9d423c4e 100644 --- a/src/Provider/Photon/Photon.php +++ b/src/Provider/Photon/Photon.php @@ -177,20 +177,23 @@ public function getName(): string return 'photon'; } + /** + * @param string|string[]|null $layers + */ private function buildLayerFilterQuery(mixed $layers): string { - if (!is_iterable($layers)) { - $layers = [$layers]; + $query = ''; + if (null === $layers) { + return $query; } - - if (!is_array($layers)) { - $layers = iterator_to_array($layers); + if (is_string($layers)) { + return '&layer='.urlencode($layers); + } + foreach ($layers as $layer) { + $query .= '&layer='.urlencode($layer); } - return implode('', array_map( - static fn ($layer) => sprintf('&layer=%s', $layer), - array_filter($layers, static fn ($layer) => is_scalar($layer)), - )); + return $query; } /**