Skip to content

Commit 7dadc1c

Browse files
committed
Refactor providers to leverage ResultFactories - fix #232
1 parent eb915ec commit 7dadc1c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2783
-952
lines changed

src/Geocoder/Geocoder.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class Geocoder implements GeocoderInterface
2424
*/
2525
const VERSION = '1.5.2-dev';
2626

27+
/**
28+
* @var integer
29+
*/
30+
const MAX_RESULTS = 5;
31+
2732
/**
2833
* @var ProviderInterface[]
2934
*/
@@ -39,15 +44,23 @@ class Geocoder implements GeocoderInterface
3944
*/
4045
private $resultFactory;
4146

47+
/**
48+
* @var integer
49+
*/
50+
private $maxResults;
51+
4252
/**
4353
* @param ProviderInterface $provider
4454
* @param ResultFactoryInterface $resultFactory
55+
* @param integer $maxResults
4556
*/
46-
public function __construct(ProviderInterface $provider = null, ResultFactoryInterface $resultFactory = null)
57+
public function __construct(ProviderInterface $provider = null, ResultFactoryInterface $resultFactory = null,
58+
$maxResults = self::MAX_RESULTS)
4759
{
4860
$this->provider = $provider;
4961

5062
$this->setResultFactory($resultFactory);
63+
$this->setMaxResults($maxResults);
5164
}
5265

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

74+
/**
75+
* @param integer $maxResults
76+
*
77+
* @return GeocoderInterface
78+
*/
79+
public function setMaxResults($maxResults)
80+
{
81+
$this->maxResults = $maxResults;
82+
83+
return $this;
84+
}
85+
86+
/**
87+
* @return integer $maxResults
88+
*/
89+
public function getMaxResults()
90+
{
91+
return $this->maxResults;
92+
}
93+
6194
/**
6295
* {@inheritDoc}
6396
*/
@@ -68,8 +101,9 @@ public function geocode($value)
68101
return $this->returnResult(array());
69102
}
70103

71-
$data = $this->getProvider()->getGeocodedData(trim($value));
72-
$result = $this->returnResult($data);
104+
$provider = $this->getProvider()->setMaxResults($this->getMaxResults());
105+
$data = $provider->getGeocodedData(trim($value));
106+
$result = $this->returnResult($data);
73107

74108
return $result;
75109
}
@@ -84,8 +118,9 @@ public function reverse($latitude, $longitude)
84118
return $this->returnResult(array());
85119
}
86120

87-
$data = $this->getProvider()->getReversedData(array($latitude, $longitude));
88-
$result = $this->returnResult($data);
121+
$provider = $this->getProvider()->setMaxResults($this->getMaxResults());
122+
$data = $provider->getReversedData(array($latitude, $longitude));
123+
$result = $this->returnResult($data);
89124

90125
return $result;
91126
}

src/Geocoder/Provider/AbstractProvider.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace Geocoder\Provider;
1212

13+
use Geocoder\Geocoder;
1314
use Geocoder\HttpAdapter\HttpAdapterInterface;
1415

1516
/**
@@ -27,6 +28,11 @@ abstract class AbstractProvider
2728
*/
2829
protected $locale = null;
2930

31+
/**
32+
* @var integer
33+
*/
34+
protected $maxResults = Geocoder::MAX_RESULTS;
35+
3036
/**
3137
* @param HttpAdapterInterface $adapter An HTTP adapter.
3238
* @param string $locale A locale (optional).
@@ -85,6 +91,30 @@ public function setLocale($locale = null)
8591
return $this;
8692
}
8793

94+
/**
95+
* Sets the maximum of returned results.
96+
*
97+
* @param integer $maxResults
98+
*
99+
* @return AbstractProvider
100+
*/
101+
public function setMaxResults($maxResults)
102+
{
103+
$this->maxResults = $maxResults;
104+
105+
return $this;
106+
}
107+
108+
/**
109+
* Returns the maximum of wished results.
110+
*
111+
* @return integer
112+
*/
113+
public function getMaxResults()
114+
{
115+
return $this->maxResults;
116+
}
117+
88118
/**
89119
* Returns the default results.
90120
*

src/Geocoder/Provider/ArcGISOnlineProvider.php

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class ArcGISOnlineProvider extends AbstractProvider implements ProviderInterface
4242
/**
4343
* @param HttpAdapterInterface $adapter An HTTP adapter.
4444
* @param string $sourceCountry Country biasing (optional).
45-
* @param bool $useSsl Whether to use an SSL connection (optional)
45+
* @param bool $useSsl Whether to use an SSL connection (optional).
4646
*/
4747
public function __construct(HttpAdapterInterface $adapter, $sourceCountry = null, $useSsl = false)
4848
{
@@ -66,11 +66,7 @@ public function getGeocodedData($address)
6666
throw new NoResultException('Invalid address.');
6767
}
6868

