Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] unbounded horizontal scroll breaks most tile grids #1976

Open
arneke opened this issue Oct 10, 2024 · 6 comments
Open

[BUG] unbounded horizontal scroll breaks most tile grids #1976

arneke opened this issue Oct 10, 2024 · 6 comments
Labels
bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing

Comments

@arneke
Copy link

arneke commented Oct 10, 2024

What is the bug?

My EPSG:3006 WMTS layer works in 7.0.2, but stopped working after I switched to the master branch. On closer inspection, the reason was that flutter_map is requesting the wrong x,y,z tiles for a given lat,long position.

I've not completely isolated #1948 as the cause, but I think it's the most likely thing in the commit log, and there is an assumption about the modulus that is not generally true.

How can we reproduce it?

Most non-WebMercator grids should trigger this, but here is one.

// Don't include this in the repo, just to illustrate the bug
FlutterMap(
    mapController: mapController,
    options: MapOptions(
        initialCameraFit: CameraFit.bounds(
          bounds: LatLngBounds(
              LatLng(61.285991891313344, 17.006922572652666),
              LatLng(61.279648385340494, 17.018309853620366)),
        ),
        crs: Proj4Crs.fromFactory(
          code: 'EPSG:3006',
          proj4Projection: proj4.Projection.add(
            'EPSG:3006',
            '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs',
          ),
          origins: [
            Point(-1200000.0, 8500000.0),
          ],
          resolutions: const <double>[
            4096,
            2048,
            1024,
            512,
            256,
            128,
            64,
            32,
            16,
            8,
            4,
            2,
            1,
            0.5,
            0.25,
            0.125
          ],
        )),
    children: [
      TileLayer(
        tileBuilder: coordinateDebugTileBuilder,
        urlTemplate:
            'https://minkarta.lantmateriet.se/map/topowebbcache?layer=topowebb&style=default&tilematrixset=3006&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&TileMatrix={z}&TileCol={x}&TileRow={y}',
      )
    ],
  )

Do you have a potential solution?

I don't uderstand all the code in #1948 , but I believe the problem originates in

final modulo = 1 << coordinates.z;

final modulo = 1 << coordinates.z;

I don't think the code currently handles cases where

  • the grid is not square
  • has more than one tile for z = 0
  • or the projection does not cover the world

In general, I think you need a flag on the CRS to know whether unbounded scroll applies. Or only enable it for WebMercator for now.

Platforms

All

Severity

Obtrusive: Prevents normal functioning but causes no errors in the console

@arneke arneke added bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing labels Oct 10, 2024
@arneke
Copy link
Author

arneke commented Oct 10, 2024

( @monsieurtanuki )

@monsieurtanuki
Copy link
Contributor

I don't think the code currently handles cases where

  • the grid is not square
  • has more than one tile for z = 0
  • or the projection does not cover the world

@arneke Indeed, what I know about GIS is limited to

  • zoom is a positive integer
  • there are power(2, zoom) x and y coordinates (therefore 1*1 tile for zoom = 0)
  • tiles are identical squares - I guess identical rectangles would be fine too
  • projections cover all longitudes

Which of my assumptions is wrong in your case? With your help, I'd be able to make both systems work - webmercator and more exotic ones. Possibly with a flag.

I'll have a look at your example and see what happens.

@arneke
Copy link
Author

arneke commented Oct 10, 2024

Thanks for responding 👍

Unfortunately it gets a bit more complicated. Resolutions where you divide by two are common, but there are also grids where each matrix corresponds to 1:1000, 1:2000, 1:2500 , etc, to match old requirements.

And to be fair, there is quite a bit of code in flutter_map that makes this confusing. (The projection has to be the same for all layers, but each layer should actually have a separate set of resolutions and origins, so that tile boundaries from different sources do not have to align perfectly)

You can have a look at https://minkarta.lantmateriet.se/ , the web client illustrates that you cannot zoom out to a single tile, z = 0 is actually 6 x 10 tiles (approximately).

The tilematrix is described in
And https://minkarta.lantmateriet.se/map/topowebbcache?Service=WMTS&Request=getcapabilities

To be honest, I think you should only do this for webmercator, revert to the old behavior for all others. Will cover 90% of the use cases and not break anything.

@monsieurtanuki
Copy link
Contributor

@arneke Looking back at the code, hopefully it won't be hard to fix (?) because I only added a couple of new classes.
Those classes make sense anyway, it's just that in "your" case they have a slightly different behavior - e.g. "no it makes no sense to add power(2, zoom) to an X coordinate".

@monsieurtanuki
Copy link
Contributor

@arneke Good news - in a first approach - I've managed to roll back my changes in only 5 files.

before after
Screenshot_1728567156 Screenshot_1728567262

That doesn't mean that the implementation for both systems is done yet ;)

@arneke
Copy link
Author

arneke commented Oct 10, 2024

nice 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing
Projects
Status: To do
Development

No branches or pull requests

2 participants