Skip to content

[BUG] Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high #1606

Description

@wipfli

Describe the bug
When I run a simple Planetiler profile over a polygon in GPKG format I get this error message:

java.lang.IllegalArgumentException: Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high.

To Reproduce
Steps to reproduce the behavior:

  1. Download data from nlcaribischb.gpkg.txt
  2. mv nlcaribischb.gpkg.txt polygon-store/nlcaribischb.gpkg
  3. Coverage.java:
import java.nio.file.Path;
import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;
import java.util.List;

import com.onthegomap.planetiler.FeatureCollector;
import com.onthegomap.planetiler.Planetiler;
import com.onthegomap.planetiler.Profile;
import com.onthegomap.planetiler.config.Arguments;
import com.onthegomap.planetiler.reader.SourceFeature;
import com.onthegomap.planetiler.FeatureMerge;
import com.onthegomap.planetiler.VectorTile;
import com.onthegomap.planetiler.geo.GeometryException;


public class Coverage implements Profile {

  public static void main(String[] args) {
    var arguments = Arguments.fromArgs(args).withDefault("download", false);
    Path dir = Paths.get("polygon-store");
    var planetiler = Planetiler.create(arguments)
      .overwriteOutput(Path.of("meta-store", "coverage.pmtiles"))
      .setProfile(new Coverage());

    try (Stream<Path> stream = Files.list(dir)) {
      for (Path path : stream.toList()) {
        if (path.toString().endsWith(".gpkg")) {
          String filename = path.getFileName().toString();
          String nameWithoutSuffix = filename.substring(0, filename.length() - 5);
          planetiler.addGeoPackageSource(nameWithoutSuffix, path, null);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }

    planetiler.run();
  }

  @Override
  public void processFeature(SourceFeature sourceFeature, FeatureCollector features) {
    if (sourceFeature.canBePolygon()) {
      features.polygon("coverage")
        .setAttr("source", sourceFeature.getSource())
        .setPixelTolerance(6. * 0.0625);
    }
  }  
}
  1. Run command java -cp planetiler.jar Coverage.java
  2. See error
0:00:00 INF - argument: stats=use in-memory stats
0:00:00 DEB - argument: madvise=true (default value for whether to use linux madvise(random) to improve memory-mapped read performance for temporary storage)
0:00:00 DEB - argument: storage=mmap (default storage type for temporary data, one of [ram, mmap, direct])
0:00:00 DEB - argument: threads=32 (num threads)
0:00:00 DEB - argument: write_threads=1 (number of threads to use when writing temp features)
0:00:00 DEB - argument: process_threads=31 (number of threads to use when processing input features)
0:00:00 DEB - argument: bounds=null (bounds)
0:00:00 DEB - argument: polygon=null (a .poly file that limits output to tiles intersecting the shape)
0:00:00 DEB - argument: minzoom=0 (minimum zoom level)
0:00:00 DEB - argument: maxzoom=14 (maximum zoom level up to 15)
0:00:00 DEB - argument: render_maxzoom=14 (maximum rendering zoom level up to 15)
0:00:00 DEB - argument: tmpdir=data/tmp (temp directory)
0:00:00 DEB - argument: extra_name_tags= (Extra name tags to copy from OSM to output)
0:00:00 DEB - argument: feature_read_threads=2 (number of threads to use when reading features at tile write time)
0:00:00 DEB - argument: tile_write_threads=1 (number of threads used to write tiles - only supported by [files, csv, tsv, proto, pbf, json])
0:00:00 DEB - argument: loginterval=10 seconds (time between logs)
0:00:00 DEB - argument: force=false (overwriting output file and ignore disk/RAM warnings)
0:00:00 DEB - argument: append=false (append to the output file - only supported by [files, csv, tsv, proto, pbf, json])
0:00:00 DEB - argument: compress_temp=false (compress temporary feature storage (uses more CPU, but less disk space))
0:00:00 DEB - argument: mmap_temp=true (use memory-mapped IO for temp feature files)
0:00:00 DEB - argument: sort_max_readers=6 (maximum number of concurrent read threads to use when sorting chunks)
0:00:00 DEB - argument: sort_max_writers=6 (maximum number of concurrent write threads to use when sorting chunks)
0:00:00 DEB - argument: nodemap_type=sparsearray (type of node location map, one of [noop, sortedtable, sparsearray, array])
0:00:00 DEB - argument: nodemap_storage=mmap (storage for node location map, one of [ram, mmap, direct])
0:00:00 DEB - argument: nodemap_madvise=true (use linux madvise(random) for node locations)
0:00:00 DEB - argument: multipolygon_geometry_storage=mmap (storage for multipolygon geometries, one of [ram, mmap, direct])
0:00:00 DEB - argument: multipolygon_geometry_madvise=true (use linux madvise(random) for temporary multipolygon geometry storage)
0:00:00 DEB - argument: http_user_agent=Planetiler downloader (https://github.com/onthegomap/planetiler) (User-Agent header to set when downloading files over HTTP)
0:00:00 DEB - argument: http_timeout=30 seconds (Timeout to use when downloading files over HTTP)
0:00:00 DEB - argument: http_retries=5 (Retries to use when downloading files over HTTP)
0:00:00 DEB - argument: http_retry_wait=5 seconds (How long to wait before retrying HTTP request)
0:00:00 DEB - argument: download_chunk_size_mb=100 (Size of file chunks to download in parallel in megabytes)
0:00:00 DEB - argument: download_threads=1 (Number of parallel threads to use when downloading each file)
0:00:00 DEB - argument: download_max_bandwidth= (Maximum bandwidth to consume when downloading files in units mb/s, mbps, kbps, etc.)
0:00:00 DEB - argument: min_feature_size_at_max_zoom=0.0625 (Default value for the minimum size in tile pixels of features to emit at the maximum zoom level to allow for overzooming)
0:00:00 DEB - argument: min_feature_size=1.0 (Default value for the minimum size in tile pixels of features to emit below the maximum zoom level)
0:00:00 DEB - argument: simplify_tolerance_at_max_zoom=0.0625 (Default value for the tile pixel tolerance to use when simplifying features at the maximum zoom level to allow for overzooming)
0:00:00 DEB - argument: simplify_tolerance=0.1 (Default value for the tile pixel tolerance to use when simplifying features below the maximum zoom level)
0:00:00 DEB - argument: osm_lazy_reads=true (Read OSM blocks from disk in worker threads)
0:00:00 DEB - argument: skip_filled_tiles=false (Skip writing tiles containing only polygon fills to the output)
0:00:00 DEB - argument: tile_warning_size_mb=1.0 (Maximum size in megabytes of a tile to emit a warning about)
0:00:00 DEB - argument: color=null (Color the terminal output)
0:00:00 DEB - argument: keep_unzipped=false (keep unzipped sources by default after reading)
0:00:00 DEB - argument: tile_compression=gzip (the tile compression, one of [gzip, none])
0:00:00 DEB - argument: output_layerstats=false (output a tsv.gz file for each tile/layer size)
0:00:00 DEB - argument: debug_url=https://onthegomap.github.io/planetiler-demo/#{z}/{lat}/{lon} (debug url to use for displaying tiles with {z} {lat} {lon} placeholders)
0:00:00 DEB - argument: tile_weights=data/tile_weights.tsv.gz (tsv.gz file with columns z,x,y,loads to generate weighted average tile size stat)
0:00:00 DEB - argument: max_point_buffer=Infinity (Additional global limit for the max tile pixels to include points outside tile bounds of all layers. Set to a lower value to reduce tile size for clients that handle label collisions across tiles (most web and native clients). NOTE: Do not reduce if you need to support raster tile rendering)
0:00:00 DEB - argument: log_jts_exceptions=false (Emit verbose details to debug JTS geometry errors)
0:00:00 DEB - argument: feature_source_id_multiplier=10 (Set vector tile feature IDs to (featureId * thisValue) + sourceId where sourceId is 1 for OSM nodes, 2 for ways, 3 for relations, and 0 for other sources. Set to false to disable.)
0:00:00 DEB - argument: only_download=false (download source data then exit)
0:00:00 DEB - argument: tests=null (run test cases in a yaml then quit)
0:00:00 DEB - argument: download=false (download sources)
0:00:00 DEB - argument: refresh_sources=false (download new version of source files if they have changed)
0:00:00 DEB - argument: download_osm_tile_weights=false (download OSM tile weights file)
0:00:00 DEB - argument: temp_nodes=data/tmp/node.db (temp node db location)
0:00:00 DEB - argument: temp_multipolygons=data/tmp/multipolygon.db (temp multipolygon db location)
0:00:00 DEB - argument: temp_features=data/tmp/feature.db (temp feature db location)
0:00:00 DEB - argument: osm_parse_node_bounds=false (parse bounds from OSM nodes instead of header)
0:00:00 DEB - argument: output=meta-store/coverage.pmtiles (output tile archive URI)
0:00:00 DEB - argument: nlcaribischb_path=polygon-store/nlcaribischb.gpkg (nlcaribischb geopackage path)
0:00:00 DEB - argument: refresh_nlcaribischb=false (Download new version of nlcaribischb if changed)
0:00:00 DEB - argument: free_nlcaribischb_after_read=false (delete nlcaribischb input file after reading to make space for output (reduces peak disk usage))
0:00:00 DEB - argument: nlcaribischb_keep_unzipped=false (keep unzipped nlcaribischb after reading)
0:00:00 DEB - argument: version=false (show version then exit)
0:00:00 INF - Planetiler build git hash: e6e13811ed69a61c82f3599d1a72d28fa98f6801
0:00:00 INF - Planetiler build version: 0.9.3
0:00:00 INF - Planetiler build timestamp: 2025-10-28T09:50:32.363Z
0:00:00 DEB - argument: help=false (show arguments then exit)
0:00:00 DEB - argument: layer_stats=/home/oliver/mapterhorn/pipelines/meta-store/coverage.pmtiles.layerstats.tsv.gz (layer stats output path)
0:00:00 INF - Building Coverage profile into file:///home/oliver/mapterhorn/pipelines/meta-store/coverage.pmtiles in these phases:
0:00:00 INF -   nlcaribischb: Process features in polygon-store/nlcaribischb.gpkg
0:00:00 INF -   sort: Sort rendered features by tile ID
0:00:00 INF -   archive: Encode each tile and write to TileArchiveConfig[format=PMTILES, scheme=FILE, uri=file:///home/oliver/mapterhorn/pipelines/meta-store/coverage.pmtiles, options={}]
0:00:00 DEB - argument: archive_name=Coverage ('name' attribute for tileset metadata)
0:00:00 DEB - argument: archive_description=null ('description' attribute for tileset metadata)
0:00:00 DEB - argument: archive_attribution=null ('attribution' attribute for tileset metadata)
0:00:00 DEB - argument: archive_version=null ('version' attribute for tileset metadata)
0:00:00 DEB - argument: archive_type=baselayer ('type' attribute for tileset metadata)
0:00:00 DEB - argument: archive_format=pbf ('format' attribute for tileset metadata)
0:00:00 INF - Using merge sort feature map, chunk size=2000mb max workers=32
0:00:00 INF [nlcaribischb] - 
0:00:00 INF [nlcaribischb] - Starting...
Worker nlcaribischb_read-2 died
java.lang.IllegalArgumentException: Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high.
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:642)
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:846)
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:784)
	at org.geotools.measure.Angle.toString(Angle.java:149)
	at java.base/java.text.MessageFormat.subformat(MessageFormat.java:1336)
	at java.base/java.text.MessageFormat.format(MessageFormat.java:912)
	at java.base/java.text.Format.format(Format.java:159)
	at java.base/java.text.MessageFormat.format(MessageFormat.java:884)
	at org.geotools.referencing.operation.projection.MapProjection.verifyGeographicRanges(MapProjection.java:478)
	at org.geotools.referencing.operation.projection.MapProjection$Inverse.transform(MapProjection.java:1003)
	at org.geotools.referencing.operation.projection.MapProjection$Inverse.transform(MapProjection.java:1038)
	at org.geotools.geometry.jts.DefaultCoordinateSequenceTransformer.transform(DefaultCoordinateSequenceTransformer.java:108)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.projectCoordinateSequence(GeometryCoordinateSequenceTransformer.java:247)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformStraightLineString(GeometryCoordinateSequenceTransformer.java:201)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformLineString(GeometryCoordinateSequenceTransformer.java:182)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformPolygon(GeometryCoordinateSequenceTransformer.java:252)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transform(GeometryCoordinateSequenceTransformer.java:142)
	at org.geotools.geometry.jts.JTS.transform(JTS.java:405)
	at com.onthegomap.planetiler.reader.GeoPackageReader.readFeatures(GeoPackageReader.java:201)
	at com.onthegomap.planetiler.reader.SourceFeatureProcessor.lambda$readPaths$3(SourceFeatureProcessor.java:174)
	at com.onthegomap.planetiler.worker.WorkerPipeline$Builder.lambda$addWorker$0(WorkerPipeline.java:249)
	at com.onthegomap.planetiler.worker.Worker.lambda$new$0(Worker.java:41)
	at com.onthegomap.planetiler.worker.Worker.lambda$new$1(Worker.java:68)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Exception in thread "main" com.onthegomap.planetiler.Planetiler$PlanetilerException: Error occurred during stage nlcaribischb
	at com.onthegomap.planetiler.Planetiler.run(Planetiler.java:880)
	at Coverage.main(Coverage.java:38)
Caused by: com.onthegomap.planetiler.util.Exceptions$FatalPlanetilerException: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high.
	at com.onthegomap.planetiler.util.Exceptions.throwFatalException(Exceptions.java:29)
	at com.onthegomap.planetiler.stats.ProgressLoggers.await(ProgressLoggers.java:367)
	at com.onthegomap.planetiler.stats.ProgressLoggers.awaitAndLog(ProgressLoggers.java:352)
	at com.onthegomap.planetiler.worker.WorkerPipeline.awaitAndLog(WorkerPipeline.java:59)
	at com.onthegomap.planetiler.reader.SourceFeatureProcessor.processFiles(SourceFeatureProcessor.java:130)
	at com.onthegomap.planetiler.reader.SourceFeatureProcessor.processFiles(SourceFeatureProcessor.java:65)
	at com.onthegomap.planetiler.reader.GeoPackageReader.process(GeoPackageReader.java:116)
	at com.onthegomap.planetiler.Planetiler.lambda$addGeoPackageSource$4(Planetiler.java:410)
	at com.onthegomap.planetiler.Planetiler.lambda$ifSourceUsed$14(Planetiler.java:1006)
	at com.onthegomap.planetiler.Planetiler.run(Planetiler.java:878)
	at Coverage.main(Coverage.java:38)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:484)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:208)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:135)
Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high.
	at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2096)
	at com.onthegomap.planetiler.stats.ProgressLoggers.await(ProgressLoggers.java:361)
	... 14 more
