From 6b1362408d3f74e11731f9ee167c8b7012436725 Mon Sep 17 00:00:00 2001 From: Daniele Barbaro Date: Tue, 8 Sep 2026 15:29:30 +0200 Subject: [PATCH] fix(parser): always return altitude as a float A coordinate declaring an altitude produced a float, one omitting it produced the integer 0, so the type of the same key depended on the input. The array shape documented on parsePointCoordinates() claims float in both cases, and PHPStan believed it. Callers comparing strictly, or encoding to JSON and diffing the result, saw 0 where they had been told to expect 0.0. --- src/Traits/ParsesCoordinates.php | 4 +-- tests/AltitudeTest.php | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 tests/AltitudeTest.php diff --git a/src/Traits/ParsesCoordinates.php b/src/Traits/ParsesCoordinates.php index 926c41b..b612246 100644 --- a/src/Traits/ParsesCoordinates.php +++ b/src/Traits/ParsesCoordinates.php @@ -16,7 +16,7 @@ protected function parsePointCoordinates(string $coordinates): array return [ 'longitude' => (float) $parts[0], 'latitude' => (float) ($parts[1] ?? 0), - 'altitude' => isset($parts[2]) ? (float) $parts[2] : 0, + 'altitude' => isset($parts[2]) ? (float) $parts[2] : 0.0, ]; } @@ -35,7 +35,7 @@ protected function parseLineStringCoordinates(string $coordinates): array $coords[] = [ 'longitude' => (float) $parts[0], 'latitude' => (float) $parts[1], - 'altitude' => isset($parts[2]) ? (float) $parts[2] : 0, + 'altitude' => isset($parts[2]) ? (float) $parts[2] : 0.0, ]; } } diff --git a/tests/AltitudeTest.php b/tests/AltitudeTest.php new file mode 100644 index 0000000..250c8ef --- /dev/null +++ b/tests/AltitudeTest.php @@ -0,0 +1,47 @@ + + + + + + {$coordinates} + + + + + {$coordinates} 7.9,45.9 + + + + +XML; +} + +it('returns a float altitude when the coordinate omits it', function () { + $placemarks = (new KmlParser)->loadFromString(kmlWithCoordinates('7.7,45.8'))->getPlacemarks(); + + expect($placemarks[0]['coordinates']['altitude'])->toBeFloat() + ->and($placemarks[1]['coordinates'][0]['altitude'])->toBeFloat() + ->and($placemarks[1]['coordinates'][1]['altitude'])->toBeFloat(); +}); + +it('returns a float altitude when the coordinate declares it', function () { + $placemark = (new KmlParser)->loadFromString(kmlWithCoordinates('7.7,45.8,12'))->getPlacemarks()[0]; + + expect($placemark['coordinates']['altitude'])->toBeFloat() + ->and($placemark['coordinates']['altitude'])->toBe(12.0); +}); + +it('keeps the altitude a float through to GeoJSON', function () { + $geometry = (new KmlParser)->loadFromString(kmlWithCoordinates('7.7,45.8')) + ->toGeoJson()['features'][0]['geometry']; + + expect($geometry['coordinates'][2])->toBeFloat() + ->and($geometry['coordinates'])->toBe([7.7, 45.8, 0.0]); +});