Passed
Pull Request — main (#10)
by
unknown
02:31
created

ElementFactory::buildForGeometryCollection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PrinsFrank\PhpGeoSVG\Html\Factory;
6
7
use PrinsFrank\PhpGeoSVG\Coordinator\Coordinator;
8
use PrinsFrank\PhpGeoSVG\Exception\NotImplementedException;
9
use PrinsFrank\PhpGeoSVG\Geometry\GeometryCollection;
10
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\GeometryObject;
11
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\LineString;
12
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\MultiLineString;
13
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\MultiPoint;
14
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\MultiPolygon;
15
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\Point;
16
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObject\Polygon;
17
use PrinsFrank\PhpGeoSVG\Geometry\GeometryObjectCallback;
18
use PrinsFrank\PhpGeoSVG\Geometry\Position\Position;
19
use PrinsFrank\PhpGeoSVG\Html\Elements\CircleElement;
20
use PrinsFrank\PhpGeoSVG\Html\Elements\Element;
21
use PrinsFrank\PhpGeoSVG\Html\Elements\GroupElement;
22
use PrinsFrank\PhpGeoSVG\Html\Elements\PathElement;
23
use PrinsFrank\PhpGeoSVG\Html\Elements\SvgElement;
24
use PrinsFrank\PhpGeoSVG\Html\Elements\Text\TextContent;
25
use PrinsFrank\PhpGeoSVG\Html\Elements\TitleElement;
26
use PrinsFrank\PhpGeoSVG\Html\Rendering\PathShapeRenderer;
27
28
class ElementFactory
29
{
30
    /**
31
     * @throws NotImplementedException
32
     */
33 2
    public static function buildForGeometryCollection(GeometryCollection $geometryCollection, Coordinator $coordinator): Element
34
    {
35 2
        $svgElement = (new SvgElement())
36 2
            ->setAttribute('width', $coordinator->getWidth())
37 2
            ->setAttribute('height', $coordinator->getHeight())
38 2
            ->setAttribute('viewbox', '0 0 ' . $coordinator->getWidth() . ' ' . $coordinator->getHeight());
39
40 2
        foreach ($geometryCollection->getGeometryObjects() as $geometryObject) {
41 1
            $svgElement->addChildElement(self::buildForGeometryObject($geometryObject, $coordinator, $geometryCollection->getGeometryObjectCallback()));
42
        }
43
44 2
        return $svgElement;
45
    }
46
47
    /**
48
     * @throws NotImplementedException
49
     */
50 4
    public static function buildForGeometryObject(GeometryObject $geometryObject, Coordinator $coordinator, GeometryObjectCallback $geometryObjectCallback = null): Element
51
    {
52 4
        $element = match (get_class($geometryObject)) {
53 4
            LineString::class => self::buildForLineString($geometryObject, $coordinator),
54 4
            MultiPoint::class => self::buildForMultiPoint($geometryObject, $coordinator),
55 4
            MultiPolygon::class => self::buildForMultiPolygon($geometryObject, $coordinator),
56 4
            MultiLineString::class => self::buildForMultiLineString($geometryObject, $coordinator),
57 4
            Polygon::class => self::buildForPolygon($geometryObject, $coordinator),
58 4
            Point::class => self::buildForPoint($geometryObject, $coordinator),
59 4
            default => throw new NotImplementedException('GeometryObject with class "' . get_class($geometryObject) . '" can\'t be built yet.')
60 4
        };
61
62 3
        if (null !== $geometryObject->getTitle()) {
63 1
            $element->addChildElement((new TitleElement())->setTextContent(new TextContent($geometryObject->getTitle())));
64
        }
65
66 3
        if (null !== $geometryObject->getFeatureClass()) {
67 1
            $element->setAttribute('data-feature-class', $geometryObject->getFeatureClass());
68
        }
69
70 3
        if(!is_null($geometryObjectCallback)) {
71
            $geometryObjectCallback->__invoke($geometryObject, $element);
72
        }
73
74 3
        return $element;
75
    }
76
77 1
    public static function buildForLineString(LineString $lineString, Coordinator $coordinator): PathElement
78
    {
79 1
        return (new PathElement())
80 1
            ->setAttribute('d', PathShapeRenderer::renderLineStringPath($lineString, $coordinator));
81
    }
82
83
    /**
84
     * @throws NotImplementedException
85
     */
86 2
    public static function buildForMultiPoint(MultiPoint $multiPoint, Coordinator $coordinator): GroupElement
87
    {
88 2
        $element = new GroupElement();
89 2
        foreach ($multiPoint->getPoints() as $point) {
90 1
            $element->addChildElement(self::buildForGeometryObject($point, $coordinator));
91
        }
92
93 2
        return $element;
94
    }
95
96
    /**
97
     * @throws NotImplementedException
98
     */
99 2
    public static function buildForMultiPolygon(MultiPolygon $multiPolygon, Coordinator $coordinator): GroupElement
100
    {
101 2
        $element = new GroupElement();
102 2
        foreach ($multiPolygon->getPolygons() as $polygon) {
103 1
            $element->addChildElement(self::buildForGeometryObject($polygon, $coordinator));
104
        }
105
106 2
        return $element;
107
    }
108
109
    /**
110
     * @throws NotImplementedException
111
     */
112 2
    public static function buildForMultiLineString(MultiLineString $multiLineString, Coordinator $coordinator): GroupElement
113
    {
114 2
        $element = new GroupElement();
115 2
        foreach ($multiLineString->getLineStrings() as $lineString) {
116 1
            $element->addChildElement(self::buildForGeometryObject($lineString, $coordinator));
117
        }
118
119 2
        return $element;
120
    }
121
122
    /**
123
     * @throws NotImplementedException
124
     */
125 2
    public static function buildForPolygon(Polygon $polygon, Coordinator $coordinator): Element
126
    {
127 2
        $element = new GroupElement();
128 2
        $element->addChildElement(self::buildForGeometryObject($polygon->getExteriorRing(), $coordinator));
129 2
        foreach ($polygon->getInteriorRings() as $interiorRing) {
130 1
            $element->addChildElement(self::buildForGeometryObject($interiorRing, $coordinator));
131
        }
132
133 2
        return $element;
134
    }
135
136 1
    public static function buildForPoint(Point $point, Coordinator $coordinator): CircleElement
137
    {
138 1
        return self::buildForPosition($point->getPosition(), $coordinator);
139
    }
140
141 1
    public static function buildForPosition(Position $position, Coordinator $coordinator): CircleElement
142
    {
143 1
        $element = new CircleElement();
144 1
        $element->setAttribute('cy', $coordinator->getY($position));
145 1
        $element->setAttribute('cx', $coordinator->getX($position));
146
147 1
        return $element;
148
    }
149
}
150