Caused by: java.lang.IllegalArgumentException: Angle 102,758,439,062,199,600,000,000,000,000,000,000,000,000,000 is too high.
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:642)
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:846)
	at org.geotools.measure.AngleFormat.format(AngleFormat.java:784)
	at org.geotools.measure.Angle.toString(Angle.java:149)
	at java.base/java.text.MessageFormat.subformat(MessageFormat.java:1336)
	at java.base/java.text.MessageFormat.format(MessageFormat.java:912)
	at java.base/java.text.Format.format(Format.java:159)
	at java.base/java.text.MessageFormat.format(MessageFormat.java:884)
	at org.geotools.referencing.operation.projection.MapProjection.verifyGeographicRanges(MapProjection.java:478)
	at org.geotools.referencing.operation.projection.MapProjection$Inverse.transform(MapProjection.java:1003)
	at org.geotools.referencing.operation.projection.MapProjection$Inverse.transform(MapProjection.java:1038)
	at org.geotools.geometry.jts.DefaultCoordinateSequenceTransformer.transform(DefaultCoordinateSequenceTransformer.java:108)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.projectCoordinateSequence(GeometryCoordinateSequenceTransformer.java:247)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformStraightLineString(GeometryCoordinateSequenceTransformer.java:201)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformLineString(GeometryCoordinateSequenceTransformer.java:182)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transformPolygon(GeometryCoordinateSequenceTransformer.java:252)
	at org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer.transform(GeometryCoordinateSequenceTransformer.java:142)
	at org.geotools.geometry.jts.JTS.transform(JTS.java:405)
	at com.onthegomap.planetiler.reader.GeoPackageReader.readFeatures(GeoPackageReader.java:201)
	at com.onthegomap.planetiler.reader.SourceFeatureProcessor.lambda$readPaths$3(SourceFeatureProcessor.java:174)
	at com.onthegomap.planetiler.worker.WorkerPipeline$Builder.lambda$addWorker$0(WorkerPipeline.java:249)
	at com.onthegomap.planetiler.worker.Worker.lambda$new$0(Worker.java:41)
	at com.onthegomap.planetiler.worker.Worker.lambda$new$1(Worker.java:68)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Expected behavior
No error is thrown

Environment:

  • Hardware: 7950X AMD Ryzen 9
  • OS: 24.04.1-Ubuntu
  • Java version and distribution: java --version
    openjdk 21.0.12 2026-07-21
    OpenJDK Runtime Environment (build 21.0.12+8-1-24.04-Ubuntu)
    OpenJDK 64-Bit Server VM (build 21.0.12+8-1-24.04-Ubuntu, mixed mode, sharing)

Additional context
The original Dutch Carribean Islands data came in a relatively new CRS that GDAL did not support, so I had to do some reprojection first here: https://github.com/wipfli/nlcaribisch-download/blob/main/run-b.sh

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions