Preventing overlays from disappearing when zoomed - MKMapView & MKOverlay
Asked Answered
B

3

8

I am working on an iPhone / iPad app that is using semi-transparant tiled map overlays via MKMapView and MKOverlay.

I want users to be able to zoom in deeply into the maps, but the resolution of my map overlays only goes to level 6.

I do not want to limit zooming.

But... If a user zooms "too far" and then scrolls to a new tile, if they are zoomed deeper than the tree of overlay tiles, my overlay is not drawn.

I want the overlay to draw even when the user is zoomed in deep.

Are there any best practices to achieve this?

The two options I have come up with:

1) Set a limit on how far users can zoom. Not ideal because even if the overlay is low-res, they are likely still within the colored range of transparency, and having the transparent over-layer seemingly vanish is misleading.

2) Pre-render tiles that go way deeper than they otherwise would... This works, but it balloons my app by an order of magnitude in size.

There has got to be a better way. Any ideas???

UPDATE: The closest example code to what I am doing I can find is Apple's TileMap sample from WWDC 2010. Their code suffers from the same problem - if you are zoomed in "too far" the map overlay is not displayed.

Balsaminaceous answered 4/12, 2010 at 3:12 Comment(0)
B
4

I modified Apple's TileMap sample code by adding an "OverZoom" mode. I have posted more details and my code as an answer to this question.

I hope I can help out anyone else who stumbles across this problem.

Balsaminaceous answered 15/12, 2010 at 0:17 Comment(0)
M
5

MKTileOverlay has a maximumZ property. For me, my tile server only rendered up to zoom 18 (mapnik from osm data), so I set my overlay.maximumZ = 18, and now when I zoom in to 19 or 20 (highest on iPhone), it just keeps the zoom 18 tiles.

That said I am initializing my overlay via initWithURLTemplate:

In viewDidLoad (or wherever you initialize your overlay):

self.mapView.delegate = self;
NSString *urlTemplate = @"http://servername/osm/{z}/{x}/{y}.png";
self.mapOverlay = [[MKTileOverlay alloc] initWithURLTemplate:urlTemplate];
self.mapOverlay.canReplaceMapContent=YES;
[self.map addOverlay:self.overlay level:MKOverlayLevelAboveLabels];

Then implment the following method:

-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {    
    if([overlay isKindOfClass:[MKTileOverlay class]]) {
        MKTileOverlay *tileOverlay = (MKTileOverlay *)overlay;
        tileOverlay.maximumZ = 18;  // This is what sets the cap, zoom levels further in will not be rendered and instead will keep previous zoom level tiles.
        MKTileOverlayRenderer *renderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:tileOverlay];
        return renderer;
    }
    return nil;
}
Matronna answered 25/9, 2014 at 20:21 Comment(1)
It's a nice workaround but if the user scrolls at this "too high level", it won't display not loaded tiles.Salute
B
4

I modified Apple's TileMap sample code by adding an "OverZoom" mode. I have posted more details and my code as an answer to this question.

I hope I can help out anyone else who stumbles across this problem.

Balsaminaceous answered 15/12, 2010 at 0:17 Comment(0)
C
1

I recommend checking out the HazardMap sample code on Apple's site... it's a great example of how to support zooming at all levels with a tiled MKOverlay.

Centurial answered 4/12, 2010 at 3:34 Comment(1)
HazardMap is a good example, but it is algorithmically generating tiles. I am using tiles that are sliced up from another map using gdal2tiles.Balsaminaceous

© 2022 - 2024 — McMap. All rights reserved.