Skip to content

Refactor providers to leverage ResultFactories - fix #232 #233

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

Merged
Merged
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
45 changes: 40 additions & 5 deletions src/Geocoder/Geocoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class Geocoder implements GeocoderInterface
*/
const VERSION = '1.5.2-dev';

/**
* @var integer
*/
const MAX_RESULTS = 5;

/**
* @var ProviderInterface[]
*/
Expand All @@ -39,15 +44,23 @@ class Geocoder implements GeocoderInterface
*/
private $resultFactory;

/**
* @var integer
*/
private $maxResults;

/**
* @param ProviderInterface $provider
* @param ResultFactoryInterface $resultFactory
* @param integer $maxResults
*/
public function __construct(ProviderInterface $provider = null, ResultFactoryInterface $resultFactory = null)
public function __construct(ProviderInterface $provider = null, ResultFactoryInterface $resultFactory = null,
$maxResults = self::MAX_RESULTS)
{
$this->provider = $provider;

$this->setResultFactory($resultFactory);
$this->setMaxResults($maxResults);
}

/**
Expand All @@ -58,6 +71,26 @@ public function setResultFactory(ResultFactoryInterface $resultFactory = null)
$this->resultFactory = $resultFactory ?: new DefaultResultFactory();
}

/**
* @param integer $maxResults
*
* @return GeocoderInterface
*/
public function setMaxResults($maxResults)
{
$this->maxResults = $maxResults;

return $this;
}

/**
* @return integer $maxResults
*/
public function getMaxResults()
{
return $this->maxResults;
}

/**
* {@inheritDoc}
*/
Expand All @@ -68,8 +101,9 @@ public function geocode($value)
return $this->returnResult(array());
}

$data = $this->getProvider()->getGeocodedData(trim($value));
$result = $this->returnResult($data);
$provider = $this->getProvider()->setMaxResults($this->getMaxResults());
$data = $provider->getGeocodedData(trim($value));
$result = $this->returnResult($data);

return $result;
}
Expand All @@ -84,8 +118,9 @@ public function reverse($latitude, $longitude)
return $this->returnResult(array());
}

$data = $this->getProvider()->getReversedData(array($latitude, $longitude));
$result = $this->returnResult($data);
$provider = $this->getProvider()->setMaxResults($this->getMaxResults());
$data = $provider->getReversedData(array($latitude, $longitude));
$result = $this->returnResult($data);

return $result;
}
Expand Down
30 changes: 30 additions & 0 deletions src/Geocoder/Provider/AbstractProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Geocoder\Provider;

use Geocoder\Geocoder;
use Geocoder\HttpAdapter\HttpAdapterInterface;

/**
Expand All @@ -27,6 +28,11 @@ abstract class AbstractProvider
*/
protected $locale = null;

/**
* @var integer
*/
protected $maxResults = Geocoder::MAX_RESULTS;

/**
* @param HttpAdapterInterface $adapter An HTTP adapter.
* @param string $locale A locale (optional).
Expand Down Expand Up @@ -85,6 +91,30 @@ public function setLocale($locale = null)
return $this;
}

/**
* Sets the maximum of returned results.
*
* @param integer $maxResults
*
* @return AbstractProvider
*/
public function setMaxResults($maxResults)
{
$this->maxResults = $maxResults;

return $this;
}

/**
* Returns the maximum of wished results.
*
* @return integer
*/
public function getMaxResults()
{
return $this->maxResults;
}

/**
* Returns the default results.
*
Expand Down
70 changes: 33 additions & 37 deletions src/Geocoder/Provider/ArcGISOnlineProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ArcGISOnlineProvider extends AbstractProvider implements ProviderInterface
/**
* @param HttpAdapterInterface $adapter An HTTP adapter.
* @param string $sourceCountry Country biasing (optional).
* @param bool $useSsl Whether to use an SSL connection (optional)
* @param bool $useSsl Whether to use an SSL connection (optional).
*/
public function __construct(HttpAdapterInterface $adapter, $sourceCountry = null, $useSsl = false)
{
Expand All @@ -66,11 +66,7 @@ public function getGeocodedData($address)
throw new NoResultException('Invalid address.');
}

$query = sprintf(
static::ENDPOINT_URL,
$this->protocol,
urlencode($address)
);
$query = sprintf(self::ENDPOINT_URL, $this->protocol, urlencode($address));

$json = $this->executeQuery($query);

Expand All @@ -79,42 +75,42 @@ public function getGeocodedData($address)
throw new NoResultException(sprintf('No results found for query %s', $query));
}

