Passed
Push — master ( 58539d...96b0d3 )
by Mark
01:31
created

GoogleGeocode::read()   C

Complexity

Conditions 16
Paths 128

Size

Total Lines 49
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 49
rs 5.3333
c 0
b 0
f 0
cc 16
nc 128
nop 4

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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