Skip to content

Commit 5bb8890

Browse files
authored
Add new GraphHopper Provider (#957)
* Add GraphHopper provider Close #953 * Apply fixes from StyleCI * Update phpunit.xml.dist
0 parents  commit 5bb8890

16 files changed

+488
-0
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.gitattributes export-ignore
2+
.travis.yml export-ignore
3+
phpunit.xml.dist export-ignore
4+
Tests/ export-ignore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
phpunit.xml

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: php
2+
sudo: false
3+
4+
php: 7.2
5+
6+
7+
install:
8+
- composer update --prefer-stable --prefer-dist
9+
10+
script:
11+
- composer test-ci
12+
13+
after_success:
14+
- wget https://scrutinizer-ci.com/ocular.phar
15+
- php ocular.phar code-coverage:upload --format=php-clover build/coverage.xml
16+

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Change Log
2+
3+
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
4+
5+
## 4.0.0
6+
7+
First release of this library.

GraphHopper.php

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Geocoder package.
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*
10+
* @license MIT License
11+
*/
12+
13+
namespace Geocoder\Provider\GraphHopper;
14+
15+
use Geocoder\Collection;
16+
use Geocoder\Exception\InvalidCredentials;
17+
use Geocoder\Exception\UnsupportedOperation;
18+
use Geocoder\Model\Address;
19+
use Geocoder\Model\AddressCollection;
20+
use Geocoder\Query\GeocodeQuery;
21+
use Geocoder\Query\ReverseQuery;
22+
use Geocoder\Http\Provider\AbstractHttpProvider;
23+
use Geocoder\Provider\Provider;
24+
use Http\Client\HttpClient;
25+
26+
/**
27+
* @author Gary Gale <[email protected]>
28+
*/
29+
final class GraphHopper extends AbstractHttpProvider implements Provider
30+
{
31+
/**
32+
* @var string
33+
*/
34+
const GEOCODE_ENDPOINT_URL = 'https://graphhopper.com/api/1/geocode?q=%s&key=%s&locale=%s&limit=%d';
35+
36+
/**
37+
* @var string
38+
*/
39+
const REVERSE_ENDPOINT_URL = 'https://graphhopper.com/api/1/geocode?reverse=true&point=%f,%f&key=%s&locale=%s&limit=%d';
40+
41+
/**
42+
* @var string
43+
*/
44+
private $apiKey;
45+
46+
/**
47+
* @param HttpClient $client an HTTP adapter
48+
* @param string $apiKey an API key
49+
*/
50+
public function __construct(HttpClient $client, string $apiKey)
51+
{
52+
if (empty($apiKey)) {
53+
throw new InvalidCredentials('No API key provided.');
54+
}
55+
56+
$this->apiKey = $apiKey;
57+
parent::__construct($client);
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function geocodeQuery(GeocodeQuery $query): Collection
64+
{
65+
$address = $query->getText();
66+
67+
// This API doesn't handle IPs
68+
if (filter_var($address, FILTER_VALIDATE_IP)) {
69+
throw new UnsupportedOperation('The GraphHopper provider does not support IP addresses, only street addresses.');
70+
}
71+
72+
$url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address), $this->apiKey, $query->getLocale(), $query->getLimit());
73+
74+
return $this->executeQuery($url);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
public function reverseQuery(ReverseQuery $query): Collection
81+
{
82+
$coordinates = $query->getCoordinates();
83+
$longitude = $coordinates->getLongitude();
84+
$latitude = $coordinates->getLatitude();
85+
86+
$url = sprintf(self::REVERSE_ENDPOINT_URL, $latitude, $longitude, $this->apiKey, $query->getLocale(), $query->getLimit());
87+
88+
return $this->executeQuery($url);
89+
}
90+
91+
/**
92+
* {@inheritdoc}
93+
*/
94+
public function getName(): string
95+
{
96+
return 'graphhopper';
97+
}
98+
99+
/**
100+
* @param $url
101+
*
102+
* @return Collection
103+
*/
104+
private function executeQuery(string $url): AddressCollection
105+
{
106+
$content = $this->getUrlContents($url);
107+
108+
$json = json_decode($content, true);
109+
110+
if (!isset($json['hits'])) {
111+
return new AddressCollection([]);
112+
}
113+
114+
$locations = $json['hits'];
115+
116+
if (empty($locations)) {
117+
return new AddressCollection([]);
118+
}
119+
120+
$results = [];
121+
foreach ($locations as $location) {
122+
$bounds = [
123+
'east' => null,
124+
'north' => null,
125+
'west' => null,
126+
'south' => null,
127+
];
128+
if (isset($location['extent'])) {
129+
$bounds = [
130+
'east' => $location['extent'][0],
131+
'north' => $location['extent'][1],
132+
'west' => $location['extent'][2],
133+
'south' => $location['extent'][3],
134+
];
135+
}
136+
137+
$results[] = Address::createFromArray([
138+
'providedBy' => $this->getName(),
139+
'latitude' => $location['point']['lat'],
140+
'longitude' => $location['point']['lng'],
141+
'bounds' => $bounds,
142+
'streetNumber' => isset($location['housenumber']) ? $location['housenumber'] : null,
143+
'streetName' => isset($location['street']) ? $location['street'] : null,
144+
'locality' => isset($location['city']) ? $location['city'] : null,
145+
'postalCode' => isset($location['postcode']) ? $location['postcode'] : null,
146+
'country' => isset($location['country']) ? $location['country'] : null,
147+
]);
148+
}
149+
150+
return new AddressCollection($results);
151+
}
152+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2011 — William Durand <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Readme.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# GraphHopper Geocoder provider
2+
[![Build Status](https://travis-ci.org/geocoder-php/graphhopper-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/graphhopper-provider)
3+
[![Latest Stable Version](https://poser.pugx.org/geocoder-php/graphhopper-provider/v/stable)](https://packagist.org/packages/geocoder-php/graphhopper-provider)
4+
[![Total Downloads](https://poser.pugx.org/geocoder-php/graphhopper-provider/downloads)](https://packagist.org/packages/geocoder-php/graphhopper-provider)
5+
[![Monthly Downloads](https://poser.pugx.org/geocoder-php/graphhopper-provider/d/monthly.png)](https://packagist.org/packages/geocoder-php/graphhopper-provider)
6+
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/geocoder-php/graphhopper-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/graphhopper-provider)
7+
[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/graphhopper-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/graphhopper-provider)
8+
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
9+
10+
This is the GraphHopper provider from the PHP Geocoder. This is a **READ ONLY** repository. See the
11+
[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation.
12+
13+
### Install
14+
15+
```bash
16+
composer require geocoder-php/graphhopper-provider
17+
```
18+
19+
### Contribute
20+
21+
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or
22+
report any issues you find on the [issue tracker](https://github.com/geocoder-php/Geocoder/issues).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:1640:"{"hits":[{"osm_id":5076279021,"osm_type":"N","country":"United States of America","osm_key":"man_made","housenumber":"800","city":"Washington","street":"16th Street Northwest","osm_value":"surveillance","postcode":"20012","name":"16th Street Northwest","state":"District of Columbia","point":{"lng":-77.036931,"lat":38.900368}},{"osm_id":55326891,"extent":[-77.0371738,38.9006934,-77.0367231,38.9003173],"country":"United States of America","city":"Washington","postcode":"20006","point":{"lng":-77.03689992471391,"lat":38.90050395},"osm_type":"W","osm_key":"tourism","housenumber":"800","street":"16th Street Northwest","osm_value":"hotel","name":"Hay-Adams Hotel","state":"District of Columbia"},{"osm_id":367142942,"osm_type":"N","country":"United States of America","osm_key":"amenity","city":"Washington","street":"H Street Northwest","osm_value":"public_building","postcode":"20006","name":"United States Chamber of Commerce Building","state":"District of Columbia","point":{"lng":-77.0374769,"lat":38.9003895}},{"osm_id":4957653991,"osm_type":"N","country":"United States of America","osm_key":"tourism","city":"Washington","street":"16th Street Northwest","osm_value":"information","postcode":"20012","name":"16th Street Meridian","state":"District of Columbia","point":{"lng":-77.0364753,"lat":38.9003613}},{"osm_id":589539534,"osm_type":"W","extent":[-77.0379693,38.900203,-77.036554,38.9002001],"country":"United States of America","osm_key":"highway","city":"Washington","osm_value":"primary","postcode":"20006","name":"H Street Northwest","state":"District of Columbia","point":{"lng":-77.0376048,"lat":38.9002018}}],"took":19}";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:21:"{"hits":[],"took":10}";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:357:"{"hits":[{"osm_id":526221246,"extent":[-0.2032839,51.5215898,-0.2019938,51.5210691],"country":"Royaume-Uni","city":"Londres","postcode":"W10 5JJ","point":{"lng":-0.20279208322428877,"lat":51.52134195},"osm_type":"W","osm_key":"office","housenumber":"242","street":"Acklam Road","osm_value":"yes","name":"Westbourne Studios","state":"Angleterre"}],"took":16}";

0 commit comments

Comments
 (0)