Completed
Push — master ( 69bbac...c6a45b )
by Dragos
03:11
created

GPX::toString()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 26
nc 1
nop 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace SportTrackerConnector\Core\Workout\Dumper;
6
7
use DateTime;
8
use DateTimeZone;
9
use InvalidArgumentException;
10
use SportTrackerConnector\Core\Workout\Extension\ExtensionInterface;
11
use SportTrackerConnector\Core\Workout\Extension\HR;
12
use SportTrackerConnector\Core\Workout\TrackPoint;
13
use SportTrackerConnector\Core\Workout\Workout;
14
use XMLWriter;
15
16
/**
17
 * Dump a workout to GPX format.
18
 */
19
class GPX extends AbstractDumper
20
{
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function toString(Workout $workout) : string
25
    {
26
        $xmlWriter = new XMLWriter();
27
        $xmlWriter->openMemory();
28
        $xmlWriter->setIndent(true);
29
        $xmlWriter->startDocument('1.0', 'UTF-8');
30
        $xmlWriter->startElement('gpx');
31
32
        $xmlWriter->writeAttribute('version', '1.1');
33
        $xmlWriter->writeAttribute('creator', 'SportTrackerConnector');
34
        $xmlWriter->writeAttributeNs(
35
            'xsi',
36
            'schemaLocation',
37
            null,
38
            'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd'
39
        );
40
        $xmlWriter->writeAttribute('xmlns', 'http://www.topografix.com/GPX/1/1');
41
        $xmlWriter->writeAttributeNs(
42
            'xmlns',
43
            'gpxtpx',
44
            null,
45
            'http://www.garmin.com/xmlschemas/TrackPointExtension/v1'
46
        );
47
        $xmlWriter->writeAttributeNs('xmlns', 'gpxx', null, 'http://www.garmin.com/xmlschemas/GpxExtensions/v3');
48
        $xmlWriter->writeAttributeNs('xmlns', 'xsi', null, 'http://www.w3.org/2001/XMLSchema-instance');
49
50
        $this->writeMetaData($xmlWriter, $workout);
51
        $this->writeTracks($xmlWriter, $workout);
52
53
        $xmlWriter->endElement();
54
        $xmlWriter->endDocument();
55
56
        return $xmlWriter->outputMemory(true);
57
    }
58
59
    /**
60
     * Write the tracks to the GPX.
61
     *
62
     * @param XMLWriter $xmlWriter The XML writer.
63
     * @param Workout $workout The workout.
64
     */
65
    private function writeTracks(XMLWriter $xmlWriter, Workout $workout)
66
    {
67
        foreach ($workout->tracks() as $track) {
68
            $xmlWriter->startElement('trk');
69
            $xmlWriter->writeElement('type', $track->sport());
70
            $xmlWriter->startElement('trkseg');
71
            $this->writeTrackPoints($xmlWriter, $track->trackPoints());
72
            $xmlWriter->endElement();
73
            $xmlWriter->endElement();
74
        }
75
    }
76
77
    /**
78
     * Write the track points to the GPX.
79
     *
80
     * @param XMLWriter $xmlWriter The XML writer.
81
     * @param TrackPoint[] $trackPoints The track points to write.
82
     */
83
    private function writeTrackPoints(XMLWriter $xmlWriter, array $trackPoints)
84
    {
85
        foreach ($trackPoints as $trackPoint) {
86
            $xmlWriter->startElement('trkpt');
87
88
            // Location.
89
            $xmlWriter->writeAttribute('lat', (string)$trackPoint->latitude());
90
            $xmlWriter->writeAttribute('lon', (string)$trackPoint->longitude());
91
92
            // Elevation.
93
            $xmlWriter->writeElement('ele', (string)$trackPoint->getElevation());
94
95
            // Time of position
96
            $dateTime = clone $trackPoint->dateTime();
97
            $dateTime->setTimezone(new DateTimeZone('UTC'));
98
            $xmlWriter->writeElement('time', $dateTime->format(DateTime::W3C));
99
100
            // Extensions.
101
            $this->writeExtensions($xmlWriter, $trackPoint->extensions());
102
103
            $xmlWriter->endElement();
104
        }
105
    }
106
107
    /**
108
     * Write the extensions into the GPX.
109
     *
110
     * @param XMLWriter $xmlWriter The XMLWriter.
111
     * @param ExtensionInterface[] $extensions The extensions to write.
112
     * @throws InvalidArgumentException If an extension is not known.
113
     */
114
    protected function writeExtensions(XMLWriter $xmlWriter, array $extensions)
115
    {
116
        $xmlWriter->startElement('extensions');
117
        foreach ($extensions as $extension) {
118
            switch ($extension::ID()) {
119
                case HR::ID():
120
                    $xmlWriter->startElementNs('gpxtpx', 'TrackPointExtension', null);
121
                    $xmlWriter->writeElementNs('gpxtpx', 'hr', null, (string)$extension->value());
122
                    $xmlWriter->endElement();
123
                    break;
124
            }
125
        }
126
        $xmlWriter->endElement();
127
    }
128
129
    /**
130
     * Write the metadata in the GPX.
131
     *
132
     * @param XMLWriter $xmlWriter The XML writer.
133
     * @param Workout $workout The workout.
134
     */
135
    protected function writeMetaData(XMLWriter $xmlWriter, Workout $workout)
136
    {
137
        $xmlWriter->startElement('metadata');
138
        if ($workout->author() !== null) {
139
            $xmlWriter->startElement('author');
140
            $xmlWriter->writeElement('name', $workout->author()->name());
141
            $xmlWriter->endElement();
142
        }
143
        $xmlWriter->endElement();
144
    }
145
}
146