﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
22404	[PATCH] MVT background layer: Polygons not drawn	schwarting	taylor.smock	"==== What steps will reproduce the problem?
1. In the background image settings, add a new Mapbox Vector Tiles (MVT) layer.
2. Use this as URL: `https://hfs.github.io/brandenburg-addresses/style.json`
3. Max zoom: 14, enter a name, e.g. “Brandenburg Addresses”
4. Back in the map view, add the new layer from the background imagery menu
5. Navigate the map to Brandenburg/Germany: View › Jump to Position › Enter a place name to search for: Brandenburg, Zoom (in metres): 40000

==== What is the expected result?

The MVT tiles contain polygons (hexagons in a regular grid) that should be painted as filled areas.

Here’s an interactive editor of the map style. It shows the expected result what the rendering should look like. It also shows that the MVT data is fine, and allows you to inspect the map data:

https://maputnik.github.io/editor/?style=https://hfs.github.io/brandenburg-addresses/style.json#7.39/52.454/13.436

==== What happens instead?

No polygons are drawn. The background remains black.

If you zoom in, you can see that the MVTs and the style work in principle. From zoom level 13 and higher it switches to a point visualization which works.

==== My theory of what goes wrong

I think the issue is the polygon winding order. Polygons are converted twice and at some point the correct winding order gets lost.

In the MVT standard it is prescribed that exterior rings of polygons are oriented in clockwise order (in screen coordinates, y points down). See section 4.3.4.4. “Polygon Geometry Type” in https://github.com/mapbox/vector-tile-spec/tree/master/2.1#4344-polygon-geometry-type.

I tried to debug this a bit and I think this is what happens:

In `org.openstreetmap.josm.data.imagery.vectortile.mapbox.Geometry.initializeWayGeometry()` the geometry commands of the MVT are interpreted and a polygon is constructed as `java.awt.geom.Area`. At this point the winding order is still correct.

In `org.openstreetmap.josm.data.vector.VectorDataStore.addFeatureData()`, `shapeToPrimaryFeatureObject()` and then `areaToRelation()` are called to convert the `Area` into a multipolygon `VectorRelation`. `Area.getPathIterator()` iterates over the line segments of the polygon. `pathIteratorToObjects()` converts the polygon rings into `VectorWay`s. Finally, back in `areaToRelation()`

