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.

118 lines
3.2 KiB

  1. <?php
  2. namespace p3k;
  3. class Geocoder {
  4. public static function adrFromLocation($lat, $lng) {
  5. $response = self::_reverse($lat, $lng);
  6. if(!$response)
  7. return false;
  8. $address = $response->address;
  9. $result = new geocode\Result;
  10. $result->latitude = $lat;
  11. $result->longitude = $lng;
  12. if(property_exists($address, 'Postal'))
  13. $result->postalCode = $address->Postal;
  14. if(property_exists($address, 'Region'))
  15. $result->regionName = $address->Region;
  16. if(property_exists($address, 'City'))
  17. $result->localityName = $address->City;
  18. elseif(property_exists($address, 'Subregion'))
  19. $result->localityName = $address->Subregion;
  20. elseif(property_exists($address, 'Neighborhood'))
  21. $result->localityName = $address->Neighborhood;
  22. if(property_exists($address, 'CountryCode'))
  23. $result->countryName = $address->CountryCode;
  24. return $result;
  25. }
  26. public static function geocode($input) {
  27. $response = self::_geocode($input);
  28. if(!$response || count($response->locations) == 0)
  29. return false;
  30. $location = $response->locations[0];
  31. $attributes = $location->feature->attributes;
  32. $geometry = $location->feature->geometry;
  33. $result = new geocode\Result;
  34. if($geometry) {
  35. $result->latitude = $geometry->y;
  36. $result->longitude = $geometry->x;
  37. }
  38. if($attributes->City)
  39. $result->localityName = $attributes->City;
  40. if($attributes->Region)
  41. $result->regionName = $attributes->Region;
  42. if($attributes->Country)
  43. $result->countryName = $attributes->Country;
  44. if($attributes->Postal) {
  45. $result->postalCode = $attributes->Postal;
  46. } else {
  47. // If no postal code is returned, but there was coordinates, then reverse geocode to find the postal code
  48. if($geometry) {
  49. $rev = self::_reverse($result->latitude, $result->longitude);
  50. if($rev && property_exists($rev->address, 'Postal')) {
  51. $result->postalCode = $rev->address->Postal;
  52. }
  53. }
  54. }
  55. if($location->name)
  56. $result->fullAddress = $location->name;
  57. return $result;
  58. }
  59. private static function _reverse($lat, $lng) {
  60. $ch = curl_init();
  61. 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');
  62. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  63. // curl_setopt($ch, CURLOPT_USERAGENT, '');
  64. curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  65. $result = curl_exec($ch);
  66. if($result == FALSE)
  67. return FALSE;
  68. return json_decode($result);
  69. }
  70. private static function _geocode($input) {
  71. $ch = curl_init();
  72. $params = [
  73. 'f' => 'json',
  74. 'outSR' => 4326,
  75. 'text' => $input,
  76. 'outFields' => 'City,Region,Country,Postal',
  77. ];
  78. curl_setopt($ch, CURLOPT_URL, 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?' . http_build_query($params));
  79. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  80. // curl_setopt($ch, CURLOPT_USERAGENT, '');
  81. curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  82. $result = curl_exec($ch);
  83. if($result == FALSE)
  84. return FALSE;
  85. return json_decode($result);
  86. }
  87. }