Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Pelias] custom address fields #1203

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Provider/Pelias/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
190 changes: 190 additions & 0 deletions src/Provider/Pelias/Model/PeliasAddress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Geocoder package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

namespace Geocoder\Provider\Pelias\Model;

use Geocoder\Model\Address;

class PeliasAddress extends Address
{
/**
* The pelias layer returned.
*
* @see https://github.com/pelias/documentation/blob/master/result_quality.md#layer
*/
private ?string $layer = null;

/**
* Confidence score from pelias.
*
* @see https://github.com/pelias/documentation/blob/master/result_quality.md#confidence
*/
private ?float $confidence = null;

/**
* Match type from pelias.
*
* @see https://github.com/pelias/documentation/blob/master/result_quality.md#match_type
*/
private ?string $matchType = null;

/**
* Data source from pelias.
*
* @see https://github.com/pelias/documentation/blob/master/data-sources.md
*/
private ?string $source = null;

/**
* Accuracy from pelias.
*
* @see https://github.com/pelias/documentation/blob/master/result_quality.md#accuracy
*/
private ?string $accuracy = null;

public static function createFromArray(array $data)
{
$address = parent::createFromArray($data);
$address->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;
}
}
82 changes: 45 additions & 37 deletions src/Provider/Pelias/Pelias.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<mixed> $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,
]);
}

/**
Expand Down
Loading