mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.23k stars 2.23k forks source link

Polygon distortions on high zoom levels #12825

Open lukasvdelft opened 1 year ago

lukasvdelft commented 1 year ago

I am facing the following. At high zoom levels (e.g. 24) i see distortions in data loaded as draw elements (using draw.add()). The first image shows the data in QGIS. The second image shows the data in Leaflet. The last image shows the data for mabox-gl-js with mapbox-gl-draw. The QGIS image has no distortions (desktop app). The Leaflet setup (also web context) has almost no distortions (default CRS EPSG:3857 used). The mabox-gl-js/draw setup has quite significant distortions (the polygons are walls of a building). In multiple places lines are misplaced or not straight. This is only happening in some places of the full map. I tried all available projections with lambertConformalConic (with proper center and parallels) giving the best result (the one in the last image), all the others led to more distortion. The data is in CRS4326/WGS84 format. So the question is if I have reached the maximum precision of mapbox-gl, or if there are other things to try. Also I am not sure if this question might be more suitable to ask in mabox-gl-draw issues. Thanks for any thoughts.

mapbox-gl-js version: 2.15.0 mapbox-gl-draw: 1.4.0

browser: Chrome version 114.0.5735.198

Expected Behavior

Actual Behavior

Screenshot 2023-08-02 at 12 54 50

Screenshot 2023-08-02 at 12 54 39

Screenshot 2023-08-02 at 12 49 11

mourner commented 1 year ago

In general you can increase precision for GeoJSON sources in GL JS by setting e.g. maxzoom: 24 in the source options. However, since the issue is about features coming from mapbox-gl-draw specifically, this might require implementing a maxzoom option in the plugin itself, if I understood your case correctly. Can you show a sample live test case?

lukasvdelft commented 1 year ago

yes that is exactly what I was expecting, that the maxzoom of gl-draw is the limiting (distorting) factor. i am feeding GeoJson to the draw.add function. in the issue list of gl-draw someone requested a higher zoom factor as well (#1143), but that was in januari, so it is probably not something on the radar. would it matter if I requested that feature as well? for architecture use-cases, the precision as is is surely not sufficient. I don't have a live case yet as I prioritised other things first. I would prefer starting development with mapbox-gl. thanks so far.

mourner commented 1 year ago

@lukasvdelft would you like to submit a PR to GL Draw? The actual change should be pretty small and easy.

lukasvdelft commented 1 year ago

I have the impression that the maxzoom is hardcoded on the GL side (the last PR on this I found is yours, https://github.com/mapbox/mapbox-gl-js/commit/d6c34c81f7b0d6e77f1b25c2c080a3c5afba94ab).

Draw loads layers with "style" type geojson

ctx.options.styles.forEach(function (style) { ctx.map.addLayer(style); });

So how could Draw introduce a a maxzoom for geojson if it is limited on GL side? I probably don't understand enough of the whole setup to judge this correctly.

lukasvdelft commented 1 year ago

ah, I see in setup.js of mapbox-gl-draw a function addLayers(). it specifies a sources.COLD and sources.HOT, like:

ctx.map.addSource(sources.COLD, { data: { type: geojsonTypes.FEATURE_COLLECTION, features: [] }, type: 'geojson' });

does that need to be extended with a variable which sets maxzoom? like:

ctx.map.addSource(sources.COLD, { data: { type: geojsonTypes.FEATURE_COLLECTION, features: [] }, type: 'geojson', maxzoom: defaultOptions.maxZoom });

and add maxZoom to the const defaultOptions

I never made a PR before