Skip to content

Commit 149c880

Browse files
committed
Merge pull request #307 from toin0u/feature-geocoderca-premium
Add premium support to GeocoderCaProvider + tests
2 parents 972eed7 + 3990202 commit 149c880

12 files changed

+292
-21
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ The `OIORestProvider` named `oio_rest` is able to geocode and reverse geocode **
204204
### GeocoderCaProvider ###
205205

206206
The `GeocoderCaProvider` named `geocoder_ca` is able to geocode and reverse geocode **street addresses**, exclusively in USA & Canada.
207+
An optional api key can be provided. This provider also supports SSL.
207208

208209

209210
### GeocoderUsProvider ###

src/Geocoder/Provider/GeocoderCaProvider.php

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
use Geocoder\Exception\UnsupportedException;
1414
use Geocoder\Exception\NoResultException;
15+
use Geocoder\Exception\QuotaExceededException;
16+
use Geocoder\Exception\InvalidCredentialsException;
17+
use Geocoder\HttpAdapter\HttpAdapterInterface;
1518

1619
/**
1720
* @author Antoine Corcy <[email protected]>
@@ -21,12 +24,35 @@ class GeocoderCaProvider extends AbstractProvider implements ProviderInterface
2124
/**
2225
* @var string
2326
*/
24-
const GEOCODE_ENDPOINT_URL = 'http://geocoder.ca/?geoit=xml&locate=%s';
27+
const GEOCODE_ENDPOINT_URL = '%s://geocoder.ca/?geoit=xml&locate=%s&auth=%s';
2528

2629
/**
2730
* @var string
2831
*/
29-
const REVERSE_ENDPOINT_URL = 'http://geocoder.ca/?geoit=xml&reverse=1&latt=%F&longt=%F';
32+
const REVERSE_ENDPOINT_URL = '%s://geocoder.ca/?geoit=xml&reverse=1&latt=%F&longt=%F&auth=%s';
33+
34+
/**
35+
* @var string
36+
*/
37+
private $scheme = 'http';
38+
39+
/**
40+
* @var string
41+
*/
42+
private $apiKey = null;
43+
44+
/**
45+
* @param HttpAdapterInterface $adapter An HTTP adapter.
46+
* @param bool $useSsl Whether to use an SSL connection (optional).
47+
* @param string $apiKey An API key (optional).
48+
*/
49+
public function __construct(HttpAdapterInterface $adapter, $useSsl = false, $apiKey = null)
50+
{
51+
parent::__construct($adapter);
52+
53+
$this->scheme = $useSsl ? 'https' : $this->scheme;
54+
$this->apiKey = $apiKey;
55+
}
3056

