You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.2 KiB

<?php
namespace p3k;
class Geocoder {
public static function adrFromLocation($lat, $lng) {
$response = self::_reverse($lat, $lng);
if(!$response)
return false;
if(!property_exists($response, 'address'))
return false;
$address = $response->address;
$result = new geocode\Result;
$result->latitude = $lat;
$result->longitude = $lng;
if(property_exists($address, 'Postal'))
$result->postalCode = $address->Postal;
if(property_exists($address, 'Region'))
$result->regionName = $address->Region;
if(property_exists($address, 'City'))
$result->localityName = $address->City;
elseif(property_exists($address, 'Subregion'))
$result->localityName = $address->Subregion;
elseif(property_exists($address, 'Neighborhood'))
$result->localityName = $address->Neighborhood;
if(property_exists($address, 'CountryCode'))
$result->countryName = $address->CountryCode;
return $result;
}
public static function geocode($input) {
$response = self::_geocode($input);
if(!$response || count($response->locations) == 0)
return false;
$location = $response->locations[0];
$attributes = $location->feature->attributes;
$geometry = $location->feature->geometry;
$result = new geocode\Result;
if($geometry) {
$result->latitude = $geometry->y;
$result->longitude = $geometry->x;
}
if($attributes->City)
$result->localityName = $attributes->City;
if($attributes->Region)
$result->regionName = $attributes->Region;
if($attributes->Country)
$result->countryName = $attributes->Country;
if($attributes->Postal) {
$result->postalCode = $attributes->Postal;
} else {
// If no postal code is returned, but there was coordinates, then reverse geocode to find the postal code
if($geometry) {
$rev = self::_reverse($result->latitude, $result->longitude);
if($rev && property_exists($rev->address, 'Postal')) {
$result->postalCode = $rev->address->Postal;
}
}
}
if($location->name)
$result->fullAddress = $location->name;
return $result;
}
private static function _reverse($lat, $lng) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode?location='.$lng.'%2C'.$lat.'&outSR=4326&f=json&distance=10000');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// curl_setopt($ch, CURLOPT_USERAGENT, '');
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$result = curl_exec($ch);
if($result == FALSE)
return FALSE;
return json_decode($result);
}
private static function _geocode($input) {
$ch = curl_init();
$params = [
'f' => 'json',
'outSR' => 4326,
'text' => $input,
'outFields' => 'City,Region,Country,Postal',
];
curl_setopt($ch, CURLOPT_URL, 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?' . http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// curl_setopt($ch, CURLOPT_USERAGENT, '');
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$result = curl_exec($ch);
if($result == FALSE)
return FALSE;
return json_decode($result);
}
}