Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
48cb39f
Add Here Provider
sheub Apr 15, 2018
5de7717
Rename here.php to Here.php
sheub Apr 15, 2018
97a4224
Update Here.php
sheub Apr 15, 2018
d643c17
Update HereAddress.php
sheub Apr 15, 2018
174a3ed
Update Here.php
sheub Apr 15, 2018
da878f6
Update HereAddress.php
sheub Apr 15, 2018
a1a1ef7
Update Here.php
sheub Apr 15, 2018
89f167c
Update Here.php
sheub Apr 15, 2018
1b14a89
Review Corrections
sheub Apr 16, 2018
fe848a4
+ * @param string $appId An App ID.
sheub Apr 16, 2018
89375e8
Add Tests files
sheub Apr 17, 2018
1b16397
Add phpunit.xml.dist
sheub Apr 17, 2018
fc7042a
Corrections after running tests
sheub Apr 17, 2018
b05c424
use{}
sheub Apr 17, 2018
26924bf
FIX IT!
sheub Apr 17, 2018
1d8a48d
Few Styles #844
sheub Apr 17, 2018
75ba5b2
HereMaps->Here
sheub Apr 17, 2018
04aac0a
.Some more tests
sheub Apr 17, 2018
13560f3
style
sheub Apr 17, 2018
f0a5388
Build Test OK if $testIpv4 = false;
sheub Apr 18, 2018
693de43
Update HereTest.php
sheub Apr 18, 2018
fbe308f
Code review from Baachi
sheub Apr 19, 2018
b199a7b
Merge branch 'master' of https://github.com/sheub/Geocoder
sheub Apr 19, 2018
4bb74fd
Update Here.php
sheub Apr 19, 2018
52bb5e3
Update Readme.md
sheub Apr 21, 2018
5942c1f
updated Here_Test and cached_responses
sheub Apr 21, 2018
4a17fa5
Merge branch 'master' of https://github.com/sheub/Geocoder
sheub Apr 21, 2018
51b0867
Add
sheub Apr 23, 2018
2f9edda
Update Readme.md
sheub Jun 20, 2018
23c1d76
Reworking of the Tests with adjustments to fit the two Credentials ke…
sheub Jun 20, 2018
30c5319
Merge branch 'master' of https://github.com/sheub/Geocoder
sheub Jun 20, 2018
016d991
style-ci correction + override testGeocodeQueryWithNoResults, testRev…
sheub Jun 20, 2018
9d1e4c7
Styles
sheub Jun 20, 2018
e0ee829
Update IntegrationTest.php
sheub Jun 20, 2018
cbeed07
Correct the extends and the naming (to HereCachedResponseClient)
sheub Jun 22, 2018
c31e8cd
Merge branch 'master' of https://github.com/sheub/Geocoder
sheub Jun 22, 2018
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
2 changes: 2 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
<server name="IPINFODB_API_KEY" value="YOUR_API_KEY" />
<server name="PICKPOINT_API_KEY" value="YOUR_API_KEY" />
<server name="LOCATIONIQ_API_KEY" value="YOUR_API_KEY" />
<server name="HERE_APP_ID" value="YOUR_APP_ID" />
<server name="HERE_APP_CODE" value="YOUR_APP_CODE" />
<!--<server name="MAXMIND_API_KEY" value="YOUR_API_KEY" />-->
</php>

Expand Down
3 changes: 3 additions & 0 deletions src/Provider/Here/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml
7 changes: 7 additions & 0 deletions src/Provider/Here/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Change Log

The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.

## 1.0.0

First release of this library.
167 changes: 167 additions & 0 deletions src/Provider/Here/Here.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Geocoder package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

namespace Geocoder\Provider\Here;

use Geocoder\Collection;
use Geocoder\Exception\InvalidCredentials;
use Geocoder\Exception\UnsupportedOperation;
use Geocoder\Model\AddressBuilder;
use Geocoder\Model\AddressCollection;
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;
use Geocoder\Http\Provider\AbstractHttpProvider;
use Geocoder\Provider\Provider;
use Geocoder\Provider\Here\Model\HereAddress;
use Http\Client\HttpClient;

