Summary
What tippecanoe
settings do I have to use to generate a valid PMTiles file for use with the MapWithAI plugin in JOSM?
Background info
I’m trying to generate a data set in PMTiles format for use with the MapWithAI JOSM plugin. The plugin recently gained the ability to load data from custom PMTiles.
The input data set are potentially missing addresses in Brandenburg (Germany) as Point geometries in GeoJSON format: brandenburg_missing_addresses.geojson.
The tippecanoe tool can generate vector tiles as PMTiles (also MBTiles, or MVT trees) from GeoJSON files (and other formats).
Test v1: default settings
If I run
tippecanoe --force --output=missing_v1.pmtiles --name=missing \
--no-tile-compression brandenburg_missing_addresses.geojson
I get a PMTiles file with zoom levels 0 through 14. Zoom 14 contains the full data. Lower zoom levels are thinned out and contain only a sample of the points.
I can load this data in JOSM. If you want to try it yourself, you need to have the MapWithAI plugin installed. Go to Data › MapWithAI › MapWithAI Preferences. In the bottom section with Selected entries add a new entry with the + button:
- Service URL: https://gist.github.com/hfs/81492081e966ee9f70490802dea79398/raw/f783f06acee7605c1ef33cfafebbb45bee278762/missing_v1.pmtiles
- Name: v1
- Type: PMTILES
The data gets loaded, but only a thinned out zoom level. In areas with lots of potential addresses, only a few are loaded.
I’m testing with this location: OpenStreetMap (I don’t intend to add these addresses to OSM, there’s just a high density of reported addresses.)
Screenshot from JOSM: Only a few addresses are loaded into the overlay layer.
To compare this to the data actually contained in the PMTiles file, I’ve converted it back into one GeoJSON per zoom level with the help of tippecanoe-decode
.
Here’s a screenshot showing the contents of the PMTiles file per zoom level in QGIS.
You can see the zoom level 14 is complete an not thinned out. These are the address nodes I would expect to get loaded into JOSM.
Instead, if you compare the positions of the actually loaded data with the different layers in the QGIS screenshot, you can see that zoom level 12 is the one that gets loaded into the MapWithAI layer.
Test v2: Only zoom level 12
Ok, after these results I thought that the plugin might be hardcoded to use zoom level 12.
So I created version 2 using
tippecanoe --output=missing_v2.pmtiles --name=missing \
-z12 -Z12 --no-tile-size-limit --no-tile-compression \
brandenburg_missing_addresses.geojson
-z12 -Z12
limit the zoom minimum and maximum zoom level to 12. So only this zoom level is generated. --no-tile-size-limit
disables pruning of features, so all points should be present.
The result file is available here: https://gist.github.com/hfs/81492081e966ee9f70490802dea79398/raw/f783f06acee7605c1ef33cfafebbb45bee278762/missing_v2.pmtiles
I cannot load this data. Instead, I get this exception:
java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Vector tile layers must have a layer name
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:562)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:591)
at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:672)
at org.openstreetmap.josm.plugins.mapwithai.actions.AddMapWithAILayerAction.actionPerformed(AddMapWithAILayerAction.java:116)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
I don’t understand why v2 results in this error, while v1 was created with almost the same options. Both used --name
to set a name.
Test v3: Zoom 0–12, set a description
After v2 I thought, maybe providing only zoom 12 is a problem. And there’s also a --description
option, maybe that sets the name the exception is complaining about.
tippecanoe --output=missing_v3.pmtiles --name=missing \
--description="Potentially missing addresses in Brandenburg, Germany" \
--attribution="GeoBasis-DE/LGB (2023): Georeferenzierte Adresse" \
-z12 --no-tile-size-limit --no-tile-compression \
brandenburg_missing_addresses.geojson
The result file is available here: https://gist.github.com/hfs/81492081e966ee9f70490802dea79398/raw/f783f06acee7605c1ef33cfafebbb45bee278762/missing_v3.pmtiles
This results in the same exception as v2.
Questions
After all this I’m very confused. My questions are:
What tippecanoe
settings do I have to use to generate a valid PMTiles file for use with the MapWithAI plugin in JOSM?
Does the MapWithAI plugin use the information about the minimum and maximum zoom levels in the PMTiles file?
Does it make sense to provide thinned out lower zoom levels, or should I only generate one zoom level with the full data? Which zoom level?
What’s the difference between v1 and v2/v3 resulting in the exception? I don’t understand why v2 is missing some “name” that v1 has, despite the command line options to tippecanoe being so similar?