from iOS 7.0 onward there’s the neat MKTileOverlay::initWithURLTemplate: for tiled overlay maps.
Sadly it can’t display old-school Tile Map Service maps as e.g. produced by gdal2tiles.py1) because the y-values are flipped upside down. The OSM Wiki says about this fact: „This is really just an unfortunate historical misalignment.“
But with the drop-in MKTileOverlay replacement below, you can use flipped geometries and add {-y}
in the URL template to indicate such:
1#import <MapKit/MKTileOverlay.h>
2// Copyright (c) 2015 Marcus Rohrmoser http://mro.name/me. All rights reserved.
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17// interface unchanged
18@interface MKTileOverlayOSMorTMS : MKTileOverlay
19@end
20
21/**
22 * OSM: http://wiki.openstreetmap.org/w/index.php?title=Slippy_map_tilenames&oldid=1201902#X_and_Y
23 * TSM: http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification
24 *
25 * http://wiki.openstreetmap.org/w/index.php?title=Slippy_map_tilenames&oldid=1201902#Tile_numbers_to_lat..2Flon._.2F_Coordinates_to_tile_numbers_.2F_Sample_of_usage.2C_with_optional_tms-format_support
26 * const MKTileOverlayPath p0 = { x : 70406, y : 42987, z:17 };
27 * const MKTileOverlayPath p1 = convertYfromOSMtoTMS(p0);
28 * assert(88084 == p1.y && "");
29 */
30static inline MKTileOverlayPath convertYfromOSMtoTMS(MKTileOverlayPath path)
31{
32 assert( (1 << path.z) == (NSInteger)pow(2, path.z) && "oops, pow failed" );
33 path.y = (1 << path.z) - 1 - path.y;
34 return path;
35}
36
37@implementation MKTileOverlayOSMorTMS
38
39/** Detect `{-y}` in case and set `geometryFlipped` accordingly.
40 */
41-(instancetype)initWithURLTemplate:(NSString *)URLTemplate
42{
43 NSString *t = [URLTemplate stringByReplacingOccurrencesOfString:@"{-y}" withString:@"{y}"];
44 if( self = [super initWithURLTemplate:t] ) {
45 // NSParameterAssert(256.0f == self.tileSize.width);
46 NSParameterAssert(256.0f == self.tileSize.height);
47 NSParameterAssert(t.length == URLTemplate.length || t.length + 1 == URLTemplate.length);
48 self.geometryFlipped = t.length < URLTemplate.length;
49 }
50 return self;
51}
52
53-(NSURL *)URLForTilePath:(MKTileOverlayPath)path
54{
55 if( self.geometryFlipped ) {
56 // NSParameterAssert(256.0f == self.tileSize.width);
57 NSParameterAssert(256.0f == self.tileSize.height);
58 path = convertYfromOSMtoTMS(path);
59 }
60 MRLogD(@"%ld,%ld,%ld", (long)path.z, (long)path.x, (long)path.y, nil);
61 return [super URLForTilePath:path];
62}
63@end
1) see also the debian package python-gdal or the webpage of Petr Přidal, the author of gdal2tiles with a hint to it’s commercial successor.