$location = reset($json->locations);
$data = $location->feature->attributes;

$coordinates = (array) $location->feature->geometry;
$streetName = !empty($data->Match_addr) ? $data->Match_addr : null;
$streetNumber = !empty($data->AddNum) ? $data->AddNum : null;
$city = !empty($data->City) ? $data->City : null;
$zipcode = !empty($data->Postal) ? $data->Postal : null;
$region = !empty($data->Region) ? $data->Region : null;
$county = !empty($data->Subregion) ? $data->Subregion : null;
$countryCode = !empty($data->Country) ? $data->Country : null;
$results = array();

foreach ($json->locations as $location) {
$data = $location->feature->attributes;

$coordinates = (array) $location->feature->geometry;
$streetName = !empty($data->Match_addr) ? $data->Match_addr : null;
$streetNumber = !empty($data->AddNum) ? $data->AddNum : null;
$city = !empty($data->City) ? $data->City : null;
$zipcode = !empty($data->Postal) ? $data->Postal : null;
$region = !empty($data->Region) ? $data->Region : null;
$county = !empty($data->Subregion) ? $data->Subregion : null;
$countryCode = !empty($data->Country) ? $data->Country : null;

$results[] = array_merge($this->getDefaults(), array(
'latitude' => $coordinates['y'],
'longitude' => $coordinates['x'],
'streetNumber' => $streetNumber,
'streetName' => $streetName,
'city' => $city,
'zipcode' => $zipcode,
'region' => $region,
'countryCode' => $countryCode,
'county' => $county,
));
}

return array_merge($this->getDefaults(), array(
'latitude' => $coordinates['y'],
'longitude' => $coordinates['x'],
'streetNumber' => $streetNumber,
'streetName' => $streetName,
'city' => $city,
'zipcode' => $zipcode,
'region' => $region,
'countryCode' => $countryCode,
'county' => $county,
));
return $results;
}

/**
* {@inheritDoc}
*/
public function getReversedData(array $coordinates)
{
$query = sprintf(
static::REVERSE_ENDPOINT_URL,
$this->protocol,
$coordinates[1],
$coordinates[0]
);
$query = sprintf(self::REVERSE_ENDPOINT_URL, $this->protocol, $coordinates[1], $coordinates[0]);

$json = $this->executeQuery($query);

Expand All @@ -131,7 +127,7 @@ public function getReversedData(array $coordinates)
$county = !empty($data->Subregion) ? $data->Subregion : null;
$countryCode = !empty($data->CountryCode) ? $data->CountryCode : null;

return array_merge($this->getDefaults(), array(
return array(array_merge($this->getDefaults(), array(
'latitude' => $coordinates[0],
'longitude' => $coordinates[1],
'streetName' => $streetName,
Expand All @@ -140,7 +136,7 @@ public function getReversedData(array $coordinates)
'region' => $region,
'countryCode' => $countryCode,
'county' => $county,
));
)));
}

/**
Expand All @@ -162,7 +158,7 @@ protected function buildQuery($query)
$query = sprintf('%s&sourceCountry=%s', $query, $this->getSourceCountry());
}

$query = sprintf('%s&maxLocations=%d', $query, 1); // Limit results to 1
$query = sprintf('%s&maxLocations=%d', $query, $this->getMaxResults());
$query = sprintf('%s&f=%s', $query, 'json'); // set format to json
$query = sprintf('%s&outFields=*', $query); // Get all result fields

Expand Down
4 changes: 2 additions & 2 deletions src/Geocoder/Provider/BaiduProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ protected function executeQuery($query)
throw new InvalidCredentialsException('API Key provided is not valid.');
}

return array_merge($this->getDefaults(), array(
return array(array_merge($this->getDefaults(), array(
'latitude' => isset($data['result']['location']['lat']) ? $data['result']['location']['lat'] : null,
'longitude' => isset($data['result']['location']['lng']) ? $data['result']['location']['lng'] : null,
'streetNumber' => isset($data['result']['addressComponent']['street_number']) ? $data['result']['addressComponent']['street_number'] : null,
Expand All @@ -119,6 +119,6 @@ protected function executeQuery($query)
'cityDistrict' => isset($data['result']['addressComponent']['district']) ? $data['result']['addressComponent']['district'] : null,
'county' => isset($data['result']['addressComponent']['province']) ? $data['result']['addressComponent']['province'] : null,
'countyCode' => isset($data['result']['cityCode']) ? $data['result']['cityCode'] : null,
));
)));
}
}
76 changes: 41 additions & 35 deletions src/Geocoder/Provider/BingMapsProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class BingMapsProvider extends AbstractProvider implements ProviderInterface
/**
* @var string
*/
const GEOCODE_ENDPOINT_URL = 'http://dev.virtualearth.net/REST/v1/Locations/?q=%s&key=%s';
const GEOCODE_ENDPOINT_URL = 'http://dev.virtualearth.net/REST/v1/Locations/?maxResults=%d&q=%s&key=%s';

