From 517a2e6c34c4be90b573125dca56e12674e79c38 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 20 Jun 2024 15:05:40 -0700 Subject: [PATCH] Javadoc, etc --- .../jtstest/function/CoverageFunctions.java | 15 ++--- .../locationtech/jts/coverage/CornerArea.java | 24 +++++-- .../jts/coverage/CoverageSimplifier.java | 66 +++++++++++++++++-- 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/modules/app/src/main/java/org/locationtech/jtstest/function/CoverageFunctions.java b/modules/app/src/main/java/org/locationtech/jtstest/function/CoverageFunctions.java index d214ae153a..0e847718f2 100644 --- a/modules/app/src/main/java/org/locationtech/jtstest/function/CoverageFunctions.java +++ b/modules/app/src/main/java/org/locationtech/jtstest/function/CoverageFunctions.java @@ -119,11 +119,12 @@ public static Geometry simplifyInOut(Geometry coverage, } @Metadata(description="Simplify a coverage with per-geometry tolerances") - public static Geometry simplifyTolerances(Geometry coverage, String tolerances) { + public static Geometry simplifyTolerances(Geometry coverage, + @Metadata(title="Tolerances (comma-sep)") + String tolerancesCSV) { Geometry[] cov = toGeometryArray(coverage); - double[] toleranceList = tolerances(tolerances, cov.length); - CoverageSimplifier simplifier = new CoverageSimplifier(cov); - Geometry[] result = simplifier.simplify(toleranceList); + double[] tolerances = tolerances(tolerancesCSV, cov.length); + Geometry[] result = CoverageSimplifier.simplify(cov, tolerances); return FunctionsUtil.buildGeometry(result); } @@ -140,12 +141,6 @@ private static Double[] toDoubleArray(String csvList) { return Arrays.stream(csvList.split(",")).map(Double::parseDouble).toArray(Double[]::new); } - static Geometry extractPolygons(Geometry geom) { - List components = PolygonExtracter.getPolygons(geom); - Geometry result = geom.getFactory().buildGeometry(components); - return result; - } - private static Geometry[] toGeometryArray(Geometry geom) { Geometry[] geoms = new Geometry[geom.getNumGeometries()]; for (int i = 0; i < geom.getNumGeometries(); i++) { diff --git a/modules/core/src/main/java/org/locationtech/jts/coverage/CornerArea.java b/modules/core/src/main/java/org/locationtech/jts/coverage/CornerArea.java index 4710efc39e..8338625727 100644 --- a/modules/core/src/main/java/org/locationtech/jts/coverage/CornerArea.java +++ b/modules/core/src/main/java/org/locationtech/jts/coverage/CornerArea.java @@ -16,16 +16,32 @@ import org.locationtech.jts.geom.Triangle; import org.locationtech.jts.math.MathUtil; +/** + * Computes the effective area of corners, + * taking into account the smoothing weight. + * + *

FUTURE WORK

+ * + * Support computing geodetic area + * + * @author Martin Davis + * + */ class CornerArea { public static final double DEFAULT_SMOOTH_WEIGHT = 0.0; - private double weightSmooth = DEFAULT_SMOOTH_WEIGHT; + private double smoothWeight = DEFAULT_SMOOTH_WEIGHT; public CornerArea() { } - public CornerArea(double weightSmooth) { - this.weightSmooth = weightSmooth; + /** + * Creates a new corner area computer. + * + * @param smoothWeight the weight for smoothing corners. In range [0..1]. + */ + public CornerArea(double smoothWeight) { + this.smoothWeight = smoothWeight; } public double area(Coordinate pp, Coordinate p, Coordinate pn) { @@ -35,7 +51,7 @@ public double area(Coordinate pp, Coordinate p, Coordinate pn) { //-- rescale to [-1 .. 1], with 1 being narrow and -1 being flat double angBias = 1.0 - 2.0 * ang; //-- reduce area for narrower corners, to make them more likely to be removed - double areaWeighted = (1 - weightSmooth * angBias) * area; + double areaWeighted = (1 - smoothWeight * angBias) * area; return areaWeighted; } diff --git a/modules/core/src/main/java/org/locationtech/jts/coverage/CoverageSimplifier.java b/modules/core/src/main/java/org/locationtech/jts/coverage/CoverageSimplifier.java index 6f3273508f..24c65b047c 100644 --- a/modules/core/src/main/java/org/locationtech/jts/coverage/CoverageSimplifier.java +++ b/modules/core/src/main/java/org/locationtech/jts/coverage/CoverageSimplifier.java @@ -45,11 +45,16 @@ * At least one polygon is retained for each input geometry * (the one with largest area). * - * This class also supports inner simplification, which simplifies + * This class supports simplification using different distance tolerances + * for inner and outer edges of the coverage (including no simplfication + * using a tolerance of 0.0). + * This allows, for example, inner simplification, which simplifies * only edges of the coverage which are adjacent to two polygons. * This allows partial simplification of a coverage, since a simplified * subset of a coverage still matches the remainder of the coverage. *

+ * The class allows specifying a separate tolerance for each element of the input coverage. + *

* The input coverage should be valid according to {@link CoverageValidator}. * Invalid coverages may be simplified, but the result will likely still be invalid. * @@ -63,13 +68,24 @@ public class CoverageSimplifier { * * @param coverage a set of polygonal geometries forming a coverage * @param tolerance the simplification tolerance - * @return the simplified polygons + * @return the simplified coverage polygons */ public static Geometry[] simplify(Geometry[] coverage, double tolerance) { CoverageSimplifier simplifier = new CoverageSimplifier(coverage); return simplifier.simplify(tolerance); } + /** + * Simplifies the boundaries of a set of polygonal geometries forming a coverage, + * preserving the coverage topology, using a separate tolerance + * for each element of the coverage. + * Coverage edges are simplified using the lowest tolerance of each adjacent + * element. + * + * @param coverage a set of polygonal geometries forming a coverage + * @param tolerance the simplification tolerances (one per input element) + * @return the simplified coverage polygons + */ public static Geometry[] simplify(Geometry[] coverage, double[] tolerances) { CoverageSimplifier simplifier = new CoverageSimplifier(coverage); return simplifier.simplify(tolerances); @@ -82,13 +98,22 @@ public static Geometry[] simplify(Geometry[] coverage, double[] tolerances) { * * @param coverage a set of polygonal geometries forming a coverage * @param tolerance the simplification tolerance - * @return the simplified polygons + * @return the simplified coverage polygons */ public static Geometry[] simplifyInner(Geometry[] coverage, double tolerance) { CoverageSimplifier simplifier = new CoverageSimplifier(coverage); return simplifier.simplify(tolerance, 0); } + /** + * Simplifies the outer boundaries of a set of polygonal geometries forming a coverage, + * preserving the coverage topology. + * Edges in the interior of the coverage are left unchanged. + * + * @param coverage a set of polygonal geometries forming a coverage + * @param tolerance the simplification tolerance + * @return the simplified polygons + */ public static Geometry[] simplifyOuter(Geometry[] coverage, double tolerance) { CoverageSimplifier simplifier = new CoverageSimplifier(coverage); return simplifier.simplify(0, tolerance); @@ -122,27 +147,54 @@ public void setRemovableRingSizeFactor(double removableSizeFactor) { this.removableSizeFactor = factor; } + /** + * Sets the weight influencing how smooth the simplification should be. + * The weight must be between 0 and 1. + * Larger values increase the smoothness of the simplified edges. + * + * @param smoothWeight a value between 0 and 1 + */ public void setSmoothWeight(double smoothWeight) { + if (smoothWeight < 0.0 || smoothWeight > 1.0) + throw new IllegalArgumentException("smoothWeight must be in range [0 - 1]"); this.smoothWeight = smoothWeight; } /** - * Computes the simplified coverage, preserving the coverage topology. + * Computes the simplified coverage using a single distance tolerance, + * preserving the coverage topology. * - * @param tolerance the simplification tolerance - * @return the simplified polygons + * @param tolerance the simplification distance tolerance + * @return the simplified coverage polygons */ public Geometry[] simplify(double tolerance) { return simplifyEdges(tolerance, tolerance); } + /** + * Computes the simplified coverage using separate distance tolerances + * for inner and outer edges, + * preserving the coverage topology. + * + * @param toleranceInner the distance tolerance for inner edges + * @param toleranceOuter the distance tolerance for outer edges + * @return the simplified coverage polygons + */ public Geometry[] simplify(double toleranceInner, double toleranceOuter) { return simplifyEdges(toleranceInner, toleranceOuter); } + /** + * Computes the simplified coverage using separate distance tolerances + * for each coverage element, + * preserving the coverage topology. + * + * @param tolerances the distance tolerances for the coverage elements + * @return the simplified coverage polygons + */ public Geometry[] simplify(double[] tolerances) { if (tolerances.length != coverage.length) - throw new IllegalArgumentException("must have same number of tolerances as coverage elements"); + throw new IllegalArgumentException("number of tolerances does not match number of coverage elements"); return simplifyEdges(tolerances); }