/**
* @author Sébastien Barré <sebastien@sheub.eu>
*/
final class Here extends AbstractHttpProvider implements Provider
{
/**
* @var string
*/
const GEOCODE_ENDPOINT_URL = 'https://geocoder.api.here.com/6.2/geocode.json?app_id=%s&app_code=%s&searchtext=%s&gen=8';

/**
* @var string
*/
const REVERSE_ENDPOINT_URL = 'https://reverse.geocoder.api.here.com/6.2/reversegeocode.json?prox=%F,%F&250&app_id=%s&app_code=%s&mode=retrieveAddresses&gen=8&maxresults=%d';

/**
* @var string
*/
private $appId = null;

/**
* @var string
*/
private $appCode = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need the = null


/**
* @param HttpClient $adapter An HTTP adapter.
* @param string $appId An App ID.
* @param string $apoCode An App code.
*/
public function __construct(HttpClient $client, string $appId, string $appCode)
{
if (empty($appId) || empty($appCode)) {
throw new InvalidCredentials('Invalid or missing api key.');
}
$this->appId = $appId;
$this->appCode = $appCode;

parent::__construct($client);
}

/**
* {@inheritdoc}
*/
public function geocodeQuery(GeocodeQuery $query): Collection
{
// This API doesn't handle IPs
if (filter_var($query->getText(), FILTER_VALIDATE_IP)) {
throw new UnsupportedOperation('The Here provider does not support IP addresses, only street addresses.');
}

$url = sprintf(self::GEOCODE_ENDPOINT_URL, $this->appId, $this->appCode, rawurlencode($query->getText()));

if (null !== $query->getLocale()) {
$url = sprintf('%s&language=%s', $url, $query->getLocale());
}

return $this->executeQuery($url, $query->getLimit());
}

/**
* {@inheritdoc}
*/
public function reverseQuery(ReverseQuery $query): Collection
{
$coordinates = $query->getCoordinates();
$url = sprintf(self::REVERSE_ENDPOINT_URL, $coordinates->getLatitude(), $coordinates->getLongitude(), $this->appId, $this->appCode, $query->getLimit());

return $this->executeQuery($url, $query->getLimit());
}

/**
* @param string $url
* @param string $locale
* @param int $limit
*
* @return \Geocoder\Collection
*/
private function executeQuery(string $url, int $limit): Collection
{
$content = $this->getUrlContents($url);
$json = json_decode($content, true);

if (isset($json['type'])) {
switch ($json['type']['subtype']) {
case 'InvalidInputData':
throw new InvalidArgument('Input parameter validation failed.');
case 'QuotaExceeded':
throw new QuotaExceeded('Valid request but quota exceeded.');
case 'InvalidCredentials':
throw new InvalidCredentials('Invalid or missing api key.');
}
}

if (!isset($json['Response']) || empty($json['Response'])) {
return new AddressCollection([]);
}

if (!isset($json['Response']['View'][0])) {
return new AddressCollection([]);
}

$locations = $json['Response']['View'][0]['Result'];

foreach ($locations as $loc) {
$location = $loc['Location'];
$builder = new AddressBuilder($this->getName());
$coordinates = isset($location['NavigationPosition'][0]) ? $location['NavigationPosition'][0] : $location['DisplayPosition'];
$builder->setCoordinates($coordinates['Latitude'], $coordinates['Longitude']);
$bounds = $location['MapView'];

$builder->setBounds($bounds['BottomRight']['Latitude'], $bounds['TopLeft']['Longitude'], $bounds['TopLeft']['Latitude'], $bounds['BottomRight']['Longitude']);
$builder->setStreetNumber($location['Address']['HouseNumber'] ?? null);
$builder->setStreetName($location['Address']['Street'] ?? null);
$builder->setPostalCode($location['Address']['PostalCode'] ?? null);
$builder->setLocality($location['Address']['City'] ?? null);
$builder->setSubLocality($location['Address']['District'] ?? null);
$builder->setCountry($location['Address']['AdditionalData'][0]['value'] ?? null);
$builder->setCountryCode($location['Address']['Country'] ?? null);

$address = $builder->build(HereAddress::class);
$address = $address->withLocationId($location['LocationId']);
$address = $address->withLocationType($location['LocationType']);
$results[] = $address;

if (count($results) >= $limit) {
break;
}
}

return new AddressCollection($results);
}

/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'Here';
}
}
21 changes: 21 additions & 0 deletions src/Provider/Here/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2018 — Sébastien Barré <sebastien@sheub.eu>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
99 changes: 99 additions & 0 deletions src/Provider/Here/Model/HereAddress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Geocoder package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

namespace Geocoder\Provider\Here\Model;

use Geocoder\Model\Address;

