From 120c92eeb36db76d06da6ef765e27565aa91cce9 Mon Sep 17 00:00:00 2001 From: Mike Barry Date: Sat, 26 Oct 2024 07:08:08 -0400 Subject: [PATCH] accessor on feature --- .../planetiler/reader/SourceFeature.java | 27 ++++++++++++--- .../planetiler/FeatureCollectorTest.java | 33 +++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SourceFeature.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SourceFeature.java index 10a04a6a7f..f2d51fb197 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SourceFeature.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SourceFeature.java @@ -43,7 +43,8 @@ public abstract class SourceFeature implements WithTags, WithGeometryType, WithS private Geometry validPolygon = null; private double area = Double.NaN; private double length = Double.NaN; - private double size = Double.NaN; + private double areaMeters = Double.NaN; + private double lengthMeters = Double.NaN; private LineSplitter lineSplitter; /** @@ -283,7 +284,7 @@ public final Geometry validatedPolygon() throws GeometryException { * {@code 1} means the area of the entire planet. */ public double area() throws GeometryException { - return Double.isNaN(area) ? (area = canBePolygon() ? polygon().getArea() : 0) : area; + return Double.isNaN(area) ? (area = canBePolygon() ? Math.abs(polygon().getArea()) : 0) : area; } /** @@ -297,11 +298,27 @@ public double length() throws GeometryException { } /** - * Returns and caches sqrt of {@link #area()} if polygon or {@link #length()} if a line string. + * Returns the sqrt of {@link #area()} if polygon or {@link #length()} if a line string. */ public double size() throws GeometryException { - return Double.isNaN(size) ? (size = canBePolygon() ? Math.sqrt(Math.abs(area())) : canBeLine() ? length() : 0) : - size; + return canBePolygon() ? Math.sqrt(Math.abs(area())) : canBeLine() ? length() : 0; + } + + /** Returns and caches the approximate area of the geometry in square meters. */ + public double areaMeters() throws GeometryException { + return Double.isNaN(areaMeters) ? (areaMeters = + (isPoint() || canBePolygon() || canBeLine()) ? GeoUtils.areaInMeters(latLonGeometry()) : 0) : areaMeters; + } + + /** Returns and caches the approximate length of the geometry in meters. */ + public double lengthMeters() throws GeometryException { + return Double.isNaN(lengthMeters) ? (lengthMeters = + (isPoint() || canBePolygon() || canBeLine()) ? GeoUtils.lengthInMeters(latLonGeometry()) : 0) : lengthMeters; + } + + /** Returns the sqrt of {@link #areaMeters()} if polygon or {@link #lengthMeters()} if a line string. */ + public double sizeMeters() throws GeometryException { + return canBePolygon() ? Math.sqrt(Math.abs(areaMeters())) : canBeLine() ? lengthMeters() : 0; } /** Returns the ID of the source that this feature came from. */ diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/FeatureCollectorTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/FeatureCollectorTest.java index 799e2ae81f..8fa6e39449 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/FeatureCollectorTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/FeatureCollectorTest.java @@ -890,4 +890,37 @@ void testPointAlongLine() { assertFalse(iter.hasNext()); } + + + @Test + void testSizeInMetersOfLine() throws GeometryException { + var sourceLine = newReaderFeature(newLineString( + 0, 0, + 1, 0 + ), Map.of()); + + assertEquals(111_195, sourceLine.lengthMeters(), 1d); + assertEquals(111_195, sourceLine.sizeMeters(), 1d); + assertEquals(0, sourceLine.areaMeters()); + } + + + @Test + void testSizeInMetersOfPolygon() throws GeometryException { + var sourceLine = newReaderFeature(rectangle(0, 1), Map.of()); + + assertEquals(0, sourceLine.lengthMeters()); + assertEquals(111192, sourceLine.sizeMeters(), 1d); + assertEquals(Math.pow(111192.25757749, 2), sourceLine.areaMeters(), 1d); + } + + + @Test + void testSizeInMetersOfPoint() throws GeometryException { + var sourceLine = newReaderFeature(newPoint(0, 1), Map.of()); + + assertEquals(0, sourceLine.lengthMeters()); + assertEquals(0, sourceLine.sizeMeters()); + assertEquals(0, sourceLine.areaMeters()); + } }