GoogleGeocode.class.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. /*
  3. * (c) Camptocamp <info@camptocamp.com>
  4. * (c) Patrick Hayes
  5. *
  6. * This code is open-source and licenced under the Modified BSD License.
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * PHP Google Geocoder Adapter
  12. *
  13. *
  14. * @package geoPHP
  15. * @author Patrick Hayes <patrick.d.hayes@gmail.com>
  16. */
  17. class GoogleGeocode extends GeoAdapter
  18. {
  19. /**
  20. * Read an address string or array geometry objects
  21. *
  22. * @param string - Address to geocode
  23. * @param string - Type of Geometry to return. Can either be 'points' or 'bounds' (polygon)
  24. * @param Geometry|bounds-array - Limit the search area to within this region. For example
  25. * by default geocoding "Cairo" will return the location of Cairo Egypt.
  26. * If you pass a polygon of illinois, it will return Cairo IL.
  27. * @param return_multiple - Return all results in a multipoint or multipolygon
  28. * @return Geometry|GeometryCollection
  29. */
  30. public function read($address, $return_type = 'point', $bounds = FALSE, $return_multiple = FALSE) {
  31. if (is_array($address)) $address = join(',', $address);
  32. if (gettype($bounds) == 'object') {
  33. $bounds = $bounds->getBBox();
  34. }
  35. if (gettype($bounds) == 'array') {
  36. $bounds_string = '&bounds='.$bounds['miny'].','.$bounds['minx'].'|'.$bounds['maxy'].','.$bounds['maxx'];
  37. }
  38. else {
  39. $bounds_string = '';
  40. }
  41. $url = "http://maps.googleapis.com/maps/api/geocode/json";
  42. $url .= '?address='. urlencode($address);
  43. $url .= $bounds_string;
  44. $url .= '&sensor=false';
  45. $this->result = json_decode(@file_get_contents($url));
  46. if ($this->result->status == 'OK') {
  47. if ($return_multiple == FALSE) {
  48. if ($return_type == 'point') {
  49. return $this->getPoint();
  50. }
  51. if ($return_type == 'bounds' || $return_type == 'polygon') {
  52. return $this->getPolygon();
  53. }
  54. }
  55. if ($return_multiple == TRUE) {
  56. if ($return_type == 'point') {
  57. $points = array();
  58. foreach ($this->result->results as $delta => $item) {
  59. $points[] = $this->getPoint($delta);
  60. }
  61. return new MultiPoint($points);
  62. }
  63. if ($return_type == 'bounds' || $return_type == 'polygon') {
  64. $polygons = array();
  65. foreach ($this->result->results as $delta => $item) {
  66. $polygons[] = $this->getPolygon($delta);
  67. }
  68. return new MultiPolygon($polygons);
  69. }
  70. }
  71. }
  72. else {
  73. if ($this->result->status) throw new Exception('Error in Google Geocoder: '.$this->result->status);
  74. else throw new Exception('Unknown error in Google Geocoder');
  75. return FALSE;
  76. }
  77. }
  78. /**
  79. * Serialize geometries into a WKT string.
  80. *
  81. * @param Geometry $geometry
  82. * @param string $return_type Should be either 'string' or 'array'
  83. *
  84. * @return string Does a reverse geocode of the geometry
  85. */
  86. public function write(Geometry $geometry, $return_type = 'string') {
  87. $centroid = $geometry->getCentroid();
  88. $lat = $centroid->getY();
  89. $lon = $centroid->getX();
  90. $url = "http://maps.googleapis.com/maps/api/geocode/json";
  91. $url .= '?latlng='.$lat.','.$lon;
  92. $url .= '&sensor=false';
  93. $this->result = json_decode(@file_get_contents($url));
  94. if ($this->result->status == 'OK') {
  95. if ($return_type == 'string') {
  96. return $this->result->results[0]->formatted_address;
  97. }
  98. if ($return_type == 'array') {
  99. return $this->result->results[0]->address_components;
  100. }
  101. }
  102. else {
  103. if ($this->result->status) throw new Exception('Error in Google Reverse Geocoder: '.$this->result->status);
  104. else throw new Exception('Unknown error in Google Reverse Geocoder');
  105. return FALSE;
  106. }
  107. }
  108. private function getPoint($delta = 0) {
  109. $lat = $this->result->results[$delta]->geometry->location->lat;
  110. $lon = $this->result->results[$delta]->geometry->location->lng;
  111. return new Point($lon, $lat);
  112. }
  113. private function getPolygon($delta = 0) {
  114. $points = array (
  115. $this->getTopLeft($delta),
  116. $this->getTopRight($delta),
  117. $this->getBottomRight($delta),
  118. $this->getBottomLeft($delta),
  119. $this->getTopLeft($delta),
  120. );
  121. $outer_ring = new LineString($points);
  122. return new Polygon(array($outer_ring));
  123. }
  124. private function getTopLeft($delta = 0) {
  125. $lat = $this->result->results[$delta]->geometry->bounds->northeast->lat;
  126. $lon = $this->result->results[$delta]->geometry->bounds->southwest->lng;
  127. return new Point($lon, $lat);
  128. }
  129. private function getTopRight($delta = 0) {
  130. $lat = $this->result->results[$delta]->geometry->bounds->northeast->lat;
  131. $lon = $this->result->results[$delta]->geometry->bounds->northeast->lng;
  132. return new Point($lon, $lat);
  133. }
  134. private function getBottomLeft($delta = 0) {
  135. $lat = $this->result->results[$delta]->geometry->bounds->southwest->lat;
  136. $lon = $this->result->results[$delta]->geometry->bounds->southwest->lng;
  137. return new Point($lon, $lat);
  138. }
  139. private function getBottomRight($delta = 0) {
  140. $lat = $this->result->results[$delta]->geometry->bounds->southwest->lat;
  141. $lon = $this->result->results[$delta]->geometry->bounds->northeast->lng;
  142. return new Point($lon, $lat);
  143. }
  144. }