Total Complexity | 127 |
Total Lines | 1353 |
Duplicated Lines | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 1 |
Complex classes like Geometry often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Geometry, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | abstract class Geometry |
||
27 | { |
||
28 | |||
29 | /** |
||
30 | * Type constants |
||
31 | */ |
||
32 | const POINT = 'Point'; |
||
33 | const LINESTRING = 'LineString'; |
||
34 | const POLYGON = 'Polygon'; |
||
35 | const MULTI_POINT = 'MultiPoint'; |
||
36 | const MULTI_LINESTRING = 'MultiLineString'; |
||
37 | const MULTI_POLYGON = 'MultiPolygon'; |
||
38 | const GEOMETRY_COLLECTION = 'GeometryCollection'; |
||
39 | const CIRCULAR_STRING = 'CircularString'; |
||
40 | const COMPOUND_CURVE = 'CompoundCurve'; |
||
41 | const CURVE_POLYGON = 'CurvePolygon'; |
||
42 | const MULTI_CURVE = 'MultiCurve'; // Abstract |
||
43 | const MULTI_SURFACE = 'MultiSurface'; // Abstract |
||
44 | const CURVE = 'Curve'; // Abstract |
||
45 | const SURFACE = 'Surface'; // Abstract |
||
46 | const POLYHEDRAL_SURFACE = 'PolyhedralSurface'; |
||
47 | const TIN = 'TIN'; |
||
48 | const TRIANGLE = 'Triangle'; |
||
49 | |||
50 | /** |
||
51 | * @var bool True if Geometry has Z (altitude) value |
||
52 | */ |
||
53 | protected $hasZ = false; |
||
54 | |||
55 | /** |
||
56 | * @var bool True if Geometry has M (measure) value |
||
57 | */ |
||
58 | protected $isMeasured = false; |
||
59 | |||
60 | /** |
||
61 | * @var int|null $srid Spatial Reference System Identifier (http://en.wikipedia.org/wiki/SRID) |
||
62 | */ |
||
63 | protected $srid; |
||
64 | |||
65 | /** |
||
66 | * @var mixed|null Custom (meta)data |
||
67 | */ |
||
68 | protected $data; |
||
69 | |||
70 | /** |
||
71 | * @var \GEOSGeometry|null|false |
||
72 | */ |
||
73 | private $geos; |
||
74 | |||
75 | /** ************************************** |
||
76 | * Basic methods on geometric objects * |
||
77 | * ************************************* */ |
||
78 | |||
79 | /** |
||
80 | * The inherent dimension of the geometric object, which must be less than or equal to the coordinate dimension. |
||
81 | * In non-homogeneous collections, this will return the largest topological dimension of the contained objects. |
||
82 | * |
||
83 | * @return int |
||
84 | */ |
||
85 | abstract public function dimension(): int; |
||
86 | |||
87 | /** |
||
88 | * Returns the name of the instantiable subtype of Geometry of which the geometric object is an instantiable member. |
||
89 | * |
||
90 | * @return string |
||
91 | */ |
||
92 | abstract public function geometryType(): string; |
||
93 | |||
94 | /** |
||
95 | * Returns true whether the set of points covered by this Geometry is empty. |
||
96 | * |
||
97 | * @return bool |
||
98 | */ |
||
99 | abstract public function isEmpty(): bool; |
||
100 | |||
101 | /** |
||
102 | * Tests whether this geometry is simple. The SFS definition of simplicity follows the general rule that a Geometry |
||
103 | * is simple if it has no points of self-tangency, self-intersection or other anomalous points. |
||
104 | * Be aware: a geometry can be simple but also not valid! E.g. "LINESTRING(1 1,1 1)" or "POLYGON((1 1,1 1,1 1,1 1))" |
||
105 | * are simple but not valid. |
||
106 | * |
||
107 | * Simplicity is defined for each Geometry subclass as follows: |
||
108 | * - Valid polygonal geometries are simple, since their rings must not self-intersect. isSimple tests for this |
||
109 | * condition and reports false if it is not met. (This is a looser test than checking for validity). |
||
110 | * - Linear rings have the same semantics. |
||
111 | * - Linear geometries are simple if they do not self-intersect at points except on its end-points. |
||
112 | * - Zero-dimensional geometries (MultiPoints) are simple if they have no repeated points. |
||
113 | * - Empty Geometries are always simple. |
||
114 | * |
||
115 | * @return bool |
||
116 | */ |
||
117 | abstract public function isSimple(): bool; |
||
118 | |||
119 | /** |
||
120 | * Returns the boundary, or an empty geometry of appropriate dimension if this Geometry is empty. |
||
121 | * In the case of zero-dimensional geometries, an empty GeometryCollection is returned. |
||
122 | * The boundary of a Geometry is a set of Geometries of the next lower dimension. |
||
123 | * By default, the boundary of a collection is the boundary of it's components. |
||
124 | * |
||
125 | * @return Geometry the closure of the combinatorial boundary of this Geometry |
||
126 | */ |
||
127 | abstract public function boundary(): Geometry; |
||
128 | |||
129 | /** |
||
130 | * @return Geometry[] |
||
131 | */ |
||
132 | abstract public function getComponents(): array; |
||
133 | |||
134 | /** *********************************************** |
||
135 | * Methods applicable on certain geometry types * |
||
136 | * ********************************************** */ |
||
137 | |||
138 | /** |
||
139 | * Returns the area of this Geometry. |
||
140 | * Areal Geometries have a non-zero area. They override this function to compute the area. Others return 0.0 |
||
141 | * |
||
142 | * @return float |
||
143 | */ |
||
144 | public function area(): float |
||
145 | { |
||
146 | return $this->getArea(); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * |
||
151 | * @return Point |
||
152 | */ |
||
153 | public function centroid(): Point |
||
154 | { |
||
155 | return $this->getCentroid(); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * @see Geometry::getLength() |
||
160 | * @return float |
||
161 | */ |
||
162 | public function length(): float |
||
163 | { |
||
164 | return $this->getLength(); |
||
165 | } |
||
166 | |||
167 | abstract public function length3D(): float; |
||
168 | |||
169 | /** |
||
170 | * @see Geometry::getX() |
||
171 | * |
||
172 | * @return float|null |
||
173 | */ |
||
174 | public function x() |
||
175 | { |
||
176 | return $this->getX(); |
||
|
|||
177 | } |
||
178 | |||
179 | /** |
||
180 | * @see Geometry::getY() |
||
181 | * |
||
182 | * @return float|null |
||
183 | */ |
||
184 | public function y() |
||
185 | { |
||
186 | return $this->getY(); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * @see Geometry::getZ() |
||
191 | * |
||
192 | * @return float|null |
||
193 | */ |
||
194 | public function z() |
||
195 | { |
||
196 | return $this->getZ(); |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * @see Geometry::getM() |
||
201 | * |
||
202 | * @return float|null |
||
203 | */ |
||
204 | public function m() |
||
205 | { |
||
206 | return $this->getM(); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * @return int |
||
211 | */ |
||
212 | abstract public function numGeometries(): int; |
||
213 | |||
214 | /** |
||
215 | * @param int $n One-based index. |
||
216 | * @return Geometry|null The geometry or null if not found. |
||
217 | */ |
||
218 | abstract public function geometryN(int $n); |
||
219 | |||
220 | /** |
||
221 | * @return Point|null |
||
222 | */ |
||
223 | public function startPoint() |
||
224 | { |
||
225 | return null; |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * @return Point|null |
||
230 | */ |
||
231 | public function endPoint() |
||
232 | { |
||
233 | return null; |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * @return bool |
||
238 | * @throws UnsupportedMethodException |
||
239 | */ |
||
240 | public function isRing(): bool |
||
241 | { |
||
242 | throw new UnsupportedMethodException( |
||
243 | get_called_class() . '::isRing', |
||
244 | 0, |
||
245 | "It should only be called on a linear feature." |
||
246 | ); |
||
247 | } |
||
248 | |||
249 | abstract public function isClosed(): bool; |
||
250 | |||
251 | abstract public function numPoints(): int; |
||
252 | |||
253 | /** |
||
254 | * @param int $n Nth point |
||
255 | * @return Point|null |
||
256 | */ |
||
257 | public function pointN(int $n) |
||
258 | { |
||
259 | return null; |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * @return Geometry|null |
||
264 | */ |
||
265 | public function exteriorRing() |
||
266 | { |
||
267 | return null; |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * @return int|null |
||
272 | */ |
||
273 | public function numInteriorRings() |
||
274 | { |
||
275 | return null; |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * @return Geometry|null |
||
280 | */ |
||
281 | public function interiorRingN(int $n) |
||
282 | { |
||
283 | return null; |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * Returns the shortest distance between g1 and g2. |
||
288 | * The Geometry inputs for distance can be any combination of 2D or 3D geometries. |
||
289 | * If both geometries are 3D then a 3D distance is computed. |
||
290 | * If both geometries are 2D then a 2D distance is computed. |
||
291 | * If one geometry is 2D and the other is 3D then a 2D distance is computed (as if the 2D object was infinitely |
||
292 | * extended along the Z axis). |
||
293 | * |
||
294 | * @return float|null the distance between the geometries. null if input geometry is empty. |
||
295 | */ |
||
296 | abstract public function distance(Geometry $geom); |
||
297 | |||
298 | abstract public function equals(Geometry $geom): bool; |
||
299 | |||
300 | // Abstract: Non-Standard |
||
301 | // ---------------------------------------------------------- |
||
302 | |||
303 | /** |
||
304 | * @return array{'minx'?:float|null, 'miny'?:float|null, 'maxx'?:float|null, 'maxy'?:float|null} |
||
305 | */ |
||
306 | abstract public function getBBox(): array; |
||
307 | |||
308 | /** |
||
309 | * @return array<int, array> |
||
310 | */ |
||
311 | abstract public function asArray(): array; |
||
312 | |||
313 | /** |
||
314 | * @return Point[] |
||
315 | */ |
||
316 | abstract public function getPoints(): array; |
||
317 | |||
318 | /** |
||
319 | * @return self |
||
320 | */ |
||
321 | abstract public function invertXY(); |
||
322 | |||
323 | /** |
||
324 | * @param bool $toArray return underlying components as LineStrings/Points or as array. |
||
325 | * @return LineString[]|Point[]|array{}|array[] |
||
326 | */ |
||
327 | abstract public function explode(bool $toArray = false): array; |
||
328 | |||
329 | /** |
||
330 | * @param float|int $radius |
||
331 | * @return float 0.0 |
||
332 | */ |
||
333 | abstract public function greatCircleLength($radius = geoPHP::EARTH_WGS84_SEMI_MAJOR_AXIS): float; //meters |
||
334 | |||
335 | abstract public function haversineLength(): float; //degrees |
||
336 | |||
337 | /** |
||
338 | * 3D to 2D |
||
339 | * @return void |
||
340 | */ |
||
341 | abstract public function flatten(); |
||
342 | |||
343 | // Elevations statistics |
||
344 | |||
345 | /** |
||
346 | * @return int|float|null |
||
347 | */ |
||
348 | public function minimumZ() |
||
349 | { |
||
350 | return null; |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * @return int|float|null |
||
355 | */ |
||
356 | public function maximumZ() |
||
357 | { |
||
358 | return null; |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * @return int|float|null |
||
363 | */ |
||
364 | public function minimumM() |
||
365 | { |
||
366 | return null; |
||
367 | } |
||
368 | |||
369 | /** |
||
370 | * @return int|float|null |
||
371 | */ |
||
372 | public function maximumM() |
||
373 | { |
||
374 | return null; |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * @return int|float|null |
||
379 | */ |
||
380 | public function zDifference() |
||
381 | { |
||
382 | return null; |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * @param int|float $verticalTolerance |
||
387 | * @return int|float|null |
||
388 | */ |
||
389 | public function elevationGain($verticalTolerance = 0) |
||
390 | { |
||
391 | return null; |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * @param int|float $verticalTolerance |
||
396 | * @return int|float|null |
||
397 | */ |
||
398 | public function elevationLoss($verticalTolerance = 0) |
||
399 | { |
||
400 | return null; |
||
401 | } |
||
402 | |||
403 | // Public: Standard -- Common to all geometries |
||
404 | // ---------------------------------------------------------- |
||
405 | |||
406 | /** |
||
407 | * check if Geometry has Z (altitude) coordinate |
||
408 | * |
||
409 | * @return bool true if collection has Z value. |
||
410 | */ |
||
411 | public function is3D(): bool |
||
412 | { |
||
413 | return $this->hasZ(); |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * check if Geometry has a measure value |
||
418 | * |
||
419 | * @return bool true if collection has measure values |
||
420 | */ |
||
421 | abstract public function isMeasured(): bool; |
||
422 | |||
423 | /** |
||
424 | * @param int|null $srid Spatial Reference System Identifier |
||
425 | * @return void |
||
426 | */ |
||
427 | public function setSRID($srid) |
||
428 | { |
||
429 | $geosObj = $this->getGeos(); |
||
430 | if (is_object($geosObj)) { |
||
431 | // @codeCoverageIgnoreStart |
||
432 | /** @noinspection PhpUndefinedMethodInspection */ |
||
433 | $geosObj->setSRID($srid ?? 0); |
||
434 | // @codeCoverageIgnoreEnd |
||
435 | } |
||
436 | $this->srid = $srid; |
||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Adds custom data to the geometry |
||
441 | * |
||
442 | * @param string|array<mixed> $property The name of the data or an associative array |
||
443 | * @param mixed|null $value The data. Can be any type (string, integer, array, etc.) |
||
444 | * @return void |
||
445 | */ |
||
446 | public function setData($property, $value = null) |
||
447 | { |
||
448 | if (is_array($property)) { |
||
449 | $this->data = $property; |
||
450 | } else { |
||
451 | $this->data[$property] = $value; |
||
452 | } |
||
453 | } |
||
454 | |||
455 | /** |
||
456 | * Returns the requested data by property name, or all data of the geometry |
||
457 | * |
||
458 | * @param string|null $property The name of the data. If omitted, all data will be returned |
||
459 | * @return mixed|null The data or null if not exists |
||
460 | */ |
||
461 | public function getData($property = null) |
||
462 | { |
||
463 | if ($property) { |
||
464 | return $this->hasDataProperty($property) ? $this->data[$property] : null; |
||
465 | } |
||
466 | |||
467 | return $this->data; |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Tells whether the geometry has data with the specified name |
||
472 | * |
||
473 | * @param string $property The name of the property |
||
474 | * @return bool True if the geometry has data with the specified name, otherwise false. |
||
475 | */ |
||
476 | public function hasDataProperty($property): bool |
||
477 | { |
||
478 | return array_key_exists($property, $this->data ?: []); |
||
479 | } |
||
480 | |||
481 | /** |
||
482 | * returns the envelope of a geometry or the geometry itself if it is a point |
||
483 | * |
||
484 | * @return \geoPHP\Geometry\Geometry|null |
||
485 | */ |
||
486 | public function envelope() |
||
487 | { |
||
488 | if ($this->isEmpty()) { |
||
489 | $type = '\\geoPHP\\Geometry\\' . $this->geometryType(); |
||
490 | return new $type(); |
||
491 | } |
||
492 | if ($this->geometryType() === Geometry::POINT) { |
||
493 | return $this; |
||
494 | } |
||
495 | |||
496 | $geosObj = $this->getGeos(); |
||
497 | if (is_object($geosObj)) { |
||
498 | // @codeCoverageIgnoreStart |
||
499 | /** @noinspection PhpUndefinedMethodInspection */ |
||
500 | return geoPHP::geosToGeometry($geosObj->envelope()); |
||
501 | // @codeCoverageIgnoreEnd |
||
502 | } |
||
503 | |||
504 | $boundingBox = $this->getBBox(); |
||
505 | |||
506 | if (empty($boundingBox)) { |
||
507 | return new Polygon([new LineString()]); |
||
508 | } |
||
509 | |||
510 | $points = [ |
||
511 | new Point($boundingBox['maxx'], $boundingBox['miny']), |
||
512 | new Point($boundingBox['maxx'], $boundingBox['maxy']), |
||
513 | new Point($boundingBox['minx'], $boundingBox['maxy']), |
||
514 | new Point($boundingBox['minx'], $boundingBox['miny']), |
||
515 | new Point($boundingBox['maxx'], $boundingBox['miny']), |
||
516 | ]; |
||
517 | |||
518 | return new Polygon([new LineString($points)]); |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * Public: Non-Standard -- Common to all geometries |
||
523 | * $this->out($format, $other_args); |
||
524 | * |
||
525 | * @return string |
||
526 | */ |
||
527 | public function out(): string |
||
528 | { |
||
529 | $args = func_get_args(); |
||
530 | $format = strtolower(array_shift($args)); |
||
531 | |||
532 | // Big Endian WKB |
||
533 | if (strstr($format, 'xdr')) { |
||
534 | $args[] = true; |
||
535 | $format = str_replace('xdr', '', $format); |
||
536 | } |
||
537 | |||
538 | $processorType = '\\geoPHP\\Adapter\\' . geoPHP::getAdapterMap()[$format]; |
||
539 | $processor = new $processorType; |
||
540 | array_unshift($args, $this); |
||
541 | $result = call_user_func_array([$processor, 'write'], $args); |
||
542 | |||
543 | return $result; |
||
544 | } |
||
545 | |||
546 | /** |
||
547 | * @return int |
||
548 | */ |
||
549 | public function coordinateDimension(): int |
||
550 | { |
||
551 | return 2 + ($this->hasZ() ? 1 : 0) + ($this->isMeasured() ? 1 : 0); |
||
552 | } |
||
553 | |||
554 | /** |
||
555 | * Utility function to check if any line segments intersect |
||
556 | * Derived from @source http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect |
||
557 | * |
||
558 | * @param Point $segment1Start |
||
559 | * @param Point $segment1End |
||
560 | * @param Point $segment2Start |
||
561 | * @param Point $segment2End |
||
562 | * @return bool |
||
563 | */ |
||
564 | public static function segmentIntersects($segment1Start, $segment1End, $segment2Start, $segment2End): bool |
||
565 | { |
||
566 | $p0x = $segment1Start->getX(); |
||
567 | $p0y = $segment1Start->getY(); |
||
568 | $p1x = $segment1End->getX(); |
||
569 | $p1y = $segment1End->getY(); |
||
570 | $p2x = $segment2Start->getX(); |
||
571 | $p2y = $segment2Start->getY(); |
||
572 | $p3x = $segment2End->getX(); |
||
573 | $p3y = $segment2End->getY(); |
||
574 | |||
575 | $s1x = $p1x - $p0x; |
||
576 | $s1y = $p1y - $p0y; |
||
577 | $s2x = $p3x - $p2x; |
||
578 | $s2y = $p3y - $p2y; |
||
579 | |||
580 | $fps = (-$s2x * $s1y) + ($s1x * $s2y); |
||
581 | $fpt = (-$s2x * $s1y) + ($s1x * $s2y); |
||
582 | |||
583 | if ($fps == 0 || $fpt == 0) { |
||
584 | return false; |
||
585 | } |
||
586 | |||
587 | $s = (-$s1y * ($p0x - $p2x) + $s1x * ($p0y - $p2y)) / $fps; |
||
588 | $t = ($s2x * ($p0y - $p2y) - $s2y * ($p0x - $p2x)) / $fpt; |
||
589 | |||
590 | // Return true if collision is detected |
||
591 | return ($s > 0 && $s < 1 && $t > 0 && $t < 1); |
||
592 | |||
593 | /* |
||
594 | // x und y is for line 1 |
||
595 | // u und v is for line 2 |
||
596 | $x1 = $segment1Start->getX(); |
||
597 | $y1 = $segment1Start->getY(); |
||
598 | $x2 = $segment1End->getX(); |
||
599 | $y2 = $segment1End->getY(); |
||
600 | $u1 = $segment2Start->getX(); |
||
601 | $v1 = $segment2Start->getY(); |
||
602 | $u2 = $segment2End->getX(); |
||
603 | $v2 = $segment2End->getY(); |
||
604 | |||
605 | $dx = $x2 - $x1; |
||
606 | $dy = $y2 - $y1; |
||
607 | |||
608 | // avoid division with 0 |
||
609 | if ($dx != 0 && ($u2 - $u1) != 0) { |
||
610 | $b1 = $dy / $dx; |
||
611 | $b2 = ($v2 - $v1) / ($u2 - $u1); |
||
612 | } else { |
||
613 | $b1 = $b2 = 1; |
||
614 | } |
||
615 | |||
616 | // lines with identical inclines cannot cross, but can lie on top of each other. |
||
617 | // So calculation is done with their distances. |
||
618 | if ($b1 == $b2) { |
||
619 | if (($dx * ($v1 - $y1) - ($u1 - $x1) * $dy) == 0) { |
||
620 | return true; |
||
621 | } |
||
622 | // $u1, $v1 are on one line |
||
623 | elseif (($dx * ($v2 - $y1) - ($u2 - $x1) * $dy) == 0) { |
||
624 | return true; |
||
625 | } |
||
626 | |||
627 | return false; |
||
628 | } |
||
629 | |||
630 | $a1 = $y1 - $b1 * $x1; |
||
631 | $a2 = $v1 - $b2 * $u1; |
||
632 | |||
633 | $xi = -($a1 - $a2) / ($b1 - $b2); #(C) |
||
634 | $yi = $a1 + $b1 * $xi; |
||
635 | |||
636 | # lines cross at $xi,$yi |
||
637 | if (($x1 - $xi) * ($xi - $x2) >= 0 && |
||
638 | ($u1 - $xi) * ($xi - $u2) >= 0 && |
||
639 | ($y1 - $yi) * ($yi - $y2) >= 0 && |
||
640 | ($v1 - $yi) * ($yi - $v2) >= 0) { |
||
641 | return true; |
||
642 | } |
||
643 | |||
644 | return false; */ |
||
645 | } |
||
646 | |||
647 | // Public: Aliases |
||
648 | // ------------------------------------------------ |
||
649 | |||
650 | /** |
||
651 | * check if Geometry has Z (altitude) coordinate |
||
652 | * |
||
653 | * @return bool true if geometry has a Z-value |
||
654 | */ |
||
655 | abstract public function hasZ(): bool; |
||
656 | |||
657 | /** |
||
658 | * @return float|null |
||
659 | */ |
||
660 | public function getX() |
||
661 | { |
||
662 | return null; |
||
663 | /*throw new UnsupportedMethodException( |
||
664 | get_called_class() . '::getX', |
||
665 | null, |
||
666 | "Geometry has to be a point." |
||
667 | );*/ |
||
668 | } |
||
669 | |||
670 | /** |
||
671 | * @return float|null |
||
672 | */ |
||
673 | public function getY() |
||
674 | { |
||
675 | return null; |
||
676 | /*throw new UnsupportedMethodException( |
||
677 | get_called_class() . '::getY', |
||
678 | null, |
||
679 | "Geometry has to be a point." |
||
680 | );*/ |
||
681 | } |
||
682 | |||
683 | /** |
||
684 | * @return float|null |
||
685 | */ |
||
686 | public function getZ() |
||
687 | { |
||
688 | return null; |
||
689 | /*throw new UnsupportedMethodException( |
||
690 | get_called_class() . '::getZ', |
||
691 | null, |
||
692 | "Geometry has to be a point." |
||
693 | );*/ |
||
694 | } |
||
695 | |||
696 | /** |
||
697 | * @return float|null |
||
698 | */ |
||
699 | public function getM() |
||
700 | { |
||
701 | return null; |
||
702 | /*throw new UnsupportedMethodException( |
||
703 | get_called_class() . '::getM', |
||
704 | null, |
||
705 | "Geometry has to be a point." |
||
706 | );*/ |
||
707 | } |
||
708 | |||
709 | /** |
||
710 | * |
||
711 | * @return array{'minx'?:float|null, 'miny'?:float|null, 'maxx'?:float|null, 'maxy'?:float|null} |
||
712 | */ |
||
713 | public function getBoundingBox(): array |
||
714 | { |
||
715 | return $this->getBBox(); |
||
716 | } |
||
717 | |||
718 | /** |
||
719 | * |
||
720 | * @return Geometry[] |
||
721 | */ |
||
722 | public function dump(): array |
||
723 | { |
||
724 | return $this->getComponents(); |
||
725 | } |
||
726 | |||
727 | /** |
||
728 | * @return \geoPHP\Geometry\Point |
||
729 | */ |
||
730 | abstract public function getCentroid(): Point; |
||
731 | |||
732 | /** |
||
733 | * @see Geometry::area() |
||
734 | * @return float |
||
735 | */ |
||
736 | abstract public function getArea(): float; |
||
737 | |||
738 | /** |
||
739 | * Returns the length of this Geometry. |
||
740 | * Linear geometries return their length. Areal geometries return their perimeter. Others return 0.0 |
||
741 | * |
||
742 | * @return float |
||
743 | */ |
||
744 | public function getLength(): float |
||
745 | { |
||
746 | return 0.0; |
||
747 | } |
||
748 | |||
749 | /** |
||
750 | * @see Geometry::getGeos() |
||
751 | * @return \GEOSGeometry|false |
||
752 | */ |
||
753 | public function geos() |
||
754 | { |
||
755 | return $this->getGeos(); |
||
756 | } |
||
757 | |||
758 | /** |
||
759 | * |
||
760 | * @return string |
||
761 | */ |
||
762 | public function getGeomType(): string |
||
763 | { |
||
764 | return $this->geometryType(); |
||
765 | } |
||
766 | |||
767 | /** |
||
768 | * |
||
769 | * @return int|null |
||
770 | */ |
||
771 | public function getSRID() |
||
772 | { |
||
773 | return $this->srid; |
||
774 | } |
||
775 | |||
776 | /** |
||
777 | * |
||
778 | * @return string |
||
779 | */ |
||
780 | public function asText(): string |
||
781 | { |
||
782 | return $this->out('wkt'); |
||
783 | } |
||
784 | |||
785 | /** |
||
786 | * |
||
787 | * @return string |
||
788 | */ |
||
789 | public function asBinary(): string |
||
790 | { |
||
791 | return $this->out('wkb'); |
||
792 | } |
||
793 | |||
794 | /* * ************************************** |
||
795 | * Public: GEOS Only Functions * |
||
796 | * ************************************* */ |
||
797 | |||
798 | /** |
||
799 | * Returns the GEOS representation of Geometry if GEOS is installed |
||
800 | * |
||
801 | * @return \GEOSGeometry|false |
||
802 | * @codeCoverageIgnore |
||
803 | */ |
||
804 | public function getGeos() |
||
805 | { |
||
806 | // If it's already been set, just return it |
||
807 | if (isset($this->geos)) { |
||
808 | return $this->geos; |
||
809 | } |
||
810 | |||
811 | // It hasn't been set yet, generate it |
||
812 | if (geoPHP::geosInstalled()) { |
||
813 | /** @noinspection PhpUndefinedClassInspection */ |
||
814 | // Attention: EMPTY Points are not supported in WKB! |
||
815 | $reader = new \GEOSWKBReader(); |
||
816 | /** @noinspection PhpUndefinedMethodInspection */ |
||
817 | $this->geos = $reader->read($this->out('wkb')); |
||
818 | } else { |
||
819 | $this->geos = false; |
||
820 | } |
||
821 | |||
822 | return $this->geos; |
||
823 | } |
||
824 | |||
825 | /** |
||
826 | * @param \GEOSGeometry|null $geos |
||
827 | * @return void |
||
828 | */ |
||
829 | public function setGeos($geos = null) |
||
830 | { |
||
831 | $this->geos = $geos; |
||
832 | } |
||
833 | |||
834 | /** |
||
835 | * @return Geometry|Point|null |
||
836 | * @throws UnsupportedMethodException |
||
837 | * @codeCoverageIgnore |
||
838 | */ |
||
839 | public function pointOnSurface() |
||
840 | { |
||
841 | if ($this->isEmpty()) { |
||
842 | return new Point(); |
||
843 | } |
||
844 | $geosObj = $this->getGeos(); |
||
845 | if (is_object($geosObj)) { |
||
846 | /** @noinspection PhpUndefinedMethodInspection */ |
||
847 | return geoPHP::geosToGeometry($geosObj->pointOnSurface()); |
||
848 | } |
||
849 | // help for implementation: http://gis.stackexchange.com/questions/76498/how-is-st-pointonsurface-calculated |
||
850 | throw UnsupportedMethodException::geos(__METHOD__); |
||
851 | } |
||
852 | |||
853 | /** |
||
854 | * @param Geometry $geometry |
||
855 | * @return bool |
||
856 | * @throws UnsupportedMethodException |
||
857 | * @codeCoverageIgnore |
||
858 | */ |
||
859 | public function equalsExact(Geometry $geometry) |
||
860 | { |
||
861 | $geosObj = $this->getGeos(); |
||
862 | if (is_object($geosObj)) { |
||
863 | /** @noinspection PhpUndefinedMethodInspection */ |
||
864 | $geosObj2 = $geometry->getGeos(); |
||
865 | return is_object($geosObj2) ? $geosObj->equalsExact($geosObj2) : false; |
||
866 | } |
||
867 | throw UnsupportedMethodException::geos(__METHOD__); |
||
868 | } |
||
869 | |||
870 | /** |
||
871 | * @param Geometry $geometry |
||
872 | * @param string|null $pattern |
||
873 | * @return string|null |
||
874 | * @throws UnsupportedMethodException |
||
875 | * @codeCoverageIgnore |
||
876 | */ |
||
877 | public function relate(Geometry $geometry, $pattern = null) |
||
878 | { |
||
879 | $geosObj = $this->getGeos(); |
||
880 | if (is_object($geosObj)) { |
||
881 | $geosObj2 = $geometry->getGeos(); |
||
882 | if ($pattern !== null) { |
||
883 | /** @noinspection PhpUndefinedMethodInspection */ |
||
884 | return is_object($geosObj2) ? $geosObj->relate($geosObj2, $pattern) : null; |
||
885 | } else { |
||
886 | /** @noinspection PhpUndefinedMethodInspection */ |
||
887 | return is_object($geosObj2) ? $geosObj->relate($geosObj2) : null; |
||
888 | } |
||
889 | } |
||
890 | throw UnsupportedMethodException::geos(__METHOD__); |
||
891 | } |
||
892 | |||
893 | /** |
||
894 | * @return array<string,mixed> ['valid' => (bool)..., 'reason' => (string)...] |
||
895 | * @throws UnsupportedMethodException |
||
896 | * @codeCoverageIgnore |
||
897 | */ |
||
898 | public function checkValidity(): array |
||
899 | { |
||
900 | $geosObj = $this->getGeos(); |
||
901 | if (is_object($geosObj)) { |
||
902 | /** @noinspection PhpUndefinedMethodInspection */ |
||
903 | return $geosObj->checkValidity(); |
||
904 | } |
||
905 | throw UnsupportedMethodException::geos(__METHOD__); |
||
906 | } |
||
907 | |||
908 | /** |
||
909 | * @return bool |
||
910 | * @throws UnsupportedMethodException |
||
911 | * @codeCoverageIgnore |
||
912 | */ |
||
913 | public function isValid(): bool |
||
914 | { |
||
915 | $geosObj = $this->getGeos(); |
||
916 | if (is_object($geosObj)) { |
||
917 | /** @noinspection PhpUndefinedMethodInspection */ |
||
918 | return $geosObj->checkValidity()['valid']; |
||
919 | } |
||
920 | throw UnsupportedMethodException::geos(__METHOD__); |
||
921 | } |
||
922 | |||
923 | /** |
||
924 | * @param float|int $distance |
||
925 | * @return Geometry|null |
||
926 | * @throws UnsupportedMethodException |
||
927 | * @codeCoverageIgnore |
||
928 | */ |
||
929 | public function buffer($distance) |
||
930 | { |
||
931 | $geosObj = $this->getGeos(); |
||
932 | if (is_object($geosObj)) { |
||
933 | /** @noinspection PhpUndefinedMethodInspection */ |
||
934 | return geoPHP::geosToGeometry($geosObj->buffer($distance)); |
||
935 | } |
||
936 | throw UnsupportedMethodException::geos(__METHOD__); |
||
937 | } |
||
938 | |||
939 | /** |
||
940 | * @param Geometry $geometry |
||
941 | * @return Geometry|null |
||
942 | * @throws UnsupportedMethodException |
||
943 | * @codeCoverageIgnore |
||
944 | */ |
||
945 | public function intersection(Geometry $geometry) |
||
946 | { |
||
947 | $geosObj = $this->getGeos(); |
||
948 | if (is_object($geosObj)) { |
||
949 | $geosObj2 = $geometry->getGeos(); |
||
950 | /** @noinspection PhpUndefinedMethodInspection */ |
||
951 | return is_object($geosObj2) ? geoPHP::geosToGeometry($geosObj->intersection($geosObj2)) : null; |
||
952 | } |
||
953 | throw UnsupportedMethodException::geos(__METHOD__); |
||
954 | } |
||
955 | |||
956 | /** |
||
957 | * @param int|float $x1 |
||
958 | * @param int|float $y1 |
||
959 | * @param int|float $x2 |
||
960 | * @param int|float $y2 |
||
961 | * @return Geometry|null |
||
962 | * @throws UnsupportedMethodException |
||
963 | * @codeCoverageIgnore |
||
964 | */ |
||
965 | public function clipByRect($x1, $y1, $x2, $y2) |
||
966 | { |
||
967 | $geosObj = $this->getGeos(); |
||
968 | if (is_object($geosObj)) { |
||
969 | /** @noinspection PhpUndefinedMethodInspection */ |
||
970 | return geoPHP::geosToGeometry($geosObj->clipByRect($x1, $y1, $x2, $y2)); |
||
971 | } |
||
972 | throw UnsupportedMethodException::geos(__METHOD__); |
||
973 | } |
||
974 | |||
975 | /** |
||
976 | * @return Geometry|null |
||
977 | * @throws UnsupportedMethodException |
||
978 | * @codeCoverageIgnore |
||
979 | */ |
||
980 | public function convexHull() |
||
988 | } |
||
989 | |||
990 | /** |
||
991 | * @param float|int $tolerance snapping tolerance to use for improved robustness |
||
992 | * @param bool|false $onlyEdges if true will return a MULTILINESTRING, otherwise (the default) it will return a |
||
993 | * GEOMETRYCOLLECTION containing triangular POLYGONs. |
||
994 | * @return Geometry|null |
||
995 | * @throws UnsupportedMethodException |
||
996 | * @codeCoverageIgnore |
||
997 | */ |
||
998 | public function delaunayTriangulation($tolerance = 0.0, bool $onlyEdges = false) |
||
999 | { |
||
1000 | $geosObj = $this->getGeos(); |
||
1001 | if (is_object($geosObj)) { |
||
1002 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1003 | return geoPHP::geosToGeometry($geosObj->delaunayTriangulation($tolerance, $onlyEdges)); |
||
1004 | } |
||
1005 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1006 | } |
||
1007 | |||
1008 | /** |
||
1009 | * @param float|int $tolerance snapping tolerance to use for improved robustness |
||
1010 | * @param bool|false $onlyEdges if true will return a MULTILINESTRING, otherwise (the default) it will return a |
||
1011 | * GEOMETRYCOLLECTION containing POLYGONs. |
||
1012 | * @return Geometry|null |
||
1013 | * @throws UnsupportedMethodException |
||
1014 | * @codeCoverageIgnore |
||
1015 | */ |
||
1016 | public function voronoiDiagram($tolerance = 0.0, bool $onlyEdges = false) |
||
1017 | { |
||
1018 | $geosObj = $this->getGeos(); |
||
1019 | if (is_object($geosObj)) { |
||
1020 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1021 | return geoPHP::geosToGeometry($geosObj->voronoiDiagram($tolerance, $onlyEdges)); |
||
1022 | } |
||
1023 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1024 | } |
||
1025 | |||
1026 | /** |
||
1027 | * @param Geometry $geometry |
||
1028 | * @return Geometry|null |
||
1029 | * @throws UnsupportedMethodException |
||
1030 | * @codeCoverageIgnore |
||
1031 | */ |
||
1032 | public function difference(Geometry $geometry) |
||
1033 | { |
||
1034 | $geosObj = $this->getGeos(); |
||
1035 | if (is_object($geosObj)) { |
||
1036 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1037 | return geoPHP::geosToGeometry($geosObj->difference($geometry->getGeos())); |
||
1038 | } |
||
1039 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1040 | } |
||
1041 | |||
1042 | /** |
||
1043 | * Snaps the vertices and segments of a geometry to another Geometry's vertices. A snap distance tolerance is used |
||
1044 | * to control where snapping is performed. The result geometry is the input geometry with the vertices snapped. |
||
1045 | * If no snapping occurs then the input geometry is returned unchanged. |
||
1046 | * |
||
1047 | * Snapping one geometry to another can improve robustness for overlay operations by eliminating nearly-coincident |
||
1048 | * edges (which cause problems during noding and intersection calculation). |
||
1049 | * |
||
1050 | * Too much snapping can result in invalid topology being created, so the number and location of snapped vertices |
||
1051 | * is decided using heuristics to determine when it is safe to snap. This can result in some potential snaps being |
||
1052 | * omitted, however. |
||
1053 | * |
||
1054 | * @param Geometry $geometry |
||
1055 | * @param float $snapTolerance |
||
1056 | * @return Geometry|null |
||
1057 | * @throws UnsupportedMethodException |
||
1058 | * @codeCoverageIgnore |
||
1059 | */ |
||
1060 | public function snapTo(Geometry $geometry, $snapTolerance = 0.0) |
||
1061 | { |
||
1062 | $geosObj = $this->getGeos(); |
||
1063 | if (is_object($geosObj)) { |
||
1064 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1065 | return geoPHP::geosToGeometry($geosObj->snapTo($geometry->getGeos(), $snapTolerance)); |
||
1066 | } |
||
1067 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1068 | } |
||
1069 | |||
1070 | /** |
||
1071 | * @param Geometry $geometry |
||
1072 | * @return Geometry|null |
||
1073 | * @throws UnsupportedMethodException |
||
1074 | * @codeCoverageIgnore |
||
1075 | */ |
||
1076 | public function symDifference(Geometry $geometry) |
||
1084 | } |
||
1085 | |||
1086 | /** |
||
1087 | * Can pass in a geometry or an array of geometries |
||
1088 | * |
||
1089 | * @param Geometry|Geometry[] $geometry |
||
1090 | * @return Geometry|GeometryCollection|null |
||
1091 | * @throws UnsupportedMethodException |
||
1092 | * @codeCoverageIgnore |
||
1093 | */ |
||
1094 | public function union($geometry) |
||
1095 | { |
||
1096 | $geom = $this->getGeos(); |
||
1097 | if (is_object($geom)) { |
||
1098 | if (is_array($geometry)) { |
||
1099 | foreach ($geometry as $item) { |
||
1100 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1101 | $geom = $geom->union($item->geos()); |
||
1102 | } |
||
1103 | return geoPHP::geosToGeometry($geom); |
||
1104 | } else { |
||
1105 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1106 | return geoPHP::geosToGeometry($geom->union($geometry->getGeos())); |
||
1107 | } |
||
1108 | } |
||
1109 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1110 | } |
||
1111 | |||
1112 | /** |
||
1113 | * @param float $tolerance |
||
1114 | * @param bool|false $preserveTopology |
||
1115 | * @return Geometry|null |
||
1116 | * @throws UnsupportedMethodException |
||
1117 | * @codeCoverageIgnore |
||
1118 | */ |
||
1119 | public function simplify($tolerance, $preserveTopology = false) |
||
1120 | { |
||
1121 | $geosObj = $this->getGeos(); |
||
1122 | if (is_object($geosObj)) { |
||
1123 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1124 | return geoPHP::geosToGeometry($geosObj->simplify($tolerance, $preserveTopology)); |
||
1125 | } |
||
1126 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1127 | } |
||
1128 | |||
1129 | /** |
||
1130 | * @param int|float $dx |
||
1131 | * @param int|float $dy |
||
1132 | * @param int|float $dz |
||
1133 | * @return void |
||
1134 | */ |
||
1135 | abstract public function translate($dx = 0, $dy = 0, $dz = 0); |
||
1136 | |||
1137 | /** |
||
1138 | * The function attempts to create a valid representation of a given invalid geometry without losing any of the |
||
1139 | * input vertices. Already-valid geometries are returned without further intervention. |
||
1140 | * Supported inputs are: POINTS, MULTIPOINTS, LINESTRINGS, MULTILINESTRINGS, POLYGONS, MULTIPOLYGONS and |
||
1141 | * GEOMETRYCOLLECTIONS containing any mix of them. |
||
1142 | * In case of full or partial dimensional collapses, the output geometry may be a collection of lower-to-equal |
||
1143 | * dimension geometries or a geometry of lower dimension. Single polygons may become multi-geometries in case of |
||
1144 | * self-intersections. |
||
1145 | * |
||
1146 | * @return Geometry|null |
||
1147 | * @throws UnsupportedMethodException |
||
1148 | * @codeCoverageIgnore |
||
1149 | */ |
||
1150 | // public function makeValid() |
||
1151 | // { |
||
1152 | // $geosObj = $this->getGeos(); |
||
1153 | // if (is_object($geosObj)) { |
||
1154 | // /** @noinspection PhpUndefinedMethodInspection */ |
||
1155 | // return geoPHP::geosToGeometry($geosObj->makeValid()); |
||
1156 | // } |
||
1157 | // throw UnsupportedMethodException::geos(__METHOD__); |
||
1158 | // } |
||
1159 | |||
1160 | /** |
||
1161 | * Creates an areal geometry formed by the constituent linework of given geometry. The return type can be a |
||
1162 | * Polygon or MultiPolygon, depending on input. If the input lineworks do not form polygons NULL is returned. |
||
1163 | * The inputs can be LINESTRINGS, MULTILINESTRINGS, POLYGONS, MULTIPOLYGONS and GeometryCollections. |
||
1164 | * |
||
1165 | * @return Geometry|null |
||
1166 | * @throws UnsupportedMethodException |
||
1167 | * @codeCoverageIgnore |
||
1168 | */ |
||
1169 | // public function buildArea() |
||
1170 | // { |
||
1171 | // $geosObj = $this->getGeos(); |
||
1172 | // if (is_object($geosObj)) { |
||
1173 | // /** @noinspection PhpUndefinedMethodInspection */ |
||
1174 | // return geoPHP::geosToGeometry($geosObj->buildArea()); |
||
1175 | // } |
||
1176 | // throw UnsupportedMethodException::geos(__METHOD__); |
||
1177 | // } |
||
1178 | |||
1179 | /** |
||
1180 | * @param Geometry $geometry |
||
1181 | * @return bool |
||
1182 | * @throws UnsupportedMethodException |
||
1183 | * @codeCoverageIgnore |
||
1184 | */ |
||
1185 | public function disjoint(Geometry $geometry) |
||
1186 | { |
||
1187 | $geosObj = $this->getGeos(); |
||
1188 | if (is_object($geosObj)) { |
||
1189 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1190 | return $geosObj->disjoint($geometry->getGeos()); |
||
1191 | } |
||
1192 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1193 | } |
||
1194 | |||
1195 | /** |
||
1196 | * @param Geometry $geometry |
||
1197 | * @return bool |
||
1198 | * @throws UnsupportedMethodException |
||
1199 | * @codeCoverageIgnore |
||
1200 | */ |
||
1201 | public function touches(Geometry $geometry) |
||
1209 | } |
||
1210 | |||
1211 | /** |
||
1212 | * @param Geometry $geometry |
||
1213 | * @return bool |
||
1214 | * @throws UnsupportedMethodException |
||
1215 | * @codeCoverageIgnore |
||
1216 | */ |
||
1217 | public function intersects(Geometry $geometry) |
||
1218 | { |
||
1219 | $geosObj = $this->getGeos(); |
||
1220 | if (is_object($geosObj)) { |
||
1221 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1222 | return $geosObj->intersects($geometry->getGeos()); |
||
1223 | } |
||
1224 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1225 | } |
||
1226 | |||
1227 | /** |
||
1228 | * @param Geometry $geometry |
||
1229 | * @return bool |
||
1230 | * @throws UnsupportedMethodException |
||
1231 | * @codeCoverageIgnore |
||
1232 | */ |
||
1233 | public function crosses(Geometry $geometry) |
||
1241 | } |
||
1242 | |||
1243 | /** |
||
1244 | * @param Geometry $geometry |
||
1245 | * @return bool |
||
1246 | * @throws UnsupportedMethodException |
||
1247 | * @codeCoverageIgnore |
||
1248 | */ |
||
1249 | public function within(Geometry $geometry) |
||
1250 | { |
||
1251 | $geosObj = $this->getGeos(); |
||
1252 | if (is_object($geosObj)) { |
||
1253 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1254 | return $geosObj->within($geometry->getGeos()); |
||
1255 | } |
||
1256 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1257 | } |
||
1258 | |||
1259 | /** |
||
1260 | * @param Geometry $geometry |
||
1261 | * @return bool |
||
1262 | * @throws UnsupportedMethodException |
||
1263 | * @codeCoverageIgnore |
||
1264 | */ |
||
1265 | public function contains(Geometry $geometry) |
||
1266 | { |
||
1267 | $geosObj = $this->getGeos(); |
||
1268 | if (is_object($geosObj)) { |
||
1269 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1270 | return $geosObj->contains($geometry->getGeos()); |
||
1271 | } |
||
1272 | throw UnsupportedMethodException::geos(get_called_class() . '::contains'); |
||
1273 | } |
||
1274 | |||
1275 | /** |
||
1276 | * @param Geometry $geometry |
||
1277 | * @return bool |
||
1278 | * @throws UnsupportedMethodException |
||
1279 | * @codeCoverageIgnore |
||
1280 | */ |
||
1281 | public function overlaps(Geometry $geometry) |
||
1282 | { |
||
1283 | $geosObj = $this->getGeos(); |
||
1284 | if (is_object($geosObj)) { |
||
1285 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1286 | return $geosObj->overlaps($geometry->getGeos()); |
||
1287 | } |
||
1288 | throw UnsupportedMethodException::geos(get_called_class() . '::overlaps'); |
||
1289 | } |
||
1290 | |||
1291 | /** |
||
1292 | * @param Geometry $geometry |
||
1293 | * @return bool |
||
1294 | * @throws UnsupportedMethodException |
||
1295 | * @codeCoverageIgnore |
||
1296 | */ |
||
1297 | public function covers(Geometry $geometry) |
||
1298 | { |
||
1299 | $geosObj = $this->getGeos(); |
||
1300 | if (is_object($geosObj)) { |
||
1301 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1302 | return $geosObj->covers($geometry->getGeos()); |
||
1303 | } |
||
1304 | throw UnsupportedMethodException::geos(get_called_class() . '::covers'); |
||
1305 | } |
||
1306 | |||
1307 | /** |
||
1308 | * @param Geometry $geometry |
||
1309 | * @return bool |
||
1310 | * @throws UnsupportedMethodException |
||
1311 | * @codeCoverageIgnore |
||
1312 | */ |
||
1313 | public function coveredBy(Geometry $geometry) |
||
1314 | { |
||
1315 | $geosObj = $this->getGeos(); |
||
1316 | if (is_object($geosObj)) { |
||
1317 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1318 | return $geosObj->coveredBy($geometry->getGeos()); |
||
1319 | } |
||
1320 | throw UnsupportedMethodException::geos(get_called_class() . '::coveredBy'); |
||
1321 | } |
||
1322 | |||
1323 | /** |
||
1324 | * @param Geometry $geometry |
||
1325 | * @return float |
||
1326 | * @throws UnsupportedMethodException |
||
1327 | * @codeCoverageIgnore |
||
1328 | */ |
||
1329 | public function hausdorffDistance(Geometry $geometry) |
||
1330 | { |
||
1331 | $geosObj = $this->getGeos(); |
||
1332 | if (is_object($geosObj)) { |
||
1333 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1334 | return $geosObj->hausdorffDistance($geometry->getGeos()); |
||
1335 | } |
||
1336 | throw UnsupportedMethodException::geos(get_called_class() . '::hausdorffDistance'); |
||
1337 | } |
||
1338 | |||
1339 | /** |
||
1340 | * @param float|int $distance |
||
1341 | * @param array{quad_segs?:int|float,join?:int,mitre_limit?:int|float} $styleArray |
||
1342 | * styleArray keys supported: |
||
1343 | * - 'quad_segs' |
||
1344 | * (integer) Number of segments used to approximate a quarter circle (defaults to 8). |
||
1345 | * - 'join' |
||
1346 | * (float) Join style (defaults to GEOSBUF_JOIN_ROUND) |
||
1347 | * - 'mitre_limit' |
||
1348 | * (float) mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style) |
||
1349 | * 'miter_limit' is also accepted as a synonym for 'mitre_limit'. |
||
1350 | * |
||
1351 | * @return Geometry|null |
||
1352 | * @throws UnsupportedMethodException |
||
1353 | * @codeCoverageIgnore |
||
1354 | */ |
||
1355 | public function offsetCurve($distance = 0.0, array $styleArray = []) |
||
1363 | } |
||
1364 | |||
1365 | /** |
||
1366 | * @param Geometry $point |
||
1367 | * @return \GEOSGeometry |
||
1368 | * @throws UnsupportedMethodException |
||
1369 | * @codeCoverageIgnore |
||
1370 | */ |
||
1371 | public function project(Geometry $point) |
||
1372 | { |
||
1373 | $geosObj = $this->getGeos(); |
||
1374 | if (is_object($geosObj)) { |
||
1375 | /** @noinspection PhpUndefinedMethodInspection */ |
||
1376 | return $geosObj->project($point->getGeos()); |
||
1377 | } |
||
1378 | throw UnsupportedMethodException::geos(__METHOD__); |
||
1379 | } |
||
1380 | } |
||
1381 |
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.