/**
* @author sébastien Barré <info@zoestha.de>
*/
final class HereAddress extends Address
{
/**
* @var string|null
*/
private $locationId;

/**
* @var string|null
*/
private $locationType;

/**
* @var string|null
*/
private $locationName;

/**
* @return null|string
*/
public function getLocationId()
{
return $this->locationId;
}

/**
* @param null|string $LocationId
*
* @return HereAddress
*/
public function withLocationId(string $locationId = null): self
{
$new = clone $this;
$new->locationId = $locationId;

return $new;
}

/**
* @return null|string
*/
public function getLocationType()
{
return $this->locationType;
}

/**
* @param null|string $LocationType
*
* @return HereAddress
*/
public function withLocationType(string $locationType = null): self
{
$new = clone $this;
$new->locationType = $locationType;

return $new;
}

/**
* @return null|string
*/
public function getLocationName()
{
return $this->locationName;
}

/**
* @param null|string $LocationName
*
* @return HereAddress
*/
public function withLocationName(string $locationName = null): self
{
$new = clone $this;
$new->locationName = $locationName;

return $new;
}
}
28 changes: 28 additions & 0 deletions src/Provider/Here/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Here Geocoder provider
[![Build Status](https://travis-ci.org/geocoder-php/here-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/nominatim-provider)
[![Latest Stable Version](https://poser.pugx.org/geocoder-php/here-provider/v/stable)](https://packagist.org/packages/geocoder-php/nominatim-provider)
[![Total Downloads](https://poser.pugx.org/geocoder-php/here-provider/downloads)](https://packagist.org/packages/geocoder-php/nominatim-provider)
[![Monthly Downloads](https://poser.pugx.org/geocoder-php/here-provider/d/monthly.png)](https://packagist.org/packages/geocoder-php/nominatim-provider)
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/geocoder-php/here-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/nominatim-provider)
[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/here-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/nominatim-provider)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)

This is the Here provider from the PHP Geocoder. This is a **READ ONLY** repository. See the
[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation.

### Install

```bash
composer require geocoder-php/here-provider
```
### Note
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be removed.

## App Id and App Code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ### instead of ##

Get your Here credentials at https://developer.here.com/

## Language parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ### instead of ##

Define the preferred language of address elements in the result. Without a preferred language, the Here Geocoder will return results in an official country language or in a regional primary language so that local people will understand. Language code must be provided according to RFC 4647 standard.

### Contribute

Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or
report any issues you find on the [issue tracker](https://github.com/geocoder-php/Geocoder/issues).
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:80:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-22T09:46:26.209+0000"},"View":[]}}";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:991:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-22T09:46:25.259+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"houseNumber","MatchQuality":{"Country":1.0,"City":1.0,"Street":[1.0],"HouseNumber":1.0},"MatchType":"pointAddress","Location":{"LocationId":"NT_0cb6yPlJYuup8k2I7emOLA_xAD","LocationType":"address","DisplayPosition":{"Latitude":48.8653,"Longitude":2.39844},"NavigationPosition":[{"Latitude":48.86518,"Longitude":2.39873}],"MapView":{"TopLeft":{"Latitude":48.8664242,"Longitude":2.3967311},"BottomRight":{"Latitude":48.8641758,"Longitude":2.4001489}},"Address":{"Label":"10 Avenue Gambetta, 75020 Paris, France","Country":"FRA","State":"Île-de-France","County":"Paris","City":"Paris","District":"20e Arrondissement","Street":"Avenue Gambetta","HouseNumber":"10","PostalCode":"75020","AdditionalData":[{"value":"France","key":"CountryName"},{"value":"Île-de-France","key":"StateName"},{"value":"Paris","key":"CountyName"}]}}}]}]}}";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:994:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-20T18:12:16.673+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"MatchLevel":"houseNumber","MatchQuality":{"Country":1.0,"City":1.0,"Street":[1.0],"HouseNumber":1.0},"MatchType":"pointAddress","Location":{"LocationId":"NT_lWsc8knsFwVitNTFX88zmA_xAD","LocationType":"address","DisplayPosition":{"Latitude":51.50341,"Longitude":-0.12765},"NavigationPosition":[{"Latitude":51.50315,"Longitude":-0.12678}],"MapView":{"TopLeft":{"Latitude":51.5045342,"Longitude":-0.129456},"BottomRight":{"Latitude":51.5022858,"Longitude":-0.125844}},"Address":{"Label":"10 Downing Street, London, SW1A 2, United Kingdom","Country":"GBR","State":"England","County":"London","City":"London","District":"Westminster","Street":"Downing Street","HouseNumber":"10","PostalCode":"SW1A 2","AdditionalData":[{"value":"United Kingdom","key":"CountryName"},{"value":"England","key":"StateName"},{"value":"London","key":"CountyName"}]}}}]}]}}";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:80:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-22T09:46:26.756+0000"},"View":[]}}";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:1267:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-22T09:46:25.619+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"Distance":0.1,"MatchLevel":"street","MatchQuality":{"Country":1.0,"State":1.0,"County":1.0,"City":1.0,"District":1.0,"Street":[1.0],"PostalCode":1.0},"Location":{"LocationId":"NT_-nSC1VIpTK6RxGk-RZa.1D_l_1212860159_L","LocationType":"address","DisplayPosition":{"Latitude":48.8632155,"Longitude":2.3887721},"NavigationPosition":[{"Latitude":48.8632155,"Longitude":2.3887721}],"MapView":{"TopLeft":{"Latitude":48.86323,"Longitude":2.38847},"BottomRight":{"Latitude":48.86314,"Longitude":2.38883}},"Address":{"Label":"Avenue Gambetta, 75020 Paris, France","Country":"FRA","State":"Île-de-France","County":"Paris","City":"Paris","District":"20e Arrondissement","Street":"Avenue Gambetta","PostalCode":"75020","AdditionalData":[{"value":"France","key":"CountryName"},{"value":"Île-de-France","key":"StateName"},{"value":"Paris","key":"CountyName"}]},"MapReference":{"ReferenceId":"1212860159","MapId":"UWAM18112","MapVersion":"Q1/2018","MapReleaseDate":"2018-05-19","Spot":0.84,"SideOfStreet":"neither","CountryId":"20000001","StateId":"20002126","CountyId":"20002127","CityId":"20002128","DistrictId":"20002149"}}}]}]}}";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s:2297:"{"Response":{"MetaInfo":{"Timestamp":"2018-06-22T09:46:26.486+0000"},"View":[{"_type":"SearchResultsViewType","ViewId":0,"Result":[{"Relevance":1.0,"Distance":-0.6,"Direction":325.7,"MatchLevel":"district","MatchQuality":{"Country":1.0,"State":1.0,"County":1.0,"City":1.0,"District":1.0,"PostalCode":1.0},"Location":{"LocationId":"NT_oGdFab4eWiYVcjO-u0pTFB","LocationType":"area","DisplayPosition":{"Latitude":38.90347,"Longitude":-77.03985},"MapView":{"TopLeft":{"Latitude":38.90939,"Longitude":-77.04974},"BottomRight":{"Latitude":38.89599,"Longitude":-77.03363}},"Address":{"Label":"Connecticut Avenue/K Street, Washington, DC, United States","Country":"USA","State":"DC","County":"District of Columbia","City":"Washington","District":"Connecticut Avenue/K Street","PostalCode":"20036","AdditionalData":[{"value":"United States","key":"CountryName"},{"value":"District of Columbia","key":"StateName"},{"value":"District of Columbia","key":"CountyName"},{"value":"N","key":"PostalCodeType"}]},"MapReference":{"ReferenceId":"920905639","MapId":"NAAM18111","MapVersion":"Q1/2018","MapReleaseDate":"2018-05-24","SideOfStreet":"neither","CountryId":"21000001","StateId":"21022302","CountyId":"21022303","CityId":"21022306"}}},{"Relevance":1.0,"Distance":0.7,"Direction":163.6,"MatchLevel":"district","MatchQuality":{"Country":1.0,"State":1.0,"County":1.0,"City":1.0,"District":1.0,"PostalCode":1.0},"Location":{"LocationId":"NT_zeyJ5M16Ci53y9KE8RMTGD","LocationType":"area","DisplayPosition":{"Latitude":38.89142,"Longitude":-77.03367},"MapView":{"TopLeft":{"Latitude":38.90021,"Longitude":-77.05679},"BottomRight":{"Latitude":38.88508,"Longitude":-77.00202}},"Address":{"Label":"Washington Mall, Washington, DC, United States","Country":"USA","State":"DC","County":"District of Columbia","City":"Washington","District":"Washington Mall","PostalCode":"20004","AdditionalData":[{"value":"United States","key":"CountryName"},{"value":"District of Columbia","key":"StateName"},{"value":"District of Columbia","key":"CountyName"},{"value":"N","key":"PostalCodeType"}]},"MapReference":{"ReferenceId":"1114357553","MapId":"NAAM18111","MapVersion":"Q1/2018","MapReleaseDate":"2018-05-24","SideOfStreet":"neither","CountryId":"21000001","StateId":"21022302","CountyId":"21022303","CityId":"21022306"}}}]}]}}";
Loading