/**
* @var string
Expand Down Expand Up @@ -61,7 +61,7 @@ public function getGeocodedData($address)
throw new UnsupportedException('The BingMapsProvider does not support IP addresses.');
}

$query = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address), $this->apiKey);
$query = sprintf(self::GEOCODE_ENDPOINT_URL, $this->getMaxResults(), urlencode($address), $this->apiKey);

return $this->executeQuery($query);
}
Expand Down Expand Up @@ -107,43 +107,49 @@ protected function executeQuery($query)

$json = json_decode($content);

if (isset($json->resourceSets[0]) && isset($json->resourceSets[0]->resources[0])) {
$data = (array) $json->resourceSets[0]->resources[0];
} else {
if (!isset($json->resourceSets[0]) || !isset($json->resourceSets[0]->resources)) {
throw new NoResultException(sprintf('Could not execute query %s', $query));
}

$coordinates = (array) $data['geocodePoints'][0]->coordinates;

$bounds = null;
if (isset($data['bbox']) && is_array($data['bbox']) && count($data['bbox']) > 0) {
$bounds = array(
'south' => $data['bbox'][0],
'west' => $data['bbox'][1],
'north' => $data['bbox'][2],
'east' => $data['bbox'][3]
);
$data = (array) $json->resourceSets[0]->resources;

$results = array();

foreach ($data as $item) {
$coordinates = (array) $item->geocodePoints[0]->coordinates;

$bounds = null;
if (isset($item->bbox) && is_array($item->bbox) && count($item->bbox) > 0) {
$bounds = array(
'south' => $item->bbox[0],
'west' => $item->bbox[1],
'north' => $item->bbox[2],
'east' => $item->bbox[3]
);
}

$streetNumber = null;
$streetName = property_exists($item->address, 'addressLine') ? (string) $item->address->addressLine : '';
$zipcode = property_exists($item->address, 'postalCode') ? (string) $item->address->postalCode : '';
$city = property_exists($item->address, 'locality') ? (string) $item->address->locality: '';
$county = property_exists($item->address, 'adminDistrict2') ? (string) $item->address->adminDistrict2 : '';
$region = property_exists($item->address, 'adminDistrict') ? (string) $item->address->adminDistrict: '';
$country = property_exists($item->address, 'countryRegion') ? (string) $item->address->countryRegion: '';

$results[] = array_merge($this->getDefaults(), array(
'latitude' => $coordinates[0],
'longitude' => $coordinates[1],
'bounds' => $bounds,
'streetNumber' => $streetNumber,
'streetName' => $streetName,
'city' => empty($city) ? null : $city,
'zipcode' => empty($zipcode) ? null : $zipcode,
'county' => empty($county) ? null : $county,
'region' => empty($region) ? null : $region,
'country' => empty($country) ? null : $country,
));
}

$streetNumber = null;
$streetName = property_exists($data['address'], 'addressLine') ? (string) $data['address']->addressLine : '';
$zipcode = property_exists($data['address'], 'postalCode') ? (string) $data['address']->postalCode : '';
$city = property_exists($data['address'], 'locality') ? (string) $data['address']->locality: '';
$county = property_exists($data['address'], 'adminDistrict2') ? (string) $data['address']->adminDistrict2 : '';
$region = property_exists($data['address'], 'adminDistrict') ? (string) $data['address']->adminDistrict: '';
$country = property_exists($data['address'], 'countryRegion') ? (string) $data['address']->countryRegion: '';

return array_merge($this->getDefaults(), array(
'latitude' => $coordinates[0],
'longitude' => $coordinates[1],
'bounds' => $bounds,
'streetNumber' => $streetNumber,
'streetName' => $streetName,
'city' => empty($city) ? null : $city,
'zipcode' => empty($zipcode) ? null : $zipcode,
'county' => empty($county) ? null : $county,
'region' => empty($region) ? null : $region,
'country' => empty($country) ? null : $country,
));
return $results;
}
}
Loading