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:
#import
// Copyright (c) 2015 Marcus Rohrmoser http://mro.name/me. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// interface unchanged
@interface MKTileOverlayOSMorTMS : MKTileOverlay
@end
/**
* OSM: http://wiki.openstreetmap.org/w/index.php?title=Slippy_map_tilenames&oldid=1201902#X_and_Y
* TSM: http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification
*
* 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
* const MKTileOverlayPath p0 = { x : 70406, y : 42987, z:17 };
* const MKTileOverlayPath p1 = convertYfromOSMtoTMS(p0);
* assert(88084 == p1.y && "");
*/
static inline MKTileOverlayPath convertYfromOSMtoTMS(MKTileOverlayPath path)
{
assert( (1 << path.z) == (NSInteger)pow(2, path.z) && "oops, pow failed" );
path.y = (1 << path.z) - 1 - path.y;
return path;
}
@implementation MKTileOverlayOSMorTMS
/** Detect `{-y}` in case and set `geometryFlipped` accordingly.
*/
-(instancetype)initWithURLTemplate:(NSString *)URLTemplate
{
NSString *t = [URLTemplate stringByReplacingOccurrencesOfString:@"{-y}" withString:@"{y}"];
if( self = [super initWithURLTemplate:t] ) {
// NSParameterAssert(256.0f == self.tileSize.width);
NSParameterAssert(256.0f == self.tileSize.height);
NSParameterAssert(t.length == URLTemplate.length || t.length + 1 == URLTemplate.length);
self.geometryFlipped = t.length < URLTemplate.length;
}
return self;
}
-(NSURL *)URLForTilePath:(MKTileOverlayPath)path
{
if( self.geometryFlipped ) {
// NSParameterAssert(256.0f == self.tileSize.width);
NSParameterAssert(256.0f == self.tileSize.height);
path = convertYfromOSMtoTMS(path);
}
MRLogD(@"%ld,%ld,%ld", (long)path.z, (long)path.x, (long)path.y, nil);
return [super URLForTilePath:path];
}
@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.