visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.21k stars 2.09k forks source link

GeoJsonLayer tesselates polygon data incorrectly #6751

Closed Gimir closed 2 years ago

Gimir commented 2 years ago

Description

I generated geojson data for drawing day/night layer on map (link in reproduce section), and when I pass the data to GeoJsonLayer it draws additional polygon or something. Here is what layer looks like in my case with deck.gl:

Снимок экрана 2022-03-11 в 16 35 20

Flavors

Expected Behavior

When I test data passed to GeoJsonLayer in geojson.io, it correctly draws given polygon.

Снимок экрана 2022-03-11 в 17 14 19

Steps to Reproduce

Here is link to Sandbox Generating GeoJson data on line - 17 Creating GeoJsonLayer on line - 37

Here is Gist with full polygon data in Geojson.io (to see raw click on < > button)

Example layer GeoJson data:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {},
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            -360,
                            90
                        ],
                        [
                            360,
                            90
                        ],
                        ...
                        [
                            -360,
                            90
                        ],
                    ]
               ]
          }
     }
  ]
}

Environment

Logs

No response

ibgreen commented 2 years ago

I have seen a similar issue, in the FlatgeobufLoader example in loaders.gl (see the spurious triangle in the very south).

Screen Shot 2022-03-11 at 8 47 51 AM Screen Shot 2022-03-11 at 8 49 20 AM

To repro, go to https://loaders.gl/examples/geopkg and select the flatgeobuf file in the dropdown.

We haven't ruled out that it could be a problem in the flatgeobuf loader but it seems to follow a similar pattern (i.e. geometry close to the pole being incorrectly tessellated).

Gimir commented 2 years ago

@ibgreen yes, it seems to be same issue. I tried two layers (PolygonLayer, SolidPolygonLayer), both have this problem. Also I tried different coordinate systems (180 90, 360 90), same thing.

kylebarron commented 2 years ago

A couple quick observations:

Gimir commented 2 years ago

@kylebarron it works! Thank you man, I changed latitude to 85 and artifacts are gone.

kylebarron commented 2 years ago

Good to know, though I'd still consider this a bug.

ibgreen commented 2 years ago

Good to know, though I'd still consider this a bug.

Yes, or maybe two different bugs.

We use earcut for tesselation and it is advertised as offering very high performance with the down side being that it doesn't guarantee correctness: https://github.com/mapbox/earcut#the-algorithm.

If one or both of these issues relate to earcut . I suppose one option could be to also offer a slower, more robust tesselation algorithm.

felixpalmer commented 2 years ago

In PolygonTesselator, we already cut the polygon by Mercator bounds when wrapLongitude is set. Would a similar approach work here?

kylebarron commented 2 years ago

We could definitely try it. I haven't tried to render polar data in deck.gl myself, so I can't guarantee that will fix this error, but it might.

Pessimistress commented 2 years ago

@Gimir If you set wrapLongitude: true on the layer, it will be rendered correctly.

Web Mercator projection's latitude limit is around 85.0511 (source). 90 is projected to infinity and is usually the culprit of strange tesselation outcomes. In the shader, we clamp latitudes to 89.9 to avoid artifacts, but we don't do it on the CPU (Viewport.projectFlat). We should handle 90 gracefully since it is technically valid GeoJSON.

Pessimistress commented 2 years ago

Fixed in v8.7.4