Skip to content

Commit 2090e06

Browse files
committed
Merge pull request #211 from toin0u/TomTomProvider
Added: TomTom Provider
2 parents f3846c3 + 09dcc68 commit 2090e06

File tree

4 files changed

+460
-2
lines changed

4 files changed

+460
-2
lines changed

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ Currently, there are many providers for the following APIs:
5050
* [MaxMind web service](http://dev.maxmind.com/geoip/web-services) as IP-Based geocoding provider (City/ISP/Org and Omni services);
5151
* [Geonames](http://www.geonames.org/) as Place-Based geocoding and reverse geocoding provider;
5252
* [IpGeoBase](http://ipgeobase.ru/) as IP-Based geocoding provider (very accurate in Russia);
53-
* [Baidu](http://developer.baidu.com/map/geocoding-api.htm) as Address-Based geocoding and reverse geocoding provider (exclusively in China).
53+
* [Baidu](http://developer.baidu.com/map/geocoding-api.htm) as Address-Based geocoding and reverse geocoding provider (exclusively in China);
54+
* [TomTom](http://developer.tomtom.com/docs/read/Geocoding) as Address-Based geocoding and reverse geocoding provider.
5455

5556
Installation
5657
------------
@@ -253,6 +254,13 @@ The `BaiduProvider` named `baidu` is able to geocode and reverse geocode **stree
253254
A valid api key is required.
254255

255256

257+
### TomTomProvider ###
258+
259+
The `TomTomProvider` named `tomtom` is able to geocode and reverse geocode **street addresses**.
260+
The default langage-locale is `en`, you can choose between `de`, `es`, `fr`, `it`, `nl`, `pl`, `pt` and `sv`.
261+
A valid api key is required.
262+
263+
256264
### Using The Providers ###
257265

258266
You can use one of them or write your own provider. You can also register all providers and decide later.
@@ -283,7 +291,7 @@ $geocoder->registerProviders(array(
283291

284292
Parameters:
285293

286-
* `$locale` is available for `YahooProvider`, `YandexProvider` and `BingMapsProvider`.
294+
* `$locale` is available for `YahooProvider`, `YandexProvider`, `BingMapsProvider` and `TomTomProvider`.
287295
* `$region` is available for `GoogleMapsProvider` and `GoogleMapsBusinessProvider`.
288296
* `$toponym` is available for `YandexProvider`.
289297
* `$service` is available for `MaxMindProvider`.
@@ -542,6 +550,8 @@ Rename the `phpunit.xml.dist` file to `phpunit.xml`, then uncomment the followin
542550
<!-- <server name="MAXMIND_API_KEY" value="YOUR_API_KEY" /> -->
543551
<!-- <server name="GEONAMES_USERNAME" value="YOUR_USERNAME" /> -->
544552
<!-- <server name="BAIDU_API_KEY" value="YOUR_API_KEY" /> -->
553+
<!-- <server name="TOMTOM_GEOCODING_KEY" value="YOUR_GEOCODING_KEY" /> -->
554+
<!-- <server name="TOMTOM_MAP_KEY" value="YOUR_MAP_KEY" /> -->
545555
</php>
546556
```
547557

phpunit.xml.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<!-- <server name="MAXMIND_API_KEY" value="YOUR_API_KEY" /> -->
2121
<!-- <server name="GEONAMES_USERNAME" value="YOUR_USERNAME" /> -->
2222
<!-- <server name="BAIDU_API_KEY" value="YOUR_API_KEY" /> -->
23+
<!-- <server name="TOMTOM_GEOCODING_KEY" value="YOUR_GEOCODING_KEY" /> -->
24+
<!-- <server name="TOMTOM_MAP_KEY" value="YOUR_MAP_KEY" /> -->
2325
</php>
2426
<testsuites>
2527
<testsuite name="Geocoder Test Suite">
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Geocoder package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Geocoder\Provider;
12+
13+
use Geocoder\HttpAdapter\HttpAdapterInterface;
14+
use Geocoder\Exception\InvalidCredentialsException;
15+
use Geocoder\Exception\NoResultException;
16+
use Geocoder\Exception\UnsupportedException;
17+
18+
/**
19+
* @author Antoine Corcy <contact@sbin.dk>
20+
*/
21+
class TomTomProvider extends AbstractProvider implements ProviderInterface
22+
{
23+
/**
24+
* @var string
25+
*/
26+
const GEOCODE_ENDPOINT_URL = 'https://api.tomtom.com/lbs/geocoding/geocode?key=%s&maxResults=1&query=%s';
27+
28+
/**
29+
* @var string
30+
*/
31+
const REVERSE_ENDPOINT_URL = 'https://api.tomtom.com/lbs/services/reverseGeocode/3/xml?key=%s&point=%F,%F';
32+
33+
/**
34+
* @var string
35+
*/
36+
private $apiKey = null;
37+
38+
/**
39+
* @param HttpAdapterInterface $adapter An HTTP adapter.
40+
* @param string $apiKey An API key.
41+
* @param string $locale A locale (optional).
42+
*/
43+
public function __construct(HttpAdapterInterface $adapter, $apiKey, $locale = null)
44+
{
45+
parent::__construct($adapter, $locale);
46+
47+
$this->apiKey = $apiKey;
48+
}
49+
50+
/**
51+
* {@inheritDoc}
52+
*/
53+
public function getGeocodedData($address)
54+
{
55+
if (null === $this->apiKey) {
56+
throw new InvalidCredentialsException('No Geocoding API Key provided');
57+
}
58+
59+
// This API doesn't handle IPs
60+
if (filter_var($address, FILTER_VALIDATE_IP)) {
61+
throw new UnsupportedException('The TomTomProvider does not support IP addresses.');
62+
}
63+
64+
$query = sprintf(self::GEOCODE_ENDPOINT_URL, $this->apiKey, rawurlencode($address));
65+
66+
return $this->executeQuery($query);
67+
}
68+
69+
/**
70+
* {@inheritDoc}
71+
*/
72+
public function getReversedData(array $coordinates)
73+
{
74+
if (null === $this->apiKey) {
75+
throw new InvalidCredentialsException('No Map API Key provided');
76+
}
77+
78+
$query = sprintf(self::REVERSE_ENDPOINT_URL, $this->apiKey, $coordinates[0], $coordinates[1]);
79+
80+
return $this->executeQuery($query);
81+
}
82+
83+
/**
84+
* {@inheritDoc}
85+
*/
86+
public function getName()
87+
{
88+
return 'tomtom';
89+
}
90+
91+
/**
92+
* @param string $query
93+
*
94+
* @return array
95+
*/
96+
protected function executeQuery($query)
97+
{
98+
if (null !== $this->getLocale()) {
99+
// Supported 2- character values are de, en, es, fr, it, nl, pl, pt, and sv.
100+
// Equivalent 3-character values are GER, ENG, SPA, FRE, ITA, DUT, POL, POR, and SWE.
101+
$query = sprintf('%s&language=%s', $query, substr($this->getLocale(), 0, 2));
102+
}
103+
104+
$content = $this->getAdapter()->getContent($query);
105+
106+
try {
107+
$xml = new \SimpleXmlElement($content);
108+
} catch (\Exception $e) {
109+
throw new NoResultException(sprintf('Could not execute query %s', $query));
110+
}
111+
112+
$attributes = $xml->attributes();
113+
114+
if (isset($attributes['count']) && 0 === (int) $attributes['count']) {
115+
throw new NoResultException(sprintf('Could not execute query %s', $query));
116+
}
117+
118+
if (isset($attributes['errorCode'])) {
119+
if ('403' === (string) $attributes['errorCode']) {
120+
throw new InvalidCredentialsException('Map API Key provided is not valid.');
121+
}
122+
123+
throw new NoResultException(sprintf('Could not execute query %s', $query));
124+
}
125+
126+
$result = isset($xml->geoResult) ? $xml->geoResult : $xml->reverseGeoResult;
127+
128+
return array_merge($this->getDefaults(), array(
129+
'latitude' => isset($result->latitude) ? (double) $result->latitude : null,
130+
'longitude' => isset($result->longitude) ? (double) $result->longitude : null,
131+
'streetName' => isset($result->street) ? (string) $result->street : null,
132+
'city' => isset($result->city) ? (string) $result->city : null,
133+
'region' => isset($result->state) ? (string) $result->state : null,
134+
'country' => isset($result->country) ? (string) $result->country : null,
135+
'countryCode' => isset($result->countryISO3) ? (string) $result->countryISO3 : null,
136+
));
137+
}
138+
}

0 commit comments

Comments
 (0)