MultiLineString::getCentroid()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 32
rs 8.8333
cc 7
nc 9
nop 0
1
<?php
2
3
namespace geoPHP\Geometry;
4
5
use geoPHP\geoPHP;
6
7
/**
8
 * MultiLineString: A collection of LineStrings
9
 *
10
 * @package GeoPHPGeometry
11
 * @method  LineString[] getComponents()
12
 */
13
class MultiLineString extends MultiCurve
14
{
15
16
    public function __construct(array $components = [])
17
    {
18
        parent::__construct($components, true, LineString::class);
19
    }
20
21
    /**
22
     * @var LineString[] The elements of a MultiLineString are LineStrings
23
     */
24
    protected $components = [];
25
26
    /**
27
     * @return string "MultiLineString"
28
     */
29
    public function geometryType(): string
30
    {
31
        return Geometry::MULTI_LINESTRING;
32
    }
33
34
    /**
35
     * @return Point
36
     */
37
    public function getCentroid(): Point
38
    {
39
        if ($this->isEmpty()) {
40
            return new Point;
41
        }
42
43
        $geosObj = $this->getGeos();
44
        if (is_object($geosObj)) {
45
            // @codeCoverageIgnoreStart
46
            /** @noinspection PhpUndefinedMethodInspection */
47
            /** @var Point|null $geometry */
48
            $geometry = geoPHP::geosToGeometry($geosObj->centroid());
49
            return $geometry !== null ? $geometry : new Point();
50
            // @codeCoverageIgnoreEnd
51
        }
52
53
        $x = 0;
54
        $y = 0;
55
        $totalLength = 0.0;
56
        $components = $this->getComponents();
57
        foreach ($components as $line) {
58
            if ($line->isEmpty()) {
59
                continue;
60
            }
61
            $componentLength = $line->getLength();
62
            $componentCentroid = $line->getCentroid();
63
            $x += $componentCentroid->getX() * $componentLength;
64
            $y += $componentCentroid->getY() * $componentLength;
65
            $totalLength += $componentLength;
66
        }
67
68
        return $totalLength !== 0.0 ? new Point($x / $totalLength, $y / $totalLength) : $this->getPoints()[0];
0 ignored issues
show
introduced by
The condition $totalLength !== 0.0 is always false.
Loading history...
69
    }
70
71
    /**
72
     * The boundary of a MultiLineString is a MultiPoint which consists of the start and
73
     * end points of its non-closed LineStrings.
74
     *
75
     * @internal That seems not to be the full truth. When z-values come in, all gets a little confusing.
76
     *          PostGIS: "MULTILINESTRING((0 0 0, 1 0 0),(0 0 0, 1 0 1))" => "MULTIPOINT EMPTY"
77
     *          PostGIS: "MULTILINESTRING((0 0 0, 1 0 0),(0 0 0, 1 1 1))" => "MULTIPOINT(1 0 0,1 1 1)"
78
     *          PostGIS: "MULTILINESTRING((1 1 1, -1 1 1),(1 1 1,-1 1 0.5, 1 1 0.5))" => "MULTIPOINT(-1 1 1,1 1 0.75)"
79
     *          PostGIS: "MULTILINESTRING((0 0 0, -1 1 1),(0 0 0,-1 1 0.5, 1 1 0.5))" => "MULTIPOINT(-1 1 1,1 1 0.5)"
80
     *
81
     * @return MultiPoint
82
     */
83
    public function boundary(): Geometry
84
    {
85
        $points = [];
86
        foreach ($this->components as $line) {
87
            if (!$line->isEmpty() && !$line->isClosed()) {
88
                $points[] = $line->startPoint();
89
                $points[] = $line->endPoint();
90
            }
91
        }
92
        return new MultiPoint($points);
93
    }
94
}
95