1<?php
2
3namespace geoPHP\Geometry;
4
5use geoPHP\Exception\InvalidGeometryException;
6
7/**
8 * Class Curve
9 * TODO write this
10 *
11 * @package geoPHP\Geometry
12 * @method Point[] getComponents()
13 * @property Point[] $components A curve consists of sequence of Points
14 */
15abstract class Curve extends Collection
16{
17
18    public function __construct($components = [], $allowEmptyComponents = false, $allowedComponentType = Point::class)
19    {
20        if (is_array($components) && count($components) == 1) {
21            throw new InvalidGeometryException("Cannot construct a " . static::class . " with a single point");
22        }
23        parent::__construct($components, $allowEmptyComponents, $allowedComponentType);
24    }
25
26    protected $startPoint = null;
27
28    protected $endPoint = null;
29
30    public function geometryType()
31    {
32        return Geometry::CURVE;
33    }
34
35    public function dimension()
36    {
37        return 1;
38    }
39
40    public function startPoint()
41    {
42        if (!isset($this->startPoint)) {
43            $this->startPoint = $this->pointN(1);
44        }
45        return $this->startPoint;
46    }
47
48    public function endPoint()
49    {
50        if (!isset($this->endPoint)) {
51            $this->endPoint = $this->pointN($this->numPoints());
52        }
53        return $this->endPoint;
54    }
55
56    public function isClosed()
57    {
58        return ($this->startPoint() && $this->endPoint() ? $this->startPoint()->equals($this->endPoint()) : false);
59    }
60
61    public function isRing()
62    {
63        return ($this->isClosed() && $this->isSimple());
64    }
65
66    /**
67     * @return Point[]
68     */
69    public function getPoints()
70    {
71        return $this->getComponents();
72    }
73
74    /**
75     * The boundary of a non-closed Curve consists of its end Points
76     *
77     * @return LineString|MultiPoint
78     */
79    public function boundary()
80    {
81        return $this->isEmpty()
82            ? new LineString()
83            : ($this->isClosed()
84                ? new MultiPoint()
85                : new MultiPoint([$this->startPoint(), $this->endPoint()])
86            );
87    }
88
89    // Not valid for this geometry type
90    // --------------------------------
91    public function area()
92    {
93        return 0;
94    }
95
96    public function exteriorRing()
97    {
98        return null;
99    }
100
101    public function numInteriorRings()
102    {
103        return null;
104    }
105
106    public function interiorRingN($n)
107    {
108        return null;
109    }
110}
111