69-
$query = sprintf(
70-
static::ENDPOINT_URL,
71-
$this->protocol,
72-
urlencode($address)
73-
);
69+
$query = sprintf(self::ENDPOINT_URL, $this->protocol, urlencode($address));
7470

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

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

82-
$location = reset($json->locations);
83-
$data = $location->feature->attributes;
84-
85-
$coordinates = (array) $location->feature->geometry;
86-
$streetName = !empty($data->Match_addr) ? $data->Match_addr : null;
87-
$streetNumber = !empty($data->AddNum) ? $data->AddNum : null;
88-
$city = !empty($data->City) ? $data->City : null;
89-
$zipcode = !empty($data->Postal) ? $data->Postal : null;
90-
$region = !empty($data->Region) ? $data->Region : null;
91-
$county = !empty($data->Subregion) ? $data->Subregion : null;
92-
$countryCode = !empty($data->Country) ? $data->Country : null;
78+
$results = array();
79+
80+
foreach ($json->locations as $location) {
81+
$data = $location->feature->attributes;
82+
83+
$coordinates = (array) $location->feature->geometry;
84+
$streetName = !empty($data->Match_addr) ? $data->Match_addr : null;
85+
$streetNumber = !empty($data->AddNum) ? $data->AddNum : null;
86+
$city = !empty($data->City) ? $data->City : null;
87+
$zipcode = !empty($data->Postal) ? $data->Postal : null;
88+
$region = !empty($data->Region) ? $data->Region : null;
89+
$county = !empty($data->Subregion) ? $data->Subregion : null;
90+
$countryCode = !empty($data->Country) ? $data->Country : null;
91+
92+
$results[] = array_merge($this->getDefaults(), array(
93+
'latitude' => $coordinates['y'],
94+
'longitude' => $coordinates['x'],
95+
'streetNumber' => $streetNumber,
96+
'streetName' => $streetName,
97+
'city' => $city,
98+
'zipcode' => $zipcode,
99+
'region' => $region,
100+
'countryCode' => $countryCode,
101+
'county' => $county,
102+
));
103+
}
93104

94-
return array_merge($this->getDefaults(), array(
95-
'latitude' => $coordinates['y'],
96-
'longitude' => $coordinates['x'],
97-
'streetNumber' => $streetNumber,
98-
'streetName' => $streetName,
99-
'city' => $city,
100-
'zipcode' => $zipcode,
101-
'region' => $region,
102-
'countryCode' => $countryCode,
103-
'county' => $county,
104-
));
105+
return $results;
105106
}
106107

107108
/**
108109
* {@inheritDoc}
109110
*/
110111
public function getReversedData(array $coordinates)
111112
{
112-
$query = sprintf(
113-
static::REVERSE_ENDPOINT_URL,
114-
$this->protocol,
115-
$coordinates[1],
116-
$coordinates[0]
117-
);
113+
$query = sprintf(self::REVERSE_ENDPOINT_URL, $this->protocol, $coordinates[1], $coordinates[0]);
118114

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

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

134-
return array_merge($this->getDefaults(), array(
130+
return array(array_merge($this->getDefaults(), array(
135131
'latitude' => $coordinates[0],
136132
'longitude' => $coordinates[1],
137133
'streetName' => $streetName,
@@ -140,7 +136,7 @@ public function getReversedData(array $coordinates)
140136
'region' => $region,
141137
'countryCode' => $countryCode,
142138
'county' => $county,
143-
));
139+
)));
144140
}
145141

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

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

src/Geocoder/Provider/BaiduProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ protected function executeQuery($query)
110110
throw new InvalidCredentialsException('API Key provided is not valid.');
111111
}
112112

113-
return array_merge($this->getDefaults(), array(
113+
return array(array_merge($this->getDefaults(), array(
114114
'latitude' => isset($data['result']['location']['lat']) ? $data['result']['location']['lat'] : null,
115115
'longitude' => isset($data['result']['location']['lng']) ? $data['result']['location']['lng'] : null,
116116
'streetNumber' => isset($data['result']['addressComponent']['street_number']) ? $data['result']['addressComponent']['street_number'] : null,
@@ -119,6 +119,6 @@ protected function executeQuery($query)
119119
'cityDistrict' => isset($data['result']['addressComponent']['district']) ? $data['result']['addressComponent']['district'] : null,
120120
'county' => isset($data['result']['addressComponent']['province']) ? $data['result']['addressComponent']['province'] : null,
121121
'countyCode' => isset($data['result']['cityCode']) ? $data['result']['cityCode'] : null,
122-
));
122+
)));
123123
}
124124
}

src/Geocoder/Provider/BingMapsProvider.php

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class BingMapsProvider extends AbstractProvider implements ProviderInterface
2323
/**
2424
* @var string
2525
*/
26-
const GEOCODE_ENDPOINT_URL = 'http://dev.virtualearth.net/REST/v1/Locations/?q=%s&key=%s';
26+
const GEOCODE_ENDPOINT_URL = 'http://dev.virtualearth.net/REST/v1/Locations/?maxResults=%d&q=%s&key=%s';
2727

2828
/**
2929
* @var string
@@ -61,7 +61,7 @@ public function getGeocodedData($address)
6161
throw new UnsupportedException('The BingMapsProvider does not support IP addresses.');
6262
}
6363

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

6666
return $this->executeQuery($query);
6767
}
@@ -107,43 +107,49 @@ protected function executeQuery($query)
107107

108108
$json = json_decode($content);
109109

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

116-
$coordinates = (array) $data['geocodePoints'][0]->coordinates;
117-
118-
$bounds = null;
119-
if (isset($data['bbox']) && is_array($data['bbox']) && count($data['bbox']) > 0) {
120-
$bounds = array(
121-
'south' => $data['bbox'][0],
122-
'west' => $data['bbox'][1],
123-
'north' => $data['bbox'][2],
124-
'east' => $data['bbox'][3]
125-
);
114+
$data = (array) $json->resourceSets[0]->resources;
115+
116+
$results = array();
117+
118+
foreach ($data as $item) {
119+
$coordinates = (array) $item->geocodePoints[0]->coordinates;
120+
121+
$bounds = null;
122+
if (isset($item->bbox) && is_array($item->bbox) && count($item->bbox) > 0) {
123+
$bounds = array(
124+
'south' => $item->bbox[0],
125+
'west' => $item->bbox[1],
126+
'north' => $item->bbox[2],
127+
'east' => $item->bbox[3]
128+
);
129+
}
130+
131+
$streetNumber = null;
132+
$streetName = property_exists($item->address, 'addressLine') ? (string) $item->address->addressLine : '';
133+
$zipcode = property_exists($item->address, 'postalCode') ? (string) $item->address->postalCode : '';
134+
$city = property_exists($item->address, 'locality') ? (string) $item->address->locality: '';
135+
$county = property_exists($item->address, 'adminDistrict2') ? (string) $item->address->adminDistrict2 : '';
136+
$region = property_exists($item->address, 'adminDistrict') ? (string) $item->address->adminDistrict: '';
137+
$country = property_exists($item->address, 'countryRegion') ? (string) $item->address->countryRegion: '';
138+
139+
$results[] = array_merge($this->getDefaults(), array(
140+
'latitude' => $coordinates[0],
141+
'longitude' => $coordinates[1],
142+
'bounds' => $bounds,
143+
'streetNumber' => $streetNumber,
144+
'streetName' => $streetName,
145+
'city' => empty($city) ? null : $city,
146+
'zipcode' => empty($zipcode) ? null : $zipcode,
147+
'county' => empty($county) ? null : $county,
148+
'region' => empty($region) ? null : $region,
149+
'country' => empty($country) ? null : $country,
150+
));
126151
}
127152

128-
$streetNumber = null;
129-
$streetName = property_exists($data['address'], 'addressLine') ? (string) $data['address']->addressLine : '';
130-
$zipcode = property_exists($data['address'], 'postalCode') ? (string) $data['address']->postalCode : '';
131-
$city = property_exists($data['address'], 'locality') ? (string) $data['address']->locality: '';
132-
$county = property_exists($data['address'], 'adminDistrict2') ? (string) $data['address']->adminDistrict2 : '';
133-
$region = property_exists($data['address'], 'adminDistrict') ? (string) $data['address']->adminDistrict: '';
134-
$country = property_exists($data['address'], 'countryRegion') ? (string) $data['address']->countryRegion: '';
135-
136-
return array_merge($this->getDefaults(), array(
137-
'latitude' => $coordinates[0],
138-
'longitude' => $coordinates[1],
139-
'bounds' => $bounds,
140-
'streetNumber' => $streetNumber,
141-
'streetName' => $streetName,
142-
'city' => empty($city) ? null : $city,
143-
'zipcode' => empty($zipcode) ? null : $zipcode,
144-
'county' => empty($county) ? null : $county,
145-
'region' => empty($region) ? null : $region,
146-
'country' => empty($country) ? null : $country,
147-
));
153+
return $results;
148154
}
149155
}

0 commit comments

Comments
 (0)