flutter_map
                                
                                
                                
                                    flutter_map copied to clipboard
                            
                            
                            
                        [BUG] Retina mode not working properly when using Bing Maps
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 doctorfinds 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
 
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.
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 No problem, always happy to help another Luka ;D
(Note that #1475 might change things here.)
@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 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
@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.maxNativeZoomto 21 instead ofmaxZoom
Thanks @bramp, I will check it out and let you know.
I have tested it @bramp. It seems that issue is still there (see screenshots).
 
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.
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.
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 same issue here, i tried zoomOffset and doesnt work for me :(
Hey @dev7Aproms, can you post a full MRE please?