{{{#!java
Geometry.isClockwise(((VectorWay) member).getNodes()) ? ""outer"" : ""inner""`
}}}

is used to set the role of the polygon rings in the multipolygon relation.

During my debugging session, the role was always `inner`. I assume that is the reason why nothing gets drawn on screen: All polygons are converted to multipolygons which consist of only one hole without exterior ring.

To me it looks like `Area` is mixing up the order of line segments, so that `getPathIterator()` doesn’t return them in the same order they were put in.

In my opinion solutions could be to either use a different class than `Area` to construct the polygons. Or to carry the information whether a ring is exterior or interior as extra attribute and not rely on the winding order.

CCing @taylor.smock, because he wrote the MVT layer implementation.

==== Background information

The state of Brandenburg in Germany has published georeferenced housenumber address points as Open Data. I would like to provide a QA layer which highlights addresses which are in the “official” data, but might be missing in OSM.

This is the code to generate the MVT tiles: https://github.com/hfs/brandenburg-addresses (Sorry it’s not yet documented, it’s still work in progress at the time of writing).

As mentioned above, this is the style URL: https://hfs.github.io/brandenburg-addresses/style.json

The tiles can be found here: https://hfs.github.io/brandenburg-addresses/tiles/{z}/{x}/{y}.mvt

If you want to inspect single tile files, they can also be browsed here: https://github.com/hfs/brandenburg-addresses/tree/gh_pages/tiles

I’m confident that the winding order in the tiles is correct. They are generated using ST_AsMVT and ST_AsMVTGeom in PostGIS and I would hope that already handles the winding order. I even wrote a tool in https://github.com/hfs/brandenburg-addresses/tree/main/tools to verify that all polygons in all tiles are oriented correctly.


==== Please provide any additional information below. Attach a screenshot if possible.

{{{
Revision:18559
Is-Local-Build:true
Build-Date:2022-09-24 23:00:25

Identification: JOSM/1.5 (18559 SVN de) Linux Debian GNU/Linux bookworm/sid
Memory Usage: 593 MB / 3898 MB (336 MB allocated, but free)
Java version: 14.0.2+12-Debian-2, Debian, OpenJDK 64-Bit Server VM
Look and Feel: javax.swing.plaf.metal.MetalLookAndFeel
Screen: :0.0 3840×2400 (scaling 2.00×2.00)
Maximum Screen Size: 3840×2400
Best cursor sizes: 16×16→16×16, 32×32→32×32
Environment variable LANG: de_DE.utf8
System property file.encoding: UTF-8
System property sun.jnu.encoding: UTF-8
Locale info: de_DE
Numbers with default locale: 1234567890 -> 1234567890
Desktop environment: GNOME
Java ATK Wrapper package: libatk-wrapper-java:all-0.40.0-2
libcommons-compress-java: libcommons-compress-java:all-1.21-1
libcommons-logging-java: libcommons-logging-java:all-1.2-3
fonts-noto: fonts-noto:all-20201225-1
VM arguments: [-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44149,suspend=y,server=n, -javaagent:/opt/idea-IC-221.5591.52/plugins/java/lib/rt/debugger-agent.jar, -Dfile.encoding=UTF-8]

Plugins:
+ DirectDownload (36011)
+ DirectUpload (35951)
+ FastDraw (35978)
+ ImportImagePlugin (36013)
+ Mapillary (2.0.0-beta.17)
+ OpeningHoursEditor (35924)
+ PicLayer (1.0.2)
+ PolygonCutOut (v0.7)
+ apache-commons (36003)
+ apache-http (35924)
+ buildings_tools (36011)
+ editgpx (35931)
+ ejml (35924)
+ geotools (36015)
+ gson (35924)
+ jackson (36006)
+ javafx (35807)
+ jaxb (35952)
+ jna (36005)
+ jts (36004)
+ log4j (36007)
+ measurement (35978)
+ opendata (36011)
+ pt_assistant (1ff2e15)
+ public_transport (36011)
+ reverter (36011)
+ scripting (v0.2.7)
+ terracer (35978)
+ utilsplugin2 (36011)
+ wikipedia (605)

Tagging presets:
+ /usr/share/josm/data/defaultpresets.xml
+ https://raw.githubusercontent.com/osmlab/name-suggestion-index/main/dist/presets/nsi-josm-presets.min.xml

Map paint styles:
- https://josm.openstreetmap.de/josmfile?page=Styles/ParkingLanes&style&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Maxspeed&style&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Modified&style&zip=1
- http://github.com/bastik/mapcss-tools/raw/osm/mapnik2mapcss/osm-results/mapnik.zip
- https://josm.openstreetmap.de/josmfile?page=Styles/ParkingLanes&style&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Cycleways&style&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Lane_and_Road_Attributes&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/PublicTransport&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Building_Levels_Labels&zip=1
- https://josm.openstreetmap.de/josmfile?page=Styles/Coloured_Streets&zip=1

Last errors/warnings:
- 00002.953 E: JavaFX is not available
- 00003.012 W: Erweiterung deaktivieren - JavaFX ist nicht verfügbar. Bitte installieren Sie OpenJFX über den Paketmanager.
- 00007.933 E: Id 'openpt_map' is not unique - used by 'OpenPT Map (overlay)' and 'OpenPT Map (overlay)'!
- 00013.901 W: Cannot lock cache directory. Will not use disk cache
- 00017.585 E: Fehler beim Laden des Bildes 'bus.png'
- 00018.764 W: Cannot start IPv4 remotecontrol server on port 8111: Die Adresse wird bereits verwendet
- 00018.764 W: Cannot start IPv6 remotecontrol server on port 8111: Die Adresse wird bereits verwendet
- 00022.999 W: java.net.SocketTimeoutException: Connect timed out
- 00023.111 E: Fehler beim Laden des Bildes 'http://openptmap.de/favicon_pt.png'
}}}
"	defect	closed	normal	22.10	Core imagery	latest	fixed	template_report mvt polygon winding	
