Created
June 12, 2019 20:54
-
-
Save randy-allen/fb6e4b3882804dc9a63514b504999e15 to your computer and use it in GitHub Desktop.
A version of spatie/geocoder that uses dev.virtualearth.net instead of Google Maps API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Spatie\Geocoder; | |
use GuzzleHttp\Client; | |
use Spatie\Geocoder\Exceptions\CouldNotGeocode; | |
class Geocoder | |
{ | |
const RESULT_NOT_FOUND = 'result_not_found'; | |
/** @var \GuzzleHttp\Client */ | |
protected $client; | |
/** @var string */ | |
// protected $endpoint = 'https://maps.googleapis.com/maps/api/geocode/json'; | |
protected $endpoint = 'http://dev.virtualearth.net/REST/v1/Locations'; | |
/** @var string */ | |
protected $apiKey; | |
/** @var string */ | |
protected $language; | |
/** @var string */ | |
protected $region; | |
/** @var string */ | |
protected $bounds; | |
/** @var string */ | |
protected $country; | |
public function __construct(Client $client) | |
{ | |
$this->client = $client; | |
} | |
public function setApiKey(string $apiKey) | |
{ | |
$this->apiKey = $apiKey; | |
return $this; | |
} | |
public function setLanguage(string $language) | |
{ | |
$this->language = $language; | |
return $this; | |
} | |
public function setRegion(string $region) | |
{ | |
$this->region = $region; | |
return $this; | |
} | |
public function setBounds(string $bounds) | |
{ | |
$this->bounds = $bounds; | |
return $this; | |
} | |
public function setCountry(string $country) | |
{ | |
$this->country = $country; | |
return $this; | |
} | |
public function getCoordinatesForAddress(string $address): array | |
{ | |
if (empty($address)) { | |
return $this->emptyResponse(); | |
} | |
$payload = $this->getRequestPayload(['query' => $address]); | |
$response = $this->client->request('GET', $this->endpoint, $payload); | |
if ($response->getStatusCode() !== 200) { | |
throw CouldNotGeocode::couldNotConnect(); | |
} | |
$geocodingResponse = json_decode($response->getBody()); | |
if (! empty($geocodingResponse->error_message)) { | |
throw CouldNotGeocode::serviceReturnedError($geocodingResponse->error_message); | |
} | |
if (! count($geocodingResponse->resourceSets)) { | |
return $this->emptyResponse(); | |
} | |
return $this->formatResponse($geocodingResponse); | |
} | |
public function getAddressForCoordinates(float $lat, float $lng): array | |
{ | |
$payload = $this->getRequestPayload([ | |
'latlng' => "$lat,$lng", | |
]); | |
$response = $this->client->request('GET', $this->endpoint, $payload); | |
if ($response->getStatusCode() !== 200) { | |
throw CouldNotGeocode::couldNotConnect(); | |
} | |
$reverseGeocodingResponse = json_decode($response->getBody()); | |
if (! empty($reverseGeocodingResponse->error_message)) { | |
throw CouldNotGeocode::serviceReturnedError($reverseGeocodingResponse->error_message); | |
} | |
if (! count($reverseGeocodingResponse->results)) { | |
return $this->emptyResponse(); | |
} | |
return $this->formatResponse($reverseGeocodingResponse); | |
} | |
protected function formatResponse($response): array | |
{ | |
return [ | |
'lat' => $response->resourceSets[0]->resources[0]->point->coordinates[0], | |
'lng' => $response->resourceSets[0]->resources[0]->point->coordinates[1], | |
'accuracy' => $response->resourceSets[0]->resources[0]->confidence, | |
'formatted_address' => $response->resourceSets[0]->resources[0]->name, | |
'viewport' => $response->resourceSets[0]->resources[0]->geocodePoints, | |
// 'address_components' => $response->results[0]->address_components, | |
// 'place_id' => $response->results[0]->place_id, | |
]; | |
} | |
protected function getRequestPayload(array $parameters): array | |
{ | |
$parameters = array_merge([ | |
'key' => $this->apiKey, | |
// 'language' => $this->language, | |
// 'region' => $this->region, | |
// 'bounds' => $this->bounds, | |
], $parameters); | |
if ($this->country) { | |
$parameters = array_merge( | |
$parameters, | |
['components' => 'country:'.$this->country] | |
); | |
} | |
return ['query' => $parameters]; | |
} | |
protected function emptyResponse(): array | |
{ | |
return [ | |
'lat' => 0, | |
'lng' => 0, | |
'accuracy' => static::RESULT_NOT_FOUND, | |
'formatted_address' => static::RESULT_NOT_FOUND, | |
'viewport' => static::RESULT_NOT_FOUND, | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This file goes in /vendor/spatie/geocoder/src
Still requires a
GOOGLE_MAPS_GEOCODING_API_KEY=
in your.env
file that is actually your API key from dev.virtualearth.netTODO:
Fork spatie/geocoder and do this properly