3157
/**
3258
* {@inheritDoc}
@@ -38,17 +64,21 @@ public function getGeocodedData($address)
3864
throw new UnsupportedException('The GeocoderCaProvider does not support IP addresses.');
3965
}
4066

41-
$query = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address));
42-
$content = $this->getAdapter()->getContent($query);
67+
$query = sprintf(self::GEOCODE_ENDPOINT_URL, $this->scheme, urlencode($address), $this->apiKey);
4368

44-
$doc = new \DOMDocument();
45-
if (!@$doc->loadXML($content) || $doc->getElementsByTagName('error')->length) {
69+
try {
70+
$content = $this->handleQuery($query);
71+
} catch (InvalidCredentialsException $e) {
72+
throw $e;
73+
} catch (QuotaExceededException $e) {
74+
throw $e;
75+
} catch (NoResultException $e) {
4676
throw new NoResultException(sprintf('Could not execute query %s', $query));
4777
}
4878

4979
return array(array_merge($this->getDefaults(), array(
50-
'latitude' => $this->getNodeValue($doc->getElementsByTagName('latt')),
51-
'longitude' => $this->getNodeValue($doc->getElementsByTagName('longt'))
80+
'latitude' => $this->getNodeValue($content->getElementsByTagName('latt')),
81+
'longitude' => $this->getNodeValue($content->getElementsByTagName('longt'))
5282
)));
5383
}
5484

@@ -57,22 +87,26 @@ public function getGeocodedData($address)
5787
*/
5888
public function getReversedData(array $coordinates)
5989
{
60-
$query = sprintf(self::REVERSE_ENDPOINT_URL, $coordinates[0], $coordinates[1]);
61-
$content = $this->getAdapter()->getContent($query);
90+
$query = sprintf(self::REVERSE_ENDPOINT_URL, $this->scheme, $coordinates[0], $coordinates[1], $this->apiKey);
6291

63-
$doc = new \DOMDocument();
64-
if (!@$doc->loadXML($content) || $doc->getElementsByTagName('error')->length) {
92+
try {
93+
$content = $this->handleQuery($query);
94+
} catch (InvalidCredentialsException $e) {
95+
throw $e;
96+
} catch (QuotaExceededException $e) {
97+
throw $e;
98+
} catch (NoResultException $e) {
6599
throw new NoResultException(sprintf('Could not resolve coordinates %s', implode(', ', $coordinates)));
66100
}
67101

68102
return array(array_merge($this->getDefaults(), array(
69-
'latitude' => $this->getNodeValue($doc->getElementsByTagName('latt')),
70-
'longitude' => $this->getNodeValue($doc->getElementsByTagName('longt')),
71-
'streetNumber' => $this->getNodeValue($doc->getElementsByTagName('stnumber')),
72-
'streetName' => $this->getNodeValue($doc->getElementsByTagName('staddress')),
73-
'city' => $this->getNodeValue($doc->getElementsByTagName('city')),
74-
'zipcode' => $this->getNodeValue($doc->getElementsByTagName('postal')),
75-
'cityDistrict' => $this->getNodeValue($doc->getElementsByTagName('prov')),
103+
'latitude' => $this->getNodeValue($content->getElementsByTagName('latt')),
104+
'longitude' => $this->getNodeValue($content->getElementsByTagName('longt')),
105+
'streetNumber' => $this->getNodeValue($content->getElementsByTagName('stnumber')),
106+
'streetName' => $this->getNodeValue($content->getElementsByTagName('staddress')),
107+
'city' => $this->getNodeValue($content->getElementsByTagName('city')),
108+
'zipcode' => $this->getNodeValue($content->getElementsByTagName('postal')),
109+
'cityDistrict' => $this->getNodeValue($content->getElementsByTagName('prov')),
76110
)));
77111
}
78112

@@ -93,4 +127,31 @@ private function getNodeValue(\DOMNodeList $element)
93127
{
94128
return $element->length ? $element->item(0)->nodeValue : null;
95129
}
130+
131+
/**
132+
* @param string $query
133+
* @throws InvalidCredentialsException
134+
* @throws QuotaExceededException
135+
* @throws NoResultException
136+
* @return \DOMDocument
137+
*/
138+
private function handleQuery($query)
139+
{
140+
$content = $this->getAdapter()->getContent($query);
141+
142+
$doc = new \DOMDocument;
143+
if (!@$doc->loadXML($content) || $doc->getElementsByTagName('error')->length) {
144+
switch ($this->getNodeValue($doc->getElementsByTagName('code'))) {
145+
case '001':
146+
case '003':
147+
throw new InvalidCredentialsException(sprintf('Invalid authentification token %s', $query));
148+
case '002':
149+
throw new QuotaExceededException(sprintf('Account ran out of credits %s', $query));
150+
default:
151+
throw new NoResultException;
152+
}
153+
}
154+
155+
return $doc;
156+
}
96157
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
s:754:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<result>
3+
<geodata>
4+
5+
<latt>40.707507</latt>
6+
<longt>-74.011255</longt>
7+
<city>New York</city>
8+
<prov>NY</prov>
9+
<postal>10005</postal>
10+
<stnumber>2</stnumber>
11+
<staddress>New St</staddress>
12+
<inlatt>40.707507</inlatt>
13+
<inlongt>-74.011255</inlongt>
14+
<distance>0</distance>
15+
16+
17+
18+
<usa>
19+
<latt>40.707507</latt>
20+
<longt>-74.011255</longt>
21+
<uscity>New York</uscity>
22+
<state>NY</state>
23+
<zip>10005</zip>
24+
<usstnumber>2</usstnumber>
25+
<usstaddress>New St</usstaddress>
26+
<inlatt>40.707507</inlatt>
27+
<inlongt>-74.011255</inlongt>
28+
<distance>0</distance>
29+
30+
</usa>
31+
32+
33+
</geodata>
34+
</result>
35+
";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
s:266:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<latt>38.8987483023256</latt>
4+
<longt>-77.0376837441861</longt>
5+
6+
<standard>
7+
<stnumber>1600</stnumber><staddress>Pennsylvania Ave</staddress><city>Washington</city><prov>DC</prov></standard>
8+
</geodata>
9+
";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
s:296:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<error>
4+
<code>009</code>
5+
<description>The latitude and longitude you provided are not in the valid range.</description>
6+
</error>
7+
<inlatt>1</inlatt>
8+
<inlongt>-2</inlongt>
9+
10+
</geodata>
11+
";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
s:259:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<error>
4+
<code>005</code>
5+
<description>Postal Code is not in the proper Format.</description>
6+
</error>
7+
<latt></latt>
8+
<longt>-</longt>
9+
10+
</geodata>
11+
";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
s:263:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<error>
4+
<code>003</code>
5+
<description>Authentication token: bad-api-key not found.</description>
6+
</error>
7+
<latt></latt>
8+
<longt>-</longt>
9+
10+
</geodata>
11+
";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
s:266:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<latt>38.8987483023256</latt>
4+
<longt>-77.0376837441861</longt>
5+
6+
<standard>
7+
<stnumber>1600</stnumber><staddress>Pennsylvania Ave</staddress><city>Washington</city><prov>DC</prov></standard>
8+
</geodata>
9+
";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
s:275:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<geodata>
3+
<latt>49.831515</latt>
4+
<longt>-119.381857</longt>
5+
<postal>V1W3Z9</postal>
6+
<standard>
7+
<stnumber>4208</stnumber><staddress>GALLAGHERS S</staddress><city>Kelowna</city><prov>BC</prov></standard>
8+
</geodata>
9+
";
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
s:754:"<?xml version="1.0" encoding="UTF-8" ?>
2+
<result>
3+
<geodata>
4+
5+
<latt>40.707507</latt>
6+
<longt>-74.011255</longt>
7+
<city>New York</city>
8+
<prov>NY</prov>
9+
<postal>10005</postal>
10+
<stnumber>2</stnumber>
11+
<staddress>New St</staddress>
12+
<inlatt>40.707507</inlatt>
13+
<inlongt>-74.011255</inlongt>
14+
<distance>0</distance>
15+
16+
17+
18+
<usa>
19+
<latt>40.707507</latt>
20+
<longt>-74.011255</longt>
21+
<uscity>New York</uscity>
22+
<state>NY</state>
23+
<zip>10005</zip>
24+
<usstnumber>2</usstnumber>
25+
<usstaddress>New St</usstaddress>
26+
<inlatt>40.707507</inlatt>
27+
<inlongt>-74.011255</inlongt>
28+
<distance>0</distance>
29+
30+
</usa>
31+
32+
33+
</geodata>
34+
</result>
35+
";

0 commit comments

Comments
 (0)