diff --git a/src/Provider/Pelias/CHANGELOG.md b/src/Provider/Pelias/CHANGELOG.md index 0ae88d80a..4ff48cd89 100644 --- a/src/Provider/Pelias/CHANGELOG.md +++ b/src/Provider/Pelias/CHANGELOG.md @@ -8,6 +8,12 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee - Add support for PHP 8.1 - Add GitHub Actions workflow +- Returns the following pelias properties as well: + - layer + - confidence + - source + - match_type + - accuracy ### Removed diff --git a/src/Provider/Pelias/Model/PeliasAddress.php b/src/Provider/Pelias/Model/PeliasAddress.php new file mode 100644 index 000000000..4242546f2 --- /dev/null +++ b/src/Provider/Pelias/Model/PeliasAddress.php @@ -0,0 +1,190 @@ +layer = $data['layer'] ?? null; + $address->confidence = $data['confidence'] ?? null; + $address->matchType = $data['match_type'] ?? null; + $address->source = $data['source'] ?? null; + $address->accuracy = $data['accuracy'] ?? null; + + return $address; + } + + /** + * Get the pelias layer returned. + * + * @return string|null + */ + public function getLayer() + { + return $this->layer; + } + + /** + * Get confidence score from pelias. + * + * @return float|null + */ + public function getConfidence() + { + return $this->confidence; + } + + /** + * Get match type from pelias. + * + * @return string|null + */ + public function getMatchType() + { + return $this->matchType; + } + + /** + * Get data source from pelias. + * + * @return string|null + */ + public function getSource() + { + return $this->source; + } + + /** + * Get accuracy from pelias. + * + * @return string|null + */ + public function getAccuracy() + { + return $this->accuracy; + } + + /** + * Set the pelias layer returned. + * + * @param string|null $layer name of the pelias layer + * + * @return PeliasAddress + */ + public function withLayer(string $layer = null) + { + $new = clone $this; + $new->layer = $layer; + + return $new; + } + + /** + * Set confidence score from pelias. + * + * @param float|null $confidence confidence level as a float + * + * @return PeliasAddress + */ + public function withConfidence(float $confidence = null) + { + $new = clone $this; + $new->confidence = $confidence; + + return $new; + } + + /** + * Set match type from pelias. + * + * @param string|null $matchType precision of the match like "exact" + * + * @return PeliasAddress + */ + public function withMatchType(string $matchType = null) + { + $new = clone $this; + $new->matchType = $matchType; + + return $new; + } + + /** + * Set data source from pelias. + * + * @param string|null $source address source from pelias + * + * @return PeliasAddress + */ + public function withSource(string $source = null) + { + $new = clone $this; + $new->source = $source; + + return $new; + } + + /** + * Set accuracy from pelias. + * + * @param string|null $accuracy accuracy level from pelias like "point" + * + * @return PeliasAddress + */ + public function withAccuracy(string $accuracy = null) + { + $new = clone $this; + $new->accuracy = $accuracy; + + return $new; + } +} diff --git a/src/Provider/Pelias/Pelias.php b/src/Provider/Pelias/Pelias.php index 3bf9a79cb..d2f33538b 100644 --- a/src/Provider/Pelias/Pelias.php +++ b/src/Provider/Pelias/Pelias.php @@ -19,6 +19,7 @@ use Geocoder\Http\Provider\AbstractHttpProvider; use Geocoder\Model\Address; use Geocoder\Model\AddressCollection; +use Geocoder\Provider\Pelias\Model\PeliasAddress; use Geocoder\Provider\Provider; use Geocoder\Query\GeocodeQuery; use Geocoder\Query\ReverseQuery; @@ -132,48 +133,55 @@ protected function executeQuery(string $url): AddressCollection $results = []; foreach ($locations as $location) { - if (isset($location['bbox'])) { - $bounds = [ - 'south' => $location['bbox'][3], - 'west' => $location['bbox'][2], - 'north' => $location['bbox'][1], - 'east' => $location['bbox'][0], - ]; - } else { - $bounds = [ - 'south' => null, - 'west' => null, - 'north' => null, - 'east' => null, - ]; - } + $results[] = $this->buildAddress($location); + } - $props = $location['properties']; + return new AddressCollection($results); + } - $adminLevels = []; - foreach (['region', 'county', 'locality', 'macroregion', 'country'] as $i => $component) { - if (isset($props[$component])) { - $adminLevels[] = ['name' => $props[$component], 'level' => $i + 1]; - } - } + /** + * Build the Address object from the the Feature. + * + * @param array $location the Feature array + * + * @return PeliasAddress the address object + */ + protected function buildAddress(array $location): PeliasAddress + { + $bounds = [ + 'south' => $location['bbox'][3] ?? null, + 'west' => $location['bbox'][2] ?? null, + 'north' => $location['bbox'][1] ?? null, + 'east' => $location['bbox'][0] ?? null, + ]; - $results[] = Address::createFromArray([ - 'providedBy' => $this->getName(), - 'latitude' => $location['geometry']['coordinates'][1], - 'longitude' => $location['geometry']['coordinates'][0], - 'bounds' => $bounds, - 'streetNumber' => isset($props['housenumber']) ? $props['housenumber'] : null, - 'streetName' => isset($props['street']) ? $props['street'] : null, - 'subLocality' => isset($props['neighbourhood']) ? $props['neighbourhood'] : null, - 'locality' => isset($props['locality']) ? $props['locality'] : null, - 'postalCode' => isset($props['postalcode']) ? $props['postalcode'] : null, - 'adminLevels' => $adminLevels, - 'country' => isset($props['country']) ? $props['country'] : null, - 'countryCode' => isset($props['country_a']) ? strtoupper($props['country_a']) : null, - ]); + $props = $location['properties']; + $adminLevels = []; + foreach (['region', 'county', 'locality', 'macroregion', 'country'] as $i => $component) { + if (isset($props[$component])) { + $adminLevels[] = ['name' => $props[$component], 'level' => $i + 1]; + } } - return new AddressCollection($results); + return PeliasAddress::createFromArray([ + 'providedBy' => $this->getName(), + 'latitude' => $location['geometry']['coordinates'][1], + 'longitude' => $location['geometry']['coordinates'][0], + 'bounds' => $bounds, + 'streetNumber' => $props['housenumber'] ?? null, + 'streetName' => $props['street'] ?? null, + 'subLocality' => $props['neighbourhood'] ?? null, + 'locality' => $props['locality'] ?? null, + 'postalCode' => $props['postalcode'] ?? null, + 'adminLevels' => $adminLevels, + 'country' => $props['country'] ?? null, + 'countryCode' => isset($props['country_a']) ? strtoupper($props['country_a']) : null, + 'layer' => $props['layer'] ?? null, + 'confidence' => $props['confidence'] ?? null, + 'match_type' => $props['match_type'] ?? null, + 'source' => $props['source'] ?? null, + 'accuracy' => $props['accuracy'] ?? null, + ]); } /** diff --git a/src/Provider/Pelias/Tests/CustomPropertiesTest.php b/src/Provider/Pelias/Tests/CustomPropertiesTest.php new file mode 100644 index 000000000..c6bc18857 --- /dev/null +++ b/src/Provider/Pelias/Tests/CustomPropertiesTest.php @@ -0,0 +1,117 @@ +getMockedHttpClient($response), 'http://localhost/'); + $result = $provider->geocodeQuery(GeocodeQuery::create('foobar')); + + $this->assertInstanceOf(Collection::class, $result); + $this->assertEquals(1, $result->count()); + /** @var PeliasAddress $address */ + $address = $result->get(0); + + $this->assertInstanceOf(PeliasAddress::class, $address); + + $this->assertEquals('openaddresses', $address->getSource()); + $this->assertEquals('address', $address->getLayer()); + $this->assertEquals(1, $address->getConfidence()); + $this->assertEquals('exact', $address->getMatchType()); + $this->assertEquals('point', $address->getAccuracy()); + } + + public function testWithSource(): void + { + $address = new PeliasAddress('Pelias', new AdminLevelCollection()); + $newAddress = $address->withSource('openaddresses'); + $this->assertEquals('openaddresses', $newAddress->getSource()); + $this->assertNull($address->getSource()); + } + + public function testWithLayer(): void + { + $address = new PeliasAddress('Pelias', new AdminLevelCollection()); + $newAddress = $address->withLayer('address'); + $this->assertEquals('address', $newAddress->getLayer()); + $this->assertNull($address->getLayer()); + } + + public function testWithConfidence(): void + { + $address = new PeliasAddress('Pelias', new AdminLevelCollection()); + $newAddress = $address->withConfidence(1); + $this->assertEquals(1, $newAddress->getConfidence()); + $this->assertNull($address->getConfidence()); + } + + public function testWithMatchType(): void + { + $address = new PeliasAddress('Pelias', new AdminLevelCollection()); + $newAddress = $address->withMatchType('exact'); + $this->assertEquals('exact', $newAddress->getMatchType()); + $this->assertNull($address->getMatchType()); + } + + public function testWithAccuracy(): void + { + $address = new PeliasAddress('Pelias', new AdminLevelCollection()); + $newAddress = $address->withAccuracy('point'); + $this->assertEquals('point', $newAddress->getAccuracy()); + $this->assertNull($address->getAccuracy()); + } +}