From 1be2fca45f282e867d5cc624f90f00dd0d9c2d32 Mon Sep 17 00:00:00 2001 From: Michael Barry Date: Fri, 27 Oct 2023 20:29:26 -0400 Subject: [PATCH] Use some new Java 21 features (#695) --- .../benchmarks/BenchmarkMbtilesRead.java | 2 +- .../planetiler/FeatureCollector.java | 5 +- .../onthegomap/planetiler/FeatureMerge.java | 10 +-- .../com/onthegomap/planetiler/VectorTile.java | 73 +++++++++---------- .../collection/ArrayLongLongMapMmap.java | 2 +- .../collection/ExternalMergeSort.java | 2 +- .../planetiler/collection/FeatureGroup.java | 30 +++----- .../planetiler/expression/DataType.java | 21 ++---- .../planetiler/expression/Expression.java | 35 ++++----- .../expression/MultiExpression.java | 26 +++---- .../onthegomap/planetiler/geo/GeoUtils.java | 40 +++++----- .../planetiler/geo/PolygonIndex.java | 8 +- .../planetiler/geo/TileExtents.java | 4 +- .../planetiler/reader/GeoPackageReader.java | 2 +- .../planetiler/reader/NaturalEarthReader.java | 2 +- .../planetiler/reader/ShapefileReader.java | 2 +- .../planetiler/reader/SourceFeature.java | 2 +- .../reader/osm/OsmMultipolygon.java | 2 +- .../planetiler/reader/osm/PbfDecoder.java | 4 +- .../render/GeometryCoordinateSequences.java | 4 +- .../planetiler/render/TiledGeometry.java | 10 +-- .../planetiler/stats/ProcessInfo.java | 4 +- .../planetiler/stats/ProcessTime.java | 7 +- .../planetiler/stats/ProgressLoggers.java | 2 +- .../onthegomap/planetiler/util/AwsOsm.java | 2 +- .../planetiler/util/Downloader.java | 7 +- .../onthegomap/planetiler/util/Geofabrik.java | 2 +- .../onthegomap/planetiler/util/SortKey.java | 16 ++-- .../planetiler/util/Translations.java | 2 +- .../planetiler/worker/WorkerPipeline.java | 11 +-- .../planetiler/PlanetilerTests.java | 4 +- .../onthegomap/planetiler/VectorTileTest.java | 4 +- .../reader/ShapefileReaderTest.java | 6 +- .../render/FeatureRendererTest.java | 2 +- .../planetiler/custommap/Contexts.java | 2 +- .../expression/ConfigExpression.java | 2 +- .../planetiler/examples/OsmQaTiles.java | 10 ++- 37 files changed, 165 insertions(+), 204 deletions(-) diff --git a/planetiler-benchmarks/src/main/java/com/onthegomap/planetiler/benchmarks/BenchmarkMbtilesRead.java b/planetiler-benchmarks/src/main/java/com/onthegomap/planetiler/benchmarks/BenchmarkMbtilesRead.java index b9255ffa..e0a19f94 100644 --- a/planetiler-benchmarks/src/main/java/com/onthegomap/planetiler/benchmarks/BenchmarkMbtilesRead.java +++ b/planetiler-benchmarks/src/main/java/com/onthegomap/planetiler/benchmarks/BenchmarkMbtilesRead.java @@ -47,7 +47,7 @@ public class BenchmarkMbtilesRead { List randomCoordsToFetchPerRepetition = new LinkedList<>(); do { - try (var db = Mbtiles.newReadOnlyDatabase(mbtilesPaths.get(0))) { + try (var db = Mbtiles.newReadOnlyDatabase(mbtilesPaths.getFirst())) { try (var statement = db.connection().prepareStatement(SELECT_RANDOM_COORDS)) { statement.setInt(1, nrTileReads - randomCoordsToFetchPerRepetition.size()); var rs = statement.executeQuery(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureCollector.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureCollector.java index d7a9b075..49729ee7 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureCollector.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureCollector.java @@ -22,16 +22,13 @@ import org.locationtech.jts.geom.Geometry; * feature. *

* For example to add a polygon feature for a lake and a center label point with its name: - * - *

- * {@code
+ * {@snippet :
  * featureCollector.polygon("water")
  *   .setAttr("class", "lake");
  * featureCollector.centroid("water_name")
  *   .setAttr("class", "lake")
  *   .setAttr("name", element.getString("name"));
  * }
- * 
*/ public class FeatureCollector implements Iterable { diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureMerge.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureMerge.java index 202178d8..d272cf11 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureMerge.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/FeatureMerge.java @@ -124,7 +124,7 @@ public class FeatureMerge { List result = new ArrayList<>(features.size()); var groupedByAttrs = groupByAttrs(features, result, geometryType); for (List groupedFeatures : groupedByAttrs) { - VectorTile.Feature feature1 = groupedFeatures.get(0); + VectorTile.Feature feature1 = groupedFeatures.getFirst(); if (groupedFeatures.size() == 1) { result.add(feature1); } else { @@ -158,7 +158,7 @@ public class FeatureMerge { List result = new ArrayList<>(features.size()); var groupedByAttrs = groupByAttrs(features, result, GeometryType.LINE); for (List groupedFeatures : groupedByAttrs) { - VectorTile.Feature feature1 = groupedFeatures.get(0); + VectorTile.Feature feature1 = groupedFeatures.getFirst(); double lengthLimit = lengthLimitCalculator.apply(feature1.attrs()); // as a shortcut, can skip line merging only if: @@ -300,7 +300,7 @@ public class FeatureMerge { Collection> groupedByAttrs = groupByAttrs(features, result, GeometryType.POLYGON); for (List groupedFeatures : groupedByAttrs) { List outPolygons = new ArrayList<>(); - VectorTile.Feature feature1 = groupedFeatures.get(0); + VectorTile.Feature feature1 = groupedFeatures.getFirst(); List geometries = new ArrayList<>(groupedFeatures.size()); for (var feature : groupedFeatures) { try { @@ -331,7 +331,7 @@ public class FeatureMerge { } merged = GeoUtils.snapAndFixPolygon(merged, stats, "merge").reverse(); } else { - merged = polygonGroup.get(0); + merged = polygonGroup.getFirst(); if (!(merged instanceof Polygonal) || merged.getEnvelopeInternal().getArea() < minArea) { continue; } @@ -572,5 +572,5 @@ public class FeatureMerge { return result; } - private record WithIndex (T feature, int hilbert) {} + private record WithIndex(T feature, int hilbert) {} } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/VectorTile.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/VectorTile.java index 811b5084..cc7ca9b8 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/VectorTile.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/VectorTile.java @@ -263,7 +263,7 @@ public class VectorTile { lineStrings.add(gf.createLineString(coordSeq)); } if (lineStrings.size() == 1) { - geometry = lineStrings.get(0); + geometry = lineStrings.getFirst(); } else if (lineStrings.size() > 1) { geometry = gf.createMultiLineString(lineStrings.toArray(new LineString[0])); } @@ -305,12 +305,12 @@ public class VectorTile { } List polygons = new ArrayList<>(); for (List rings : polygonRings) { - LinearRing shell = rings.get(0); + LinearRing shell = rings.getFirst(); LinearRing[] holes = rings.subList(1, rings.size()).toArray(new LinearRing[rings.size() - 1]); polygons.add(gf.createPolygon(shell, holes)); } if (polygons.size() == 1) { - geometry = polygons.get(0); + geometry = polygons.getFirst(); } if (polygons.size() > 1) { geometry = gf.createMultiPolygon(GeometryFactory.toPolygonArray(polygons)); @@ -376,7 +376,7 @@ public class VectorTile { for (VectorTileProto.Tile.Feature feature : layer.getFeaturesList()) { int tagsCount = feature.getTagsCount(); - Map attrs = new HashMap<>(tagsCount / 2); + Map attrs = HashMap.newHashMap(tagsCount / 2); int tagIdx = 0; while (tagIdx < feature.getTagsCount()) { String key = keys.get(feature.getTags(tagIdx++)); @@ -509,20 +509,14 @@ public class VectorTile { for (Object value : layer.values()) { VectorTileProto.Tile.Value.Builder tileValue = VectorTileProto.Tile.Value.newBuilder(); - if (value instanceof String stringValue) { - tileValue.setStringValue(stringValue); - } else if (value instanceof Integer intValue) { - tileValue.setSintValue(intValue); - } else if (value instanceof Long longValue) { - tileValue.setSintValue(longValue); - } else if (value instanceof Float floatValue) { - tileValue.setFloatValue(floatValue); - } else if (value instanceof Double doubleValue) { - tileValue.setDoubleValue(doubleValue); - } else if (value instanceof Boolean booleanValue) { - tileValue.setBoolValue(booleanValue); - } else { - tileValue.setStringValue(value.toString()); + switch (value) { + case String stringValue -> tileValue.setStringValue(stringValue); + case Integer intValue -> tileValue.setSintValue(intValue); + case Long longValue -> tileValue.setSintValue(longValue); + case Float floatValue -> tileValue.setFloatValue(floatValue); + case Double doubleValue -> tileValue.setDoubleValue(doubleValue); + case Boolean booleanValue -> tileValue.setBoolValue(booleanValue); + case Object other -> tileValue.setStringValue(other.toString()); } tileLayer.addValues(tileValue.build()); } @@ -1072,31 +1066,32 @@ public class VectorTile { } void accept(Geometry geometry) { - if (geometry instanceof MultiLineString multiLineString) { - for (int i = 0; i < multiLineString.getNumGeometries(); i++) { - encode(((LineString) multiLineString.getGeometryN(i)).getCoordinateSequence(), false, GeometryType.LINE); + switch (geometry) { + case MultiLineString multiLineString -> { + for (int i = 0; i < multiLineString.getNumGeometries(); i++) { + encode(((LineString) multiLineString.getGeometryN(i)).getCoordinateSequence(), false, GeometryType.LINE); + } } - } else if (geometry instanceof Polygon polygon) { - LineString exteriorRing = polygon.getExteriorRing(); - encode(exteriorRing.getCoordinateSequence(), true, GeometryType.POLYGON); - - for (int i = 0; i < polygon.getNumInteriorRing(); i++) { - LineString interiorRing = polygon.getInteriorRingN(i); - encode(interiorRing.getCoordinateSequence(), true, GeometryType.LINE); + case Polygon polygon -> { + LineString exteriorRing = polygon.getExteriorRing(); + encode(exteriorRing.getCoordinateSequence(), true, GeometryType.POLYGON); + for (int i = 0; i < polygon.getNumInteriorRing(); i++) { + LineString interiorRing = polygon.getInteriorRingN(i); + encode(interiorRing.getCoordinateSequence(), true, GeometryType.LINE); + } } - } else if (geometry instanceof MultiPolygon multiPolygon) { - for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { - accept(multiPolygon.getGeometryN(i)); + case MultiPolygon multiPolygon -> { + for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { + accept(multiPolygon.getGeometryN(i)); + } } - } else if (geometry instanceof LineString lineString) { - encode(lineString.getCoordinateSequence(), shouldClosePath(geometry), GeometryType.LINE); - } else if (geometry instanceof Point point) { - encode(point.getCoordinateSequence(), false, GeometryType.POINT); - } else if (geometry instanceof Puntal) { - encode(new CoordinateArraySequence(geometry.getCoordinates()), shouldClosePath(geometry), + case LineString lineString -> + encode(lineString.getCoordinateSequence(), shouldClosePath(geometry), GeometryType.LINE); + case Point point -> encode(point.getCoordinateSequence(), false, GeometryType.POINT); + case Puntal ignored -> encode(new CoordinateArraySequence(geometry.getCoordinates()), shouldClosePath(geometry), geometry instanceof MultiPoint, GeometryType.POINT); - } else { - LOGGER.warn("Unrecognized geometry type: " + geometry.getGeometryType()); + case null -> LOGGER.warn("Null geometry type"); + default -> LOGGER.warn("Unrecognized geometry type: " + geometry.getGeometryType()); } } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ArrayLongLongMapMmap.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ArrayLongLongMapMmap.java index e208248b..17791e6e 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ArrayLongLongMapMmap.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ArrayLongLongMapMmap.java @@ -95,7 +95,7 @@ class ArrayLongLongMapMmap implements LongLongMap.ParallelWrites { int minChunks = 1; int maxChunks = (int) (MAX_BYTES_TO_USE / chunkSize); int targetChunks = (int) (ProcessInfo.getMaxMemoryBytes() * 0.5d / chunkSize); - return Math.min(maxChunks, Math.max(minChunks, targetChunks)); + return Math.clamp(targetChunks, minChunks, maxChunks); } public void init() { diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ExternalMergeSort.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ExternalMergeSort.java index c63269e7..11a63af5 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ExternalMergeSort.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/ExternalMergeSort.java @@ -185,7 +185,7 @@ class ExternalMergeSort implements FeatureSort { .sinkToConsumer("worker", workers, group -> { try { readSemaphore.acquire(); - var chunk = group.get(0); + var chunk = group.getFirst(); var others = group.stream().skip(1).toList(); var toSort = time(reading, () -> { // merge all chunks into first one, and remove the others diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/FeatureGroup.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/FeatureGroup.java index d990f62b..058b3a42 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/FeatureGroup.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/collection/FeatureGroup.java @@ -217,24 +217,18 @@ public final class FeatureGroup implements Iterable, var attrs = vectorTileFeature.attrs(); packer.packMapHeader((int) attrs.values().stream().filter(Objects::nonNull).count()); for (Map.Entry entry : attrs.entrySet()) { - if (entry.getValue() != null) { + Object value = entry.getValue(); + if (value != null) { packer.packInt(commonValueStrings.encode(entry.getKey())); - Object value = entry.getValue(); - if (value instanceof String string) { - packer.packValue(ValueFactory.newString(string)); - } else if (value instanceof Integer integer) { - packer.packValue(ValueFactory.newInteger(integer.longValue())); - } else if (value instanceof Long longValue) { - packer.packValue(ValueFactory.newInteger(longValue)); - } else if (value instanceof Float floatValue) { - packer.packValue(ValueFactory.newFloat(floatValue)); - } else if (value instanceof Double doubleValue) { - packer.packValue(ValueFactory.newFloat(doubleValue)); - } else if (value instanceof Boolean booleanValue) { - packer.packValue(ValueFactory.newBoolean(booleanValue)); - } else { - packer.packValue(ValueFactory.newString(value.toString())); - } + packer.packValue(switch (value) { + case String string -> ValueFactory.newString(string); + case Integer integer -> ValueFactory.newInteger(integer.longValue()); + case Long longValue -> ValueFactory.newInteger(longValue); + case Float floatValue -> ValueFactory.newFloat(floatValue); + case Double doubleValue -> ValueFactory.newFloat(doubleValue); + case Boolean booleanValue -> ValueFactory.newBoolean(booleanValue); + case Object other -> ValueFactory.newString(other.toString()); + }); } } // Use the same binary format for encoding geometries in output vector tiles. Benchmarking showed @@ -423,7 +417,7 @@ public final class FeatureGroup implements Iterable, GeometryType geomType = decodeGeomType(geomTypeAndScale); int scale = decodeScale(geomTypeAndScale); int mapSize = unpacker.unpackMapHeader(); - Map attrs = new HashMap<>(mapSize); + Map attrs = HashMap.newHashMap(mapSize); for (int i = 0; i < mapSize; i++) { String key = commonValueStrings.decode(unpacker.unpackInt()); Value v = unpacker.unpackValue(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/DataType.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/DataType.java index ab93fdef..de3fdac9 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/DataType.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/DataType.java @@ -34,19 +34,14 @@ public enum DataType implements BiFunction { /** Returns the data type associated with {@code value}, or {@link #GET_TAG} as a fallback. */ public static DataType typeOf(Object value) { - if (value instanceof String) { - return GET_STRING; - } else if (value instanceof Integer) { - return GET_INT; - } else if (value instanceof Long) { - return GET_LONG; - } else if (value instanceof Double) { - return GET_DOUBLE; - } else if (value instanceof Boolean) { - return GET_BOOLEAN; - } else { - return GET_TAG; - } + return switch (value) { + case String ignored -> GET_STRING; + case Integer ignored -> GET_INT; + case Long ignored -> GET_LONG; + case Double ignored -> GET_DOUBLE; + case Boolean ignored -> GET_BOOLEAN; + default -> GET_TAG; + }; } /** Returns the data type associated with {@code id}, or {@link #GET_TAG} as a fallback. */ diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/Expression.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/Expression.java index 6fbe641b..22fa9eb0 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/Expression.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/Expression.java @@ -23,12 +23,9 @@ import org.slf4j.LoggerFactory; *

* Calling {@code toString()} on any expression will generate code that can be used to recreate an identical copy of the * original expression, assuming that the generated code includes: - * - *

- * {@code
+ * {@snippet :
  * import static com.onthegomap.planetiler.expression.Expression.*;
  * }
- * 
*/ // TODO rename to BooleanExpression public interface Expression extends Simplifiable { @@ -141,14 +138,13 @@ public interface Expression extends Simplifiable { default Expression replace(Predicate replace, Expression b) { if (replace.test(this)) { return b; - } else if (this instanceof Not not) { - return new Not(not.child.replace(replace, b)); - } else if (this instanceof Or or) { - return new Or(or.children.stream().map(child -> child.replace(replace, b)).toList()); - } else if (this instanceof And and) { - return new And(and.children.stream().map(child -> child.replace(replace, b)).toList()); } else { - return this; + return switch (this) { + case Not(var child) -> new Not(child.replace(replace, b)); + case Or(var children) -> new Or(children.stream().map(child -> child.replace(replace, b)).toList()); + case And(var children) -> new And(children.stream().map(child -> child.replace(replace, b)).toList()); + default -> this; + }; } } @@ -156,14 +152,13 @@ public interface Expression extends Simplifiable { default boolean contains(Predicate filter) { if (filter.test(this)) { return true; - } else if (this instanceof Not not) { - return not.child.contains(filter); - } else if (this instanceof Or or) { - return or.children.stream().anyMatch(child -> child.contains(filter)); - } else if (this instanceof And and) { - return and.children.stream().anyMatch(child -> child.contains(filter)); } else { - return false; + return switch (this) { + case Not(var child) -> child.contains(filter); + case Or(var children) -> children.stream().anyMatch(child -> child.contains(filter)); + case And(var children) -> children.stream().anyMatch(child -> child.contains(filter)); + default -> false; + }; } } @@ -234,7 +229,7 @@ public interface Expression extends Simplifiable { return TRUE; } if (children.size() == 1) { - return children.get(0).simplifyOnce(); + return children.getFirst().simplifyOnce(); } if (children.contains(FALSE)) { return FALSE; @@ -288,7 +283,7 @@ public interface Expression extends Simplifiable { return FALSE; } if (children.size() == 1) { - return children.get(0).simplifyOnce(); + return children.getFirst().simplifyOnce(); } if (children.contains(TRUE)) { return TRUE; diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/MultiExpression.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/MultiExpression.java index 97bc6c77..484c5693 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/MultiExpression.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/expression/MultiExpression.java @@ -50,19 +50,15 @@ public record MultiExpression (List> expressions) implements Simplif * when a particular key is present on the input. */ private static boolean mustAlwaysEvaluate(Expression expression) { - if (expression instanceof Expression.Or or) { - return or.children().stream().anyMatch(MultiExpression::mustAlwaysEvaluate); - } else if (expression instanceof Expression.And and) { - return and.children().stream().allMatch(MultiExpression::mustAlwaysEvaluate); - } else if (expression instanceof Expression.Not not) { - return !mustAlwaysEvaluate(not.child()); - } else if (expression instanceof Expression.MatchAny any && any.matchWhenMissing()) { - return true; - } else { - return !(expression instanceof Expression.MatchAny) && - !(expression instanceof Expression.MatchField) && - !FALSE.equals(expression); - } + return switch (expression) { + case Expression.Or(var children) -> children.stream().anyMatch(MultiExpression::mustAlwaysEvaluate); + case Expression.And(var children) -> children.stream().allMatch(MultiExpression::mustAlwaysEvaluate); + case Expression.Not(var child) -> !mustAlwaysEvaluate(child); + case Expression.MatchAny any when any.matchWhenMissing() -> true; + case null, default -> !(expression instanceof Expression.MatchAny) && + !(expression instanceof Expression.MatchField) && + !FALSE.equals(expression); + }; } /** Calls {@code acceptKey} for every tag that could possibly cause {@code exp} to match an input element. */ @@ -176,7 +172,7 @@ public record MultiExpression (List> expressions) implements Simplif */ default O getOrElse(WithTags input, O defaultValue) { List matches = getMatches(input); - return matches.isEmpty() ? defaultValue : matches.get(0); + return matches.isEmpty() ? defaultValue : matches.getFirst(); } /** @@ -184,7 +180,7 @@ public record MultiExpression (List> expressions) implements Simplif */ default O getOrElse(Map tags, O defaultValue) { List matches = getMatches(WithTags.from(tags)); - return matches.isEmpty() ? defaultValue : matches.get(0); + return matches.isEmpty() ? defaultValue : matches.getFirst(); } /** Returns true if any expression matches that tags from an input element. */ diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java index c71dbd6e..0809f4de 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java @@ -281,15 +281,15 @@ public class GeoUtils { } public static Geometry combineLineStrings(List lineStrings) { - return lineStrings.size() == 1 ? lineStrings.get(0) : createMultiLineString(lineStrings); + return lineStrings.size() == 1 ? lineStrings.getFirst() : createMultiLineString(lineStrings); } public static Geometry combinePolygons(List polys) { - return polys.size() == 1 ? polys.get(0) : createMultiPolygon(polys); + return polys.size() == 1 ? polys.getFirst() : createMultiPolygon(polys); } public static Geometry combinePoints(List points) { - return points.size() == 1 ? points.get(0) : createMultiPoint(points); + return points.size() == 1 ? points.getFirst() : createMultiPoint(points); } /** @@ -383,29 +383,29 @@ public class GeoUtils { if (lineStrings.isEmpty()) { throw new GeometryException("polygon_to_linestring_empty", "No line strings"); } else if (lineStrings.size() == 1) { - return lineStrings.get(0); + return lineStrings.getFirst(); } else { return createMultiLineString(lineStrings); } } private static void getLineStrings(Geometry input, List output) throws GeometryException { - if (input instanceof LinearRing linearRing) { - output.add(JTS_FACTORY.createLineString(linearRing.getCoordinateSequence())); - } else if (input instanceof LineString lineString) { - output.add(lineString); - } else if (input instanceof Polygon polygon) { - getLineStrings(polygon.getExteriorRing(), output); - for (int i = 0; i < polygon.getNumInteriorRing(); i++) { - getLineStrings(polygon.getInteriorRingN(i), output); + switch (input) { + case LinearRing linearRing -> output.add(JTS_FACTORY.createLineString(linearRing.getCoordinateSequence())); + case LineString lineString -> output.add(lineString); + case Polygon polygon -> { + getLineStrings(polygon.getExteriorRing(), output); + for (int i = 0; i < polygon.getNumInteriorRing(); i++) { + getLineStrings(polygon.getInteriorRingN(i), output); + } } - } else if (input instanceof GeometryCollection gc) { - for (int i = 0; i < gc.getNumGeometries(); i++) { - getLineStrings(gc.getGeometryN(i), output); + case GeometryCollection gc -> { + for (int i = 0; i < gc.getNumGeometries(); i++) { + getLineStrings(gc.getGeometryN(i), output); + } } - } else { - throw new GeometryException("get_line_strings_bad_type", - "unrecognized geometry type: " + input.getGeometryType()); + case null, default -> throw new GeometryException("get_line_strings_bad_type", + "unrecognized geometry type: " + (input == null ? "null" : input.getGeometryType())); } } @@ -416,7 +416,7 @@ public class GeoUtils { /** Returns a point approximately {@code ratio} of the way from start to end and {@code offset} units to the right. */ public static Point pointAlongOffset(LineString lineString, double ratio, double offset) { int numPoints = lineString.getNumPoints(); - int middle = Math.max(0, Math.min(numPoints - 2, (int) (numPoints * ratio))); + int middle = Math.clamp((int) (numPoints * ratio), 0, numPoints - 2); Coordinate a = lineString.getCoordinateN(middle); Coordinate b = lineString.getCoordinateN(middle + 1); LineSegment segment = new LineSegment(a, b); @@ -530,7 +530,7 @@ public class GeoUtils { innerGeometries.add(geom); } } - return innerGeometries.size() == 1 ? innerGeometries.get(0) : + return innerGeometries.size() == 1 ? innerGeometries.getFirst() : JTS_FACTORY.createGeometryCollection(innerGeometries.toArray(Geometry[]::new)); } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java index 6a2bfd82..0d06d903 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java @@ -19,7 +19,7 @@ import org.locationtech.jts.index.strtree.STRtree; @ThreadSafe public class PolygonIndex { - private record GeomWithData (Polygon poly, T data) {} + private record GeomWithData(Polygon poly, T data) {} private final STRtree index = new STRtree(); @@ -45,7 +45,7 @@ public class PolygonIndex { /** Returns the data associated with the first polygon containing {@code point}. */ public T getOnlyContaining(Point point) { List result = getContaining(point); - return result.isEmpty() ? null : result.get(0); + return result.isEmpty() ? null : result.getFirst(); } /** Returns the data associated with all polygons containing {@code point}. */ @@ -77,7 +77,7 @@ public class PolygonIndex { List items = index.query(point.getEnvelopeInternal()); // optimization: if there's only one then skip checking contains/distance if (items.size() == 1) { - if (items.get(0)instanceof GeomWithData value) { + if (items.getFirst() instanceof GeomWithData value) { @SuppressWarnings("unchecked") T t = (T) value.data; return List.of(t); } @@ -108,7 +108,7 @@ public class PolygonIndex { /** Returns the data associated with a polygon that contains {@code point} or nearest polygon if none are found. */ public T get(Point point) { List nearests = getContainingOrNearest(point); - return nearests.isEmpty() ? null : nearests.get(0); + return nearests.isEmpty() ? null : nearests.getFirst(); } /** Indexes {@code item} for all polygons contained in {@code geom}. */ diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/TileExtents.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/TileExtents.java index f6313cf2..911be3c7 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/TileExtents.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/TileExtents.java @@ -21,11 +21,11 @@ public class TileExtents implements Predicate { } private static int quantizeDown(double value, int levels) { - return Math.max(0, Math.min(levels, (int) Math.floor(value * levels))); + return Math.clamp((int) Math.floor(value * levels), 0, levels); } private static int quantizeUp(double value, int levels) { - return Math.max(0, Math.min(levels, (int) Math.ceil(value * levels))); + return Math.clamp((int) Math.ceil(value * levels), 0, levels); } /** Returns a filter to tiles that intersect {@code worldBounds} (specified in world web mercator coordinates). */ diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/GeoPackageReader.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/GeoPackageReader.java index fff8b20c..91882acb 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/GeoPackageReader.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/GeoPackageReader.java @@ -153,7 +153,7 @@ public class GeoPackageReader extends SimpleReader { Geometry latLonGeom = (transform.isIdentity()) ? featureGeom : JTS.transform(featureGeom, transform); FeatureColumns columns = feature.getColumns(); - SimpleFeature geom = SimpleFeature.create(latLonGeom, new HashMap<>(columns.columnCount()), + SimpleFeature geom = SimpleFeature.create(latLonGeom, HashMap.newHashMap(columns.columnCount()), sourceName, featureName, ++id); for (int i = 0; i < columns.columnCount(); ++i) { diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/NaturalEarthReader.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/NaturalEarthReader.java index c8fe0a93..14ae862a 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/NaturalEarthReader.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/NaturalEarthReader.java @@ -177,7 +177,7 @@ public class NaturalEarthReader extends SimpleReader { // create the feature and pass to next stage Geometry latLonGeometry = GeoUtils.WKB_READER.read(geometry); - SimpleFeature readerGeometry = SimpleFeature.create(latLonGeometry, new HashMap<>(column.length - 1), + SimpleFeature readerGeometry = SimpleFeature.create(latLonGeometry, HashMap.newHashMap(column.length - 1), sourceName, table, ++id); for (int c = 0; c < column.length; c++) { if (c != geometryColumn) { diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/ShapefileReader.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/ShapefileReader.java index d48f6f44..45323561 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/ShapefileReader.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/ShapefileReader.java @@ -137,7 +137,7 @@ public class ShapefileReader extends SimpleReader { latLonGeometry = JTS.transform(source, transformToLatLon); } if (latLonGeometry != null) { - SimpleFeature geom = SimpleFeature.create(latLonGeometry, new HashMap<>(attributeNames.length), + SimpleFeature geom = SimpleFeature.create(latLonGeometry, HashMap.newHashMap(attributeNames.length), sourceName, layer, ++id); for (int i = 1; i < attributeNames.length; i++) { geom.setTag(attributeNames[i], feature.getAttribute(i)); 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 63c87a34..4a474a97 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 @@ -128,7 +128,7 @@ public abstract class SourceFeature implements WithTags, WithGeometryType { private Geometry computeCentroidIfConvex() throws GeometryException { if (!canBePolygon()) { return centroid(); - } else if (polygon()instanceof Polygon poly && + } else if (polygon() instanceof Polygon poly && poly.getNumInteriorRing() == 0 && GeoUtils.isConvex(poly.getExteriorRing())) { return centroid(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmMultipolygon.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmMultipolygon.java index 4e18f594..31ca60a3 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmMultipolygon.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmMultipolygon.java @@ -232,7 +232,7 @@ public class OsmMultipolygon { if (numPolygons == 0) { return shells; } - shells.add(polygons.get(0)); + shells.add(polygons.getFirst()); if (numPolygons == 1) { return shells; } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/PbfDecoder.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/PbfDecoder.java index dd4b6976..dc6c9255 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/PbfDecoder.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/PbfDecoder.java @@ -133,7 +133,7 @@ public class PbfDecoder implements Iterable { private Map buildTags(int num, IntUnaryOperator key, IntUnaryOperator value) { if (num > 0) { - Map tags = new HashMap<>(num); + Map tags = HashMap.newHashMap(num); for (int i = 0; i < num; i++) { String k = fieldDecoder.decodeString(key.applyAsInt(i)); String v = fieldDecoder.decodeString(value.applyAsInt(i)); @@ -366,7 +366,7 @@ public class PbfDecoder implements Iterable { if (tags == null) { // divide by 2 as key&value, multiply by 2 because of the better approximation - tags = new HashMap<>(Math.max(3, 2 * (nodes.getKeysValsCount() / 2) / nodes.getKeysValsCount())); + tags = HashMap.newHashMap(Math.max(3, 2 * (nodes.getKeysValsCount() / 2) / nodes.getKeysValsCount())); } tags.put(fieldDecoder.decodeString(keyIndex), fieldDecoder.decodeString(valueIndex)); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/render/GeometryCoordinateSequences.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/render/GeometryCoordinateSequences.java index 26112918..60b117f8 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/render/GeometryCoordinateSequences.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/render/GeometryCoordinateSequences.java @@ -122,7 +122,7 @@ class GeometryCoordinateSequences { static Geometry reassemblePolygons(List> groups) throws GeometryException { int numGeoms = groups.size(); if (numGeoms == 1) { - return reassemblePolygon(groups.get(0)); + return reassemblePolygon(groups.getFirst()); } else { Polygon[] polygons = new Polygon[numGeoms]; for (int i = 0; i < numGeoms; i++) { @@ -135,7 +135,7 @@ class GeometryCoordinateSequences { /** Returns a {@link Polygon} built from all outer/inner rings in {@code group}, reversing all inner rings. */ private static Polygon reassemblePolygon(List group) throws GeometryException { try { - LinearRing first = GeoUtils.JTS_FACTORY.createLinearRing(group.get(0)); + LinearRing first = GeoUtils.JTS_FACTORY.createLinearRing(group.getFirst()); LinearRing[] rest = new LinearRing[group.size() - 1]; for (int j = 1; j < group.size(); j++) { CoordinateSequence seq = group.get(j); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/render/TiledGeometry.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/render/TiledGeometry.java index d5b9469a..03ffbfc9 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/render/TiledGeometry.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/render/TiledGeometry.java @@ -258,7 +258,7 @@ public class TiledGeometry { TileCoord tile = TileCoord.ofXYZ(wrappedX, y, z); double tileY = worldY - y; tileContents.computeIfAbsent(tile, t -> List.of(new ArrayList<>())) - .get(0) + .getFirst() .add(GeoUtils.coordinateSequence(tileX * 256, tileY * 256)); } } @@ -384,7 +384,7 @@ public class TiledGeometry { for (var entry : inProgressShapes.entrySet()) { TileCoord tileID = entry.getKey(); List inSeqs = entry.getValue(); - if (area && inSeqs.get(0).size() < 4) { + if (area && inSeqs.getFirst().size() < 4) { // not enough points in outer polygon, ignore continue; } @@ -573,20 +573,20 @@ public class TiledGeometry { } /* A tile is inside a filled region when there is an odd number of vertical edges to the left and right - + for example a simple shape: --------- out | in | out (0/2) | (1/1) | (2/0) --------- - + or a more complex shape --------- --------- out | in | out | in | (0/4) | (1/3) | (2/2) | (3/1) | | --------- | ------------------------- - + So we keep track of this number by xor'ing the left and right fills repeatedly, then and'ing them together at the end. */ diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessInfo.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessInfo.java index 4dda00a3..29736ef4 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessInfo.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessInfo.java @@ -38,7 +38,7 @@ public class ProcessInfo { for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) { if (garbageCollectorMXBean instanceof NotificationEmitter emitter) { emitter.addNotificationListener((notification, handback) -> { - if (notification.getUserData()instanceof CompositeData compositeData) { + if (notification.getUserData() instanceof CompositeData compositeData) { var info = GarbageCollectionNotificationInfo.from(compositeData); GcInfo gcInfo = info.getGcInfo(); postGcMemoryUsage.set(gcInfo.getMemoryUsageAfterGc().entrySet().stream() @@ -142,7 +142,7 @@ public class ProcessInfo { * Returns the total amount of memory available on the system if available. */ public static OptionalLong getSystemMemoryBytes() { - if (ManagementFactory.getOperatingSystemMXBean()instanceof com.sun.management.OperatingSystemMXBean osBean) { + if (ManagementFactory.getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean osBean) { return OptionalLong.of(osBean.getTotalMemorySize()); } else { return OptionalLong.empty(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessTime.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessTime.java index 16645bbf..7e8cb0b6 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessTime.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProcessTime.java @@ -10,15 +10,12 @@ import javax.annotation.concurrent.Immutable; * A utility for measuring the wall and CPU time that this JVM consumes between snapshots. *

* For example: - * - *

- * {@code
+ * {@snippet :
  * var start = ProcessTime.now();
  * // do expensive work...
- * var end - ProcessTime.now();
+ * var end = ProcessTime.now();
  * LOGGER.log("Expensive work took " + end.minus(start));
  * }
- * 
*/ @Immutable public record ProcessTime(Duration wall, Optional cpu, Duration gc) { diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProgressLoggers.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProgressLoggers.java index 3d7535ce..44dce911 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProgressLoggers.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/stats/ProgressLoggers.java @@ -275,7 +275,7 @@ public class ProgressLoggers { /** Adds the CPU utilization of every thread starting with {@code prefix} since the last log to output. */ public ProgressLoggers addThreadPoolStats(String name, String prefix) { - boolean first = loggers.isEmpty() || !(loggers.get(loggers.size() - 1) instanceof WorkerPipelineLogger); + boolean first = loggers.isEmpty() || !(loggers.getLast() instanceof WorkerPipelineLogger); try { Map lastThreads = ProcessInfo.getThreadStats(); AtomicLong lastTime = new AtomicLong(System.nanoTime()); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/AwsOsm.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/AwsOsm.java index 823a2dc3..cdd3a818 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/AwsOsm.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/AwsOsm.java @@ -95,7 +95,7 @@ public class AwsOsm { } else if (results.size() > 1) { throw new IllegalArgumentException("Found multiple AWS osm download URLs for " + searchQuery + ": " + results); } - return results.get(0); + return results.getFirst(); } } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Downloader.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Downloader.java index fa9c7778..5b5dde17 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Downloader.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Downloader.java @@ -43,15 +43,12 @@ import org.slf4j.LoggerFactory; * changes. *

* For example: - * - *

- * {@code
+ * {@snippet :
  * Downloader.create(PlanetilerConfig.defaults())
  *   .add("natural_earth", "http://url/of/natural_earth.zip", Path.of("natural_earth.zip"))
  *   .add("osm", "http://url/of/file.osm.pbf", Path.of("file.osm.pbf"))
  *   .run();
  * }
- * 
*

* As a shortcut to find the URL of a file to download from the Geofabrik * download site, you can use "geofabrik:extract name" (i.e. "geofabrik:monaco" or "geofabrik:australia") to look up @@ -247,7 +244,7 @@ public class Downloader { CompletableFuture httpHead(String url) { return client - .sendAsync(newHttpRequest(url).method("HEAD", HttpRequest.BodyPublishers.noBody()).build(), + .sendAsync(newHttpRequest(url).HEAD().build(), responseInfo -> { int status = responseInfo.statusCode(); Optional location = Optional.empty(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Geofabrik.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Geofabrik.java index fe7bf2c0..07e514ad 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Geofabrik.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Geofabrik.java @@ -106,7 +106,7 @@ public class Geofabrik { "Multiple " + name + " for '" + searchQuery + "': " + values.stream().map(d -> d.id).collect( Collectors.joining(", "))); } else if (values.size() == 1) { - return values.get(0).urls.get("pbf"); + return values.getFirst().urls.get("pbf"); } else { return null; } diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/SortKey.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/SortKey.java index 3cb9a843..fb659485 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/SortKey.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/SortKey.java @@ -13,19 +13,15 @@ import com.onthegomap.planetiler.collection.FeatureGroup; * To sort by a field descending, specify its range from high to low. *

* For example this SQL ordering: - * - *

- * {@code
+ *
+ * {@snippet lang = "sql" :
  * ORDER BY rank ASC,
  * population DESC,
  * length(name) ASC
  * }
- * 
*

* would become: - * - *

- * {@code
+ * {@snippet :
  * feature.setSortKey(
  *   SortKey
  *     .orderByInt(rank, MIN_RANK, MAX_RANK)
@@ -125,7 +121,7 @@ public class SortKey {
     }
     int levels = end + 1 - start;
     if (value < start || value > end) {
-      value = Math.max(start, Math.min(end, value));
+      value = Math.clamp(value, start, end);
     }
     return accumulate(value, start, levels);
   }
@@ -141,7 +137,7 @@ public class SortKey {
       return thenByDouble(start - value, end, start, levels);
     }
     if (value < start || value > end) {
-      value = Math.max(start, Math.min(end, value));
+      value = Math.clamp(value, start, end);
     }
 
     int intVal = doubleRangeToInt(value, start, end, levels);
@@ -160,7 +156,7 @@ public class SortKey {
     }
     assert start > 0 : "log thresholds must be > 0 got [" + start + ", " + end + "]";
     if (value < start || value > end) {
-      value = Math.max(start, Math.min(end, value));
+      value = Math.clamp(value, start, end);
     }
 
     int intVal = doubleRangeToInt(Math.log(value), Math.log(start), Math.log(end), levels);
diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Translations.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Translations.java
index c06a0fce..7e3c60b0 100644
--- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Translations.java
+++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Translations.java
@@ -128,7 +128,7 @@ public class Translations {
       Map result = new HashMap<>();
       for (var entry : tags.entrySet()) {
         String key = entry.getKey();
-        if (key.startsWith("name:") && entry.getValue()instanceof String stringVal) {
+        if (key.startsWith("name:") && entry.getValue() instanceof String stringVal) {
           result.put(key, stringVal);
         }
       }
diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/worker/WorkerPipeline.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/worker/WorkerPipeline.java
index 9bdeede6..22abcacd 100644
--- a/planetiler-core/src/main/java/com/onthegomap/planetiler/worker/WorkerPipeline.java
+++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/worker/WorkerPipeline.java
@@ -17,24 +17,21 @@ import java.util.function.Consumer;
  * A mini-framework for chaining sequential steps that run in dedicated threads with a queue between each.
  * 

* For example: - * - *

- * {@code
+ * {@snippet :
  * WorkerPipeline.start("name", stats)
  *   .readFrom("reader", List.of(1, 2, 3))
  *   .addBuffer("reader_queue", 10)
- *   .addWorker("process", 2, (i, next) -> next.accept(doExpensiveWork(i))
+ *   .addWorker("process", 2, (i, next) -> next.accept(doExpensiveWork(i)))
  *   .addBuffer("writer_queue", 10)
  *   .sinkToConsumer("writer", 1, result -> writeToDisk(result))
  *   .await();
  * }
- * 
*

* NOTE: to do any forking/joining, you must construct and wire-up queues and each sequence of steps manually. * * @param input type of this pipeline */ -public record WorkerPipeline ( +public record WorkerPipeline( String name, WorkerPipeline previous, WorkQueue inputQueue, @@ -219,7 +216,7 @@ public record WorkerPipeline ( * * @param type of elements that the next step must process */ - public record Builder ( + public record Builder( String prefix, String name, // keep track of previous elements so that build can wire-up the computation graph diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java index d1964b29..8cd3303c 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java @@ -827,7 +827,7 @@ class PlanetilerTests { var tileContents = results.tiles.get(TileCoord.ofXYZ(0, 0, 0)); assertEquals(1, tileContents.size()); - Geometry geom = tileContents.get(0).geometry().geom(); + Geometry geom = tileContents.getFirst().geometry().geom(); assertTrue(geom instanceof MultiPolygon, geom.toString()); MultiPolygon multiPolygon = (MultiPolygon) geom; assertSameNormalizedFeature(newPolygon( @@ -1884,7 +1884,7 @@ class PlanetilerTests { var point = newPoint(tileX, tileY); assertEquals(1, problematicTile.size()); - var geomCompare = problematicTile.get(0).geometry(); + var geomCompare = problematicTile.getFirst().geometry(); geomCompare.validate(); var geom = geomCompare.geom(); diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/VectorTileTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/VectorTileTest.java index 84a9f8b4..9f065ae4 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/VectorTileTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/VectorTileTest.java @@ -160,7 +160,7 @@ class VectorTileTest { List decoded = VectorTile.decode(encoded); assertEquals(1, decoded.size()); - Map decodedAttributes = decoded.get(0).attrs(); + Map decodedAttributes = decoded.getFirst().attrs(); assertEquals("value1", decodedAttributes.get("key1")); assertEquals(123L, decodedAttributes.get("key2")); assertEquals(234.1f, decodedAttributes.get("key3")); @@ -220,7 +220,7 @@ class VectorTileTest { var features = VectorTile.decode(encoded); assertEquals(1, features.size()); - MultiPolygon mp2 = (MultiPolygon) decodeSilently(features.get(0).geometry()); + MultiPolygon mp2 = (MultiPolygon) decodeSilently(features.getFirst().geometry()); assertEquals(mp.getNumGeometries(), mp2.getNumGeometries()); } diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/reader/ShapefileReaderTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/reader/ShapefileReaderTest.java index 1cb2d209..b5340247 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/reader/ShapefileReaderTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/reader/ShapefileReaderTest.java @@ -94,9 +94,9 @@ class ShapefileReaderTest { assertEquals(1, reader.getFeatureCount()); List features = new ArrayList<>(); reader.readFeatures(features::add); - assertEquals(10.5113, features.get(0).latLonGeometry().getCentroid().getX(), 1e-4); - assertEquals(0, features.get(0).latLonGeometry().getCentroid().getY(), 1e-4); - assertEquals(3, features.get(0).getTag("value")); + assertEquals(10.5113, features.getFirst().latLonGeometry().getCentroid().getX(), 1e-4); + assertEquals(0, features.getFirst().latLonGeometry().getCentroid().getY(), 1e-4); + assertEquals(3, features.getFirst().getTag("value")); } } diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/render/FeatureRendererTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/render/FeatureRendererTest.java index fab95501..549f7569 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/render/FeatureRendererTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/render/FeatureRendererTest.java @@ -47,7 +47,7 @@ class FeatureRendererTest { private FeatureCollector collector(Geometry worldGeom) { var latLonGeom = GeoUtils.worldToLatLonCoords(worldGeom); return new FeatureCollector.Factory(config, stats) - .get(SimpleFeature.create(latLonGeom, new HashMap<>(0), null, null, + .get(SimpleFeature.create(latLonGeom, HashMap.newHashMap(0), null, null, 1)); } diff --git a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java index 57ca78c9..1ad9a409 100644 --- a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java +++ b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java @@ -410,7 +410,7 @@ public class Contexts { } public String matchKey() { - return matchKeys().isEmpty() ? null : matchKeys().get(0); + return matchKeys().isEmpty() ? null : matchKeys().getFirst(); } public Object matchValue() { diff --git a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/expression/ConfigExpression.java b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/expression/ConfigExpression.java index 58bcf473..a6be2619 100644 --- a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/expression/ConfigExpression.java +++ b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/expression/ConfigExpression.java @@ -164,7 +164,7 @@ public interface ConfigExpression public ConfigExpression simplifyOnce() { return switch (children.size()) { case 0 -> constOf(null); - case 1 -> children.get(0); + case 1 -> children.getFirst(); default -> { var result = children.stream() .flatMap( diff --git a/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/OsmQaTiles.java b/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/OsmQaTiles.java index 4b149034..72fe948e 100644 --- a/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/OsmQaTiles.java +++ b/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/OsmQaTiles.java @@ -76,10 +76,12 @@ public class OsmQaTiles implements Profile { } feature .setAttr("@id", sourceFeature.id()) - .setAttr("@type", element instanceof OsmElement.Node ? "node" : - element instanceof OsmElement.Way ? "way" : - element instanceof OsmElement.Relation ? "relation" : null - ); + .setAttr("@type", switch (element) { + case OsmElement.Node ignored -> "node"; + case OsmElement.Way ignored -> "way"; + case OsmElement.Relation ignored -> "relation"; + default -> null; + }); var info = element.info(); if (info != null) { feature