Completed
Push — master ( 0885cd...ef8e35 )
by Antoine
02:22
created

BoundingBox::addCoordinate()   C

Complexity

Conditions 8
Paths 35

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 27
cts 27
cp 1
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 22
nc 35
nop 1
crap 8
1
<?php
2
3
/*
4
 * This file is part of the Geotools library.
5
 *
6
 * (c) Antoine Corcy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace League\Geotools\BoundingBox;
13
14
use League\Geotools\Coordinate\Coordinate;
15
use League\Geotools\Coordinate\CoordinateCollection;
16
use League\Geotools\Coordinate\CoordinateInterface;
17
use League\Geotools\Coordinate\Ellipsoid;
18
use League\Geotools\Exception\InvalidArgumentException;
19
use League\Geotools\Polygon\Polygon;
20
use League\Geotools\Polygon\PolygonInterface;
21
22
/**
23
 * @author Gabriel Bull <[email protected]>
24
 */
25
class BoundingBox implements BoundingBoxInterface
26
{
27
    /**
28
     * The latitude of the north coordinate
29
     *
30
     * @var float|string|integer
31
     */
32
    private $north;
33
34
    /**
35
     * The longitude of the east coordinate
36
     *
37
     * @var float|string|integer
38
     */
39
    private $east;
40
41
    /**
42
     * The latitude of the south coordinate
43
     *
44
     * @var float|string|integer
45
     */
46
    private $south;
47
48
    /**
49
     * The longitude of the west coordinate
50
     *
51
     * @var float|string|integer
52
     */
53
    private $west;
54
55
    /**
56
     * @var boolean
57
     */
58
    private $hasCoordinate = false;
59
60
    /**
61
     * @var Ellipsoid
62
     */
63
    private $ellipsoid;
64
65
    /**
66
     * @var integer
67
     */
68
    private $precision = 8;
69
70
    /**
71
     * @param PolygonInterface|CoordinateInterface $object
72
     */
73 38
    public function __construct($object = null)
74
    {
75 38
        if ($object instanceof PolygonInterface) {
76 38
            $this->setPolygon($object);
77 38
        } elseif ($object instanceof CoordinateInterface) {
78 1
            $this->addCoordinate($object);
79 5
        } elseif (null !== $object) {
80 1
            throw new \InvalidArgumentException;
81
        }
82 38
    }
83
84 38
    private function createBoundingBoxForPolygon(PolygonInterface $polygon)
85
    {
86 38
        $this->hasCoordinate = false;
87 38
        $this->west = $this->east = $this->north = $this->south = null;
88 38
        foreach ($polygon->getCoordinates() as $coordinate) {
89 31
            $this->addCoordinate($coordinate);
90 38
        }
91 38
    }
92
93
    /**
94
     * @param CoordinateInterface $coordinate
95
     */
96 32
    private function addCoordinate(CoordinateInterface $coordinate)
97
    {
98 32
        if ($this->ellipsoid === null) {
99 32
            $this->ellipsoid = $coordinate->getEllipsoid();
100 32
        } elseif ($this->ellipsoid != $coordinate->getEllipsoid()) {
101 1
            throw new InvalidArgumentException("Ellipsoids don't match");
102
        }
103
104 32
        $latitude  = $coordinate->getLatitude();
105 32
        $longitude = $coordinate->getLongitude();
106
107 32
        if (!$this->hasCoordinate) {
108 32
            $this->setNorth($latitude);
109 32
            $this->setSouth($latitude);
110 32
            $this->setEast($longitude);
111 32
            $this->setWest($longitude);
112 32
        } else {
113 18
            if (bccomp($latitude, $this->getSouth(), $this->getPrecision()) === -1) {
114 17
                $this->setSouth($latitude);
115 17
            }
116 18
            if (bccomp($latitude, $this->getNorth(), $this->getPrecision()) === 1) {
117 18
                $this->setNorth($latitude);
118 18
            }
119 18
            if (bccomp($longitude, $this->getEast(), $this->getPrecision()) === 1) {
120 18
                $this->setEast($longitude);
121 18
            }
122 18
            if (bccomp($longitude, $this->getWest(), $this->getPrecision()) === -1) {
123 1
                $this->setWest($longitude);
124 1
            }
125
        }
126
127 32
        $this->hasCoordinate = true;
128 32
    }
129
130
    /**
131
     * @param  CoordinateInterface $coordinate
132
     * @return bool
133
     */
134 4
    public function pointInBoundingBox(CoordinateInterface $coordinate)
135
    {
136 4
        if (bccomp($coordinate->getLatitude(), $this->getSouth(), $this->getPrecision()) === -1 ||
137 4
            bccomp($coordinate->getLatitude(), $this->getNorth(), $this->getPrecision()) === 1 ||
138 4
            bccomp($coordinate->getLongitude(), $this->getEast(), $this->getPrecision()) === 1 ||
139 2
            bccomp($coordinate->getLongitude(), $this->getWest(), $this->getPrecision()) === -1
140 4
        ) {
141 2
            return false;
142
        }
143
144 2
        return true;
145
    }
146
147
    /**
148
     * @return PolygonInterface
149
     */
150 3
    public function getAsPolygon()
151
    {
152 3
        if (!$this->hasCoordinate) {
153 1
            return null;
154
        }
155
156 3
        $nw = new Coordinate(array($this->north, $this->west), $this->ellipsoid);
157
158 3
        return new Polygon(
159 3
            new CoordinateCollection(
160
                array(
161 3
                    $nw,
162 3
                    new Coordinate(array($this->north, $this->east), $this->ellipsoid),
163 3
                    new Coordinate(array($this->south, $this->east), $this->ellipsoid),
164 3
                    new Coordinate(array($this->south, $this->west), $this->ellipsoid),
165
                    $nw
166 3
                ),
167 3
                $this->ellipsoid
168 3
            )
169 3
        );
170
    }
171
172
    /**
173
     * @param  PolygonInterface $polygon
174
     * @return $this
175
     */
176 38
    public function setPolygon(PolygonInterface $polygon)
177
    {
178 38
        $this->createBoundingBoxForPolygon($polygon);
179
180 38
        return $this;
181
    }
182
183
    /**
184
     * {@inheritDoc}
185
     */
186 18
    public function getNorth()
187
    {
188 18
        return $this->north;
189
    }
190
191
    /**
192
     * @param  float|string|integer $north
193
     * @return $this
194
     */
195 32
    public function setNorth($north)
196
    {
197 32
        $this->north = $north;
198
199 32
        return $this;
200
    }
201
202
    /**
203
     * {@inheritDoc}
204
     */
205 18
    public function getEast()
206
    {
207 18
        return $this->east;
208
    }
209
210
    /**
211
     * @param  float|string|integer $east
212
     * @return $this
213
     */
214 32
    public function setEast($east)
215
    {
216 32
        $this->east = $east;
217
218 32
        return $this;
219
    }
220
221
    /**
222
     * {@inheritDoc}
223
     */
224 18
    public function getSouth()
225
    {
226 18
        return $this->south;
227
    }
228
229
    /**
230
     * @param  float|string|integer $south
231
     * @return $this
232
     */
233 32
    public function setSouth($south)
234
    {
235 32
        $this->south = $south;
236
237 32
        return $this;
238
    }
239
240
    /**
241
     * {@inheritDoc}
242
     */
243 18
    public function getWest()
244
    {
245 18
        return $this->west;
246
    }
247
248
    /**
249
     * @param  float|string|integer $west
250
     * @return $this
251
     */
252 32
    public function setWest($west)
253
    {
254 32
        $this->west = $west;
255
256 32
        return $this;
257
    }
258
259
    /**
260
     * @return integer
261
     */
262 18
    public function getPrecision()
263
    {
264 18
        return $this->precision;
265
    }
266
267
    /**
268
     * @param  integer $precision
269
     * @return $this
270
     */
271 1
    public function setPrecision($precision)
272
    {
273 1
        $this->precision = $precision;
274
275 1
        return $this;
276
    }
277
278
    /**
279
     * @param  BoundingBoxInterface $boundingBox
280
     * @return BoundingBoxInterface
281
     */
282 2
    public function merge(BoundingBoxInterface $boundingBox)
283
    {
284 2
        $bbox = clone $this;
285
286 2
        $newCoordinates = $boundingBox->getAsPolygon()->getCoordinates();
287 2
        foreach ($newCoordinates as $coordinate) {
288 2
            $bbox->addCoordinate($coordinate);
289 2
        }
290
291 2
        return $bbox;
292
    }
293
}
294