Skip to content

Commit 2643413

Browse files
committed
refactor: rte, wpt, and trk shared parsing logic
1 parent a4acc0b commit 2643413

File tree

1 file changed

+100
-121
lines changed

1 file changed

+100
-121
lines changed

app/Parsers/Files/GPXParser.php

+100-121
Original file line numberDiff line numberDiff line change
@@ -28,177 +28,156 @@ public function parseMarkersFromFile(string $filepath): array
2828

2929
if (isset($array['wpt'])) {
3030
foreach ($array['wpt'] as $marker) {
31-
// If the track name is not a string, we can't use it as a category name, so we use "Track" as the default
32-
if (
33-
!isset($marker['name']) ||
34-
!is_string($marker['name']) ||
35-
empty($marker['name'])
36-
) {
37-
$marker['name'] = $marker['sym'] ?? 'Waypoint';
38-
}
39-
40-
if (
41-
!isset($marker['desc']) ||
42-
!is_string($marker['desc']) ||
43-
empty($marker['desc'])
44-
) {
45-
$marker['desc'] = null;
46-
}
31+
$marker = $this->setMarkerDetails($marker, 'Waypoint');
4732

48-
$markerMeta = [];
33+
$markerLocations = [$this->buildMarkerLocationFromXmlElement($marker)];
4934

50-
// Add all direct children of the wpt element as metadata, except for the name and desc
51-
foreach ($marker as $key => $value) {
52-
if (in_array($key, $this->metadataKeys)) {
53-
continue;
54-
}
55-
56-
$markerMeta[$key] = $value;
35+
if (!count($markerLocations)) {
36+
continue;
5737
}
5838

59-
$markers[] = [
60-
'lat' => $marker['@attributes']['lat'],
61-
'lng' => $marker['@attributes']['lon'],
62-
'category_name' => $marker['name'],
63-
'description' => $marker['desc'] ?? null,
64-
'link' => $marker['link'] ?? null,
65-
'elevation' => $marker['ele'] ?? null,
66-
'created_at' => $marker['time'] ?? null,
67-
'updated_at' => $marker['time'] ?? null,
68-
'meta' => $markerMeta,
69-
];
39+
$markers[] = $this->buildMarker($marker, $markerLocations);
7040
}
7141
}
7242

73-
// We also need to add the trk. Each trk will be a single marker, and each trkpt will be a location for that marker.
7443
if (isset($array['trk'])) {
7544
foreach ($array['trk'] as $track) {
76-
$markerlocations = [];
45+
$markerLocations = [];
7746

7847
if (!isset($track['trkseg'])) {
7948
continue;
8049
}
8150

8251
foreach ($track['trkseg'] as $trkseg) {
8352
foreach ($trkseg as $trkpt) {
84-
$markerlocations[] = [
85-
'lat' => $trkpt['@attributes']['lat'],
86-
'lng' => $trkpt['@attributes']['lon'],
87-
'elevation' => $trkpt['ele'] ?? null,
88-
'created_at' => $trkpt['time'] ?? null,
89-
'updated_at' => $trkpt['time'] ?? null,
90-
];
53+
$markerLocations[] = $this->buildMarkerLocationFromXmlElement($trkpt);
9154
}
9255
}
9356

94-
if (!count($markerlocations)) {
57+
if (!count($markerLocations)) {
9558
continue;
9659
}
9760

98-
// If the track name is not a string, we can't use it as a category name, so we use "Track" as the default
99-
if (
100-
!is_string($track['name']) ||
101-
empty($track['name'])
102-
) {
103-
$track['name'] = 'Track';
104-
}
105-
106-
if (
107-
!is_string($track['desc']) ||
108-
empty($track['desc'])
109-
) {
110-
$track['desc'] = null;
111-
}
112-
113-
$markerMeta = [];
114-
115-
// Add all direct children of the trk element as metadata, except for the name and desc
116-
foreach ($track as $key => $value) {
117-
if (in_array($key, $this->metadataKeys)) {
118-
continue;
119-
}
120-
121-
$markerMeta[$key] = $value;
122-
}
123-
124-
$markers[] = [
125-
'description' => $track['desc'],
126-
'locations' => $markerlocations,
127-
// The category_name is the name of the track - parsed CDATA
128-
'category_name' => $track['name'],
129-
// Meta needs to be encoded as JSON
130-
'meta' => $markerMeta,
131-
];
61+
$markers[] = $this->buildMarker($track, $markerLocations);
13262
}
13363
}
13464

135-
// We need to handle rte as well. Each rte will be a single marker, and each rtept will be a location for that marker.
13665
if (isset($array['rte'])) {
137-
13866
// Sometimes the rte is not an array, but a single element, so we need to handle that. We can be sure its just a single element if it directly has rtept as a child
13967
if (isset($array['rte']['rtept'])) {
14068
$array['rte'] = [$array['rte']];
14169
}
14270

14371
foreach ($array['rte'] as $route) {
144-
$markerlocations = [];
72+
$markerLocations = [];
14573

14674
if (!isset($route['rtept'])) {
14775
continue;
14876
}
14977

15078
foreach ($route['rtept'] as $rtept) {
151-
$markerlocations[] = [
152-
'lat' => $rtept['@attributes']['lat'],
153-
'lng' => $rtept['@attributes']['lon'],
154-
'elevation' => $rtept['ele'] ?? null,
155-
'created_at' => $rtept['time'] ?? null,
156-
'updated_at' => $rtept['time'] ?? null,
157-
];
79+
$markerLocations[] = $this->buildMarkerLocationFromXmlElement($rtept);
15880
}
15981

160-
if (!count($markerlocations)) {
82+
if (!count($markerLocations)) {
16183
continue;
16284
}
16385

164-
// If the route name is not a string, we can't use it as a category name, so we use "Route" as the default
165-
if (
166-
!is_string($route['name']) ||
167-
empty($route['name'])
168-
) {
169-
$route['name'] = 'Route';
170-
}
171-
172-
if (
173-
!is_string($route['desc']) ||
174-
empty($route['desc'])
175-
) {
176-
$route['desc'] = null;
177-
}
86+
$markers[] = $this->buildMarker($route, $markerLocations);
87+
}
88+
}
17889

179-
$markerMeta = [];
90+
return $markers;
91+
}
18092

181-
// Add all direct children of the rte element as metadata, except for the name and desc
182-
foreach ($route as $key => $value) {
183-
if (in_array($key, $this->metadataKeys)) {
184-
continue;
185-
}
93+
/**
94+
* Build a marker location from a single xml element
95+
*
96+
* @param array $element
97+
* @return array
98+
*/
99+
private function buildMarkerLocationFromXmlElement(array $element): array
100+
{
101+
return [
102+
'lat' => $element['@attributes']['lat'],
103+
'lng' => $element['@attributes']['lon'],
104+
'elevation' => $element['ele'] ?? null,
105+
'created_at' => $element['time'] ?? null,
106+
'updated_at' => $element['time'] ?? null,
107+
];
108+
}
186109

187-
$markerMeta[$key] = $value;
188-
}
110+
/**
111+
* Get the metadata from the marker
112+
*
113+
* @param array $marker
114+
* @return array
115+
*/
116+
private function getMarkerMeta(array $marker): array
117+
{
118+
$markerMeta = [];
189119

190-
$markers[] = [
191-
'description' => $route['desc'],
192-
'locations' => $markerlocations,
193-
// The category_name is the name of the route - parsed CDATA
194-
'category_name' => $route['name'],
195-
// Meta needs to be encoded as JSON
196-
'meta' => $markerMeta,
197-
];
120+
// Add all direct children of the wpt element as metadata, except for the name and desc
121+
foreach ($marker as $key => $value) {
122+
if (in_array($key, $this->metadataKeys)) {
123+
continue;
198124
}
125+
126+
$markerMeta[$key] = $value;
199127
}
200128

201-
return $markers;
129+
return $markerMeta;
130+
}
131+
132+
/**
133+
* Set the marker details
134+
*
135+
* @param array $marker
136+
* @param string $fallbackName
137+
* @return array
138+
*/
139+
private function setMarkerDetails(array $marker, string $fallbackName = 'Marker')
140+
{
141+
// If the route name is not a string, we can't use it as a category name, so we use "Route" as the default
142+
if (
143+
!isset($marker['name']) ||
144+
!is_string($marker['name']) ||
145+
empty($marker['name'])
146+
) {
147+
$marker['name'] = $marker['sym'] ?? $fallbackName;
148+
}
149+
150+
if (
151+
!is_string($marker['desc']) ||
152+
empty($marker['desc'])
153+
) {
154+
$marker['desc'] = null;
155+
}
156+
157+
return $marker;
158+
}
159+
160+
/**
161+
* Build a marker
162+
*
163+
* @param array $marker
164+
* @param array $locations
165+
* @return array
166+
*/
167+
private function buildMarker(array $marker, array $locations)
168+
{
169+
$marker = $this->setMarkerDetails($marker);
170+
171+
$markerMeta = $this->getMarkerMeta($marker);
172+
173+
return
174+
[
175+
'description' => $marker['desc'],
176+
'locations' => $locations,
177+
'category_name' => $marker['name'],
178+
'link' => $marker['link'] ?? null,
179+
'meta' => $markerMeta,
180+
];
202181
}
203182

204183
public function parseMapDetailsFromFile(string $filepath): array

0 commit comments

Comments
 (0)