From 0374f62c063d58e8ddbbdb4cd53d8f35e9bcb6c0 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Tue, 11 Aug 2026 16:09:40 -0400 Subject: [PATCH] Fix parsing of coordinate strings when locale is non-English [#628] --- CHANGELOG.md | 4 ++++ .../java/com/protomaps/basemap/Basemap.java | 5 +++-- .../com/protomaps/basemap/BasemapTest.java | 20 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cab50a0e..f018d437 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +Tiles 4.15.2 +------ +- Fix parsing of commas in non-English locales [#628] + Tiles 4.15.1 ------ - Change to generic Geopackage source for Natural Earth via @mxzinke and @wipfli [#626] diff --git a/tiles/src/main/java/com/protomaps/basemap/Basemap.java b/tiles/src/main/java/com/protomaps/basemap/Basemap.java index a71ce5f7..470bc3ac 100644 --- a/tiles/src/main/java/com/protomaps/basemap/Basemap.java +++ b/tiles/src/main/java/com/protomaps/basemap/Basemap.java @@ -27,6 +27,7 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import org.apache.parquet.ParquetReadOptions; import org.apache.parquet.hadoop.ParquetFileReader; @@ -134,7 +135,7 @@ public String description() { @Override public String version() { - return "4.15.1"; + return "4.15.2"; } @Override @@ -179,7 +180,7 @@ static java.util.Optional extractBoundsFromGeoParquet(Path parquetPath) Envelope bounds = geoparquet.primaryColumnMetadata().envelope(); if (bounds != null && !bounds.isNull() && bounds.getArea() > 0) { - String boundsStr = String.format("%f,%f,%f,%f", + String boundsStr = String.format(Locale.ROOT, "%f,%f,%f,%f", bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY()); return java.util.Optional.of(boundsStr); } diff --git a/tiles/src/test/java/com/protomaps/basemap/BasemapTest.java b/tiles/src/test/java/com/protomaps/basemap/BasemapTest.java index 69f0b25f..0bd6c745 100644 --- a/tiles/src/test/java/com/protomaps/basemap/BasemapTest.java +++ b/tiles/src/test/java/com/protomaps/basemap/BasemapTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.file.Path; +import java.util.Locale; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -60,6 +61,25 @@ void testExtractBoundsFromValidGeoParquet() { assertTrue(minY < maxY, "Min Y should be less than Max Y"); } + @Test + void testExtractBoundsUsesRootLocale() { + // A locale with a comma decimal separator must not corrupt the comma-separated bounds string. + Path testFile = Path.of("src", "test", "resources", "test-bounds.parquet"); + Locale previous = Locale.getDefault(); + try { + Locale.setDefault(Locale.GERMANY); + + Optional boundsOpt = Basemap.extractBoundsFromGeoParquet(testFile); + + assertTrue(boundsOpt.isPresent(), "Should extract bounds from valid GeoParquet file"); + String boundsStr = boundsOpt.get(); + assertEquals(4, boundsStr.split(",").length, "Bounds string should have 4 comma-separated values"); + assertEquals(-122.4241767, Double.parseDouble(boundsStr.split(",")[0]), 0.0001, "Min X should match"); + } finally { + Locale.setDefault(previous); + } + } + @Test void testExtractBoundsFromNonExistentFile() { // Test that a non-existent file returns empty