1<?php
2
3/**
4 * Geometry abstract class
5 */
6abstract class Geometry
7{
8  private   $geos = NULL;
9  protected $srid = NULL;
10  protected $geom_type;
11
12  // Abtract: Standard
13  // -----------------
14  abstract public function area();
15  abstract public function boundary();
16  abstract public function centroid();
17  abstract public function length();
18  abstract public function y();
19  abstract public function x();
20  abstract public function numGeometries();
21  abstract public function geometryN($n);
22  abstract public function startPoint();
23  abstract public function endPoint();
24  abstract public function isRing();            // Mssing dependancy
25  abstract public function isClosed();          // Missing dependancy
26  abstract public function numPoints();
27  abstract public function pointN($n);
28  abstract public function exteriorRing();
29  abstract public function numInteriorRings();
30  abstract public function interiorRingN($n);
31  abstract public function dimension();
32  abstract public function equals($geom);
33  abstract public function isEmpty();
34  abstract public function isSimple();
35
36  // Abtract: Non-Standard
37  // ---------------------
38  abstract public function getBBox();
39  abstract public function asArray();
40  abstract public function getPoints();
41  abstract public function explode();
42  abstract public function greatCircleLength(); //meters
43  abstract public function haversineLength(); //degrees
44
45
46  // Public: Standard -- Common to all geometries
47  // --------------------------------------------
48  public function SRID() {
49    return $this->srid;
50  }
51
52  public function setSRID($srid) {
53    if ($this->geos()) {
54      $this->geos()->setSRID($srid);
55    }
56    $this->srid = $srid;
57  }
58
59  public function envelope() {
60    if ($this->isEmpty()) return new Polygon();
61
62    if ($this->geos()) {
63      return geoPHP::geosToGeometry($this->geos()->envelope());
64    }
65
66    $bbox = $this->getBBox();
67    $points = array (
68      new Point($bbox['maxx'],$bbox['miny']),
69      new Point($bbox['maxx'],$bbox['maxy']),
70      new Point($bbox['minx'],$bbox['maxy']),
71      new Point($bbox['minx'],$bbox['miny']),
72      new Point($bbox['maxx'],$bbox['miny']),
73    );
74
75    $outer_boundary = new LineString($points);
76    return new Polygon(array($outer_boundary));
77  }
78
79  public function geometryType() {
80    return $this->geom_type;
81  }
82
83  // Public: Non-Standard -- Common to all geometries
84  // ------------------------------------------------
85
86  // $this->out($format, $other_args);
87  public function out() {
88    $args = func_get_args();
89
90    $format = array_shift($args);
91    $type_map = geoPHP::getAdapterMap();
92    $processor_type = $type_map[$format];
93    $processor = new $processor_type();
94
95    array_unshift($args, $this);
96    $result = call_user_func_array(array($processor, 'write'), $args);
97
98    return $result;
99  }
100
101
102  // Public: Aliases
103  // ---------------
104  public function getCentroid() {
105    return $this->centroid();
106  }
107
108  public function getArea() {
109    return $this->area();
110  }
111
112  public function getX() {
113    return $this->x();
114  }
115
116  public function getY() {
117    return $this->y();
118  }
119
120  public function getGeos() {
121    return $this->geos();
122  }
123
124  public function getGeomType() {
125    return $this->geometryType();
126  }
127
128  public function getSRID() {
129    return $this->SRID();
130  }
131
132  public function asText() {
133    return $this->out('wkt');
134  }
135
136  public function asBinary() {
137    return $this->out('wkb');
138  }
139
140  // Public: GEOS Only Functions
141  // ---------------------------
142  public function geos() {
143    // If it's already been set, just return it
144    if ($this->geos && geoPHP::geosInstalled()) {
145      return $this->geos;
146    }
147    // It hasn't been set yet, generate it
148    if (geoPHP::geosInstalled()) {
149      $reader = new GEOSWKBReader();
150      $this->geos = $reader->readHEX($this->out('wkb',TRUE));
151    }
152    else {
153      $this->geos = FALSE;
154    }
155    return $this->geos;
156  }
157
158  public function setGeos($geos) {
159    $this->geos = $geos;
160  }
161
162  public function pointOnSurface() {
163    if ($this->geos()) {
164      return geoPHP::geosToGeometry($this->geos()->pointOnSurface());
165    }
166  }
167
168  public function equalsExact(Geometry $geometry) {
169    if ($this->geos()) {
170      return $this->geos()->equalsExact($geometry->geos());
171    }
172  }
173
174  public function relate(Geometry $geometry, $pattern = NULL) {
175    if ($this->geos()) {
176      if ($pattern) {
177        return $this->geos()->relate($geometry->geos(), $pattern);
178      }
179      else {
180        return $this->geos()->relate($geometry->geos());
181      }
182    }
183  }
184
185  public function checkValidity() {
186    if ($this->geos()) {
187      return $this->geos()->checkValidity();
188    }
189  }
190
191  public function buffer($distance) {
192    if ($this->geos()) {
193      return geoPHP::geosToGeometry($this->geos()->buffer($distance));
194    }
195  }
196
197  public function intersection(Geometry $geometry) {
198    if ($this->geos()) {
199      return geoPHP::geosToGeometry($this->geos()->intersection($geometry->geos()));
200    }
201  }
202
203  public function convexHull() {
204    if ($this->geos()) {
205      return geoPHP::geosToGeometry($this->geos()->convexHull());
206    }
207  }
208
209  public function difference(Geometry $geometry) {
210    if ($this->geos()) {
211      return geoPHP::geosToGeometry($this->geos()->difference($geometry->geos()));
212    }
213  }
214
215  public function symDifference(Geometry $geometry) {
216    if ($this->geos()) {
217      return geoPHP::geosToGeometry($this->geos()->symDifference($geometry->geos()));
218    }
219  }
220
221  // Can pass in a geometry or an array of geometries
222  public function union(Geometry $geometry) {
223    if ($this->geos()) {
224      if (is_array($geometry)) {
225        $geom = $this->geos();
226        foreach ($geometry as $item) {
227          $geom = $geom->union($item->geos());
228        }
229        return geoPHP::geosToGeometry($geom);
230      }
231      else {
232        return geoPHP::geosToGeometry($this->geos()->union($geometry->geos()));
233      }
234    }
235  }
236
237  public function simplify($tolerance, $preserveTopology = FALSE) {
238    if ($this->geos()) {
239      return geoPHP::geosToGeometry($this->geos()->simplify($tolerance, $preserveTopology));
240    }
241  }
242
243  public function disjoint(Geometry $geometry) {
244    if ($this->geos()) {
245      return $this->geos()->disjoint($geometry->geos());
246    }
247  }
248
249  public function touches(Geometry $geometry) {
250    if ($this->geos()) {
251      return $this->geos()->touches($geometry->geos());
252    }
253  }
254
255  public function intersects(Geometry $geometry) {
256    if ($this->geos()) {
257      return $this->geos()->intersects($geometry->geos());
258    }
259  }
260
261  public function crosses(Geometry $geometry) {
262    if ($this->geos()) {
263      return $this->geos()->crosses($geometry->geos());
264    }
265  }
266
267  public function within(Geometry $geometry) {
268    if ($this->geos()) {
269      return $this->geos()->within($geometry->geos());
270    }
271  }
272
273  public function contains(Geometry $geometry) {
274    if ($this->geos()) {
275      return $this->geos()->contains($geometry->geos());
276    }
277  }
278
279  public function overlaps(Geometry $geometry) {
280    if ($this->geos()) {
281      return $this->geos()->overlaps($geometry->geos());
282    }
283  }
284
285  public function covers(Geometry $geometry) {
286    if ($this->geos()) {
287      return $this->geos()->covers($geometry->geos());
288    }
289  }
290
291  public function coveredBy(Geometry $geometry) {
292    if ($this->geos()) {
293      return $this->geos()->coveredBy($geometry->geos());
294    }
295  }
296
297  public function distance(Geometry $geometry) {
298    if ($this->geos()) {
299      return $this->geos()->distance($geometry->geos());
300    }
301  }
302
303  public function hausdorffDistance(Geometry $geometry) {
304    if ($this->geos()) {
305      return $this->geos()->hausdorffDistance($geometry->geos());
306    }
307  }
308
309  public function project(Geometry $point, $normalized = NULL) {
310    if ($this->geos()) {
311      return $this->geos()->project($point->geos(), $normalized);
312    }
313  }
314
315  // Public - Placeholders
316  // ---------------------
317  public function hasZ() {
318    // geoPHP does not support Z values at the moment
319    return FALSE;
320  }
321
322  public function is3D() {
323    // geoPHP does not support 3D geometries at the moment
324    return FALSE;
325  }
326
327  public function isMeasured() {
328    // geoPHP does not yet support M values
329    return FALSE;
330  }
331
332  public function coordinateDimension() {
333    // geoPHP only supports 2-dimensional space
334    return 2;
335  }
336
337  public function z() {
338    // geoPHP only supports 2-dimensional space
339    return NULL;
340  }
341
342  public function m() {
343    // geoPHP only supports 2-dimensional space
344    return NULL;
345  }
346
347}
348