flutter_map icon indicating copy to clipboard operation
flutter_map copied to clipboard

[BUG] Retina mode not working properly when using Bing Maps

Open luka-glusica opened this issue 2 years ago • 8 comments

What is the bug?

Hi,

I've been playing around with Bing Maps implementation (see here). Although it works properly in a default setup, when setting retinaMode: true in TileLayer options, markers I used to position on the map somewhere in the UK, get distorted and translated somewhere in between New Zealand and Antractica.

I would appreciate some help on the subject.

Thanks.

What is the expected behaviour?

It should work like it works for any other TileLayer implementation. I have tried it with OSM and Azure Maps and it works fine.

How can we reproduce this issue?

class BingTileProvider extends TileProvider {
  BingTileProvider({
    super.headers,
  });

  String _getQuadKey(int x, int y, int z) {
    final StringBuffer quadKey = StringBuffer();
    for (int i = z; i > 0; i--) {
      int digit = 0;
      final int mask = 1 << (i - 1);
      if ((x & mask) != 0) {
        digit++;
      }
      if ((y & mask) != 0) {
        digit++;
        digit++;
      }
      quadKey.write(digit);
    }
    return quadKey.toString();
  }

  @override
  String getTileUrl(Coords<num> coords, TileLayer options) {
    String url = options.urlTemplate ?? '';

    return url.replaceAll('{subdomain}', 't0').replaceAll('{quadkey}',
            _getQuadKey(coords.x.toInt(), coords.y.toInt(), coords.z.toInt()))
        .replaceAll('{culture}', 'en-US');
  }

  @override
  ImageProvider<Object> getImage(Coords<num> coords, TileLayer options) {
    return NetworkImage(getTileUrl(coords, options));
  }
}

class BingRoadLayer extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: http.get(Uri.parse(
          'http://dev.virtualearth.net/REST/V1/Imagery/Metadata/RoadOnDemand?output=json&include=ImageryProviders&key=[YOUR_API_KEY]')),
      builder: (context, response) {
        if (response.connectionState == ConnectionState.waiting) {
          return SizedBox();
        }

        return TileLayer(
          maxZoom: 21,
          urlTemplate: jsonDecode(response.data!.body)['resourceSets'][0]
              ['resources'][0]['imageUrl'],
          tileProvider: BingTileProvider(),
          retinaMode: true,
        );
      },
    );
  }
}

Do you have a potential solution?

Not really.

Can you provide any other information?

No response

Platforms Affected

Android

Severity

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

Frequency

Consistently: Always occurs at the same time and location

Requirements

  • [X] I agree to follow this project's Code of Conduct
  • [X] My Flutter/Dart installation is unaltered, and flutter doctor finds no relevant issues
  • [X] I am using the latest stable version of this package
  • [X] I have checked the FAQs section on the documentation website
  • [X] I have checked for similar issues which may be duplicates

luka-glusica avatar Mar 26 '23 10:03 luka-glusica

Hi @luka-glusica, Unfortunately I can't offer help with solving this, I have no experience with this. It may be a bug, or Bing Maps may not properly support retina mode in this way. Note the experience with the markers moving around is the opposite: the map is moving around underneath the markers. The markers coordinate space is not affected. Leaving open for now.

JaffaKetchup avatar Mar 29 '23 15:03 JaffaKetchup

Thanks, @JaffaKetchup.

I'm a bit new to Flutter, so I can't confidently dive in deeply into source code, but there are some Web solutions with conceptually similar implementation, that might give us the clue (e.g Openlayers has a nice implementation of Bing Maps with hidpi parameter for higher pixel density tiles).

I'll try to find the solution myself in the meantime and post it here.

luka-glusica avatar Mar 29 '23 17:03 luka-glusica

@luka-glusica No problem, always happy to help another Luka ;D

(Note that #1475 might change things here.)

JaffaKetchup avatar Mar 29 '23 19:03 JaffaKetchup

@luka-glusica No problem, always happy to help another Luka ;D

I noticed that as well, but it was late and I wasn't sure if I imagined it :D

(Note that #1475 might change things here.)

Great, I'll check it out. Thanks.

luka-glusica avatar Mar 30 '23 06:03 luka-glusica

@luka-glusica in Flutter Maps v6, the Retina implementation has been improved. Do you know if this issue still occurs? and would you provide a screenshot?

One quick idea, is that Retina mode is implemented by requesting 4 tiles at one zoom lower than the camera. If you are zoomed in as far as Bing allows, but then FM/Retina fetches one layer further, I suspect incorrect things may happen. You could try and set TileLayer.maxNativeZoom to 21 instead of maxZoom

bramp avatar Oct 12 '23 16:10 bramp

@luka-glusica in Flutter Maps v6, the Retina implementation has been improved. Do you know if this issue still occurs? and would you provide a screenshot?

One quick idea, is that Retina mode is implemented by requesting 4 tiles at one zoom lower than the camera. If you are zoomed in as far as Bing allows, but then FM/Retina fetches one layer further, I suspect incorrect things may happen. You could try and set TileLayer.maxNativeZoom to 21 instead of maxZoom

Thanks @bramp, I will check it out and let you know.

luka-glusica avatar Oct 17 '23 11:10 luka-glusica

I have tested it @bramp. It seems that issue is still there (see screenshots).

retina_true retina_false

As you can see, same markers, same coordinates, but retinaMode: true on the left and retinaMode: false on the right (correct preview). I also tried setting maxNativeZoom to 21 as suggested, but the output is the same.

luka-glusica avatar Oct 17 '23 12:10 luka-glusica

I wonder if this is somehow related to the tileSize being broken (#1669), as this has similar results. No real idea though. I also wonder whether this is something that zoomOffset might fix, as well as playing around with tileSize. I have no idea which (if any) combination might work, but just looking at the images above, it's potentially possible.

JaffaKetchup avatar Oct 18 '23 21:10 JaffaKetchup

Hey @luka-glusica, if you're still experiencing this issue, I think setting zoomOffset to -1 might fix this. Let me know if it doesn't!

JaffaKetchup avatar Jun 06 '24 13:06 JaffaKetchup

@JaffaKetchup same issue here, i tried zoomOffset and doesnt work for me :(

dev7Aproms avatar Jul 04 '24 15:07 dev7Aproms

Hey @dev7Aproms, can you post a full MRE please?

JaffaKetchup avatar Jul 06 '24 10:07 JaffaKetchup