我正在尝试更新我的平铺地图代码以使用iOS 7的MKTileOverlay
和MKTileOverlayRenderer
,我可以使用一些指示来使事情更好。
首先,这是iOS6代码:AppleTileOverlay.m和TileOverlayView.m。当我将TileOverlayView
替换为一个在所有方面都相同的类时,除了它是MKOverlayRenderer
的子类而不是MKOverlayView
之外,这在iOS 7中仍能很好地工作。
我正在测试的新作品是MKTileOverlay
的子类,唯一的方法是:
-(NSURL *)URLForTilePath:(MKTileOverlayPath)path {
NSString *tileKey = [[NSString alloc] initWithFormat:@"%d%d%d", path.x, path.y, path.z];
NSString *tilePath = [[NSBundle mainBundle] pathForResource:tileKey ofType:nil inDirectory:@"TileFolder"];
NSURL *url;
if (tilePath) {
url = [NSURL fileURLWithPath:tilePath];
}
return url;
}
地图图块大部分时间都可以正常加载,但是日志填满了这样的消息:
Error loading URL (null): Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x1b3e19e0 {NSUnderlyingError=0x1894d470 "bad URL", NSLocalizedDescription=bad URL}
从返回nil的方法获取URL。
所以问题是:我可以避免这些错误消息,或者我应该坚持使用旧的覆盖类吗?
答案 0 :(得分:1)
我认为使用Swift 2.0时, URLForFilePath(...)无法返回 nil ,因为它不是可选的。
我设法使用 MKTileOverlay 子类来解决此问题,以检查上面的有效磁贴路径并加载“假”'如果图块图像不可用,则为透明图块。
override func URLForTilePath(path: MKTileOverlayPath) -> NSURL {
let tileKey = String(format:"%d/%d/%d",path.z,path.x,path.y)
let tilePath = NSBundle.mainBundle().pathForResource(tileKey, ofType: "png", inDirectory: "Maps/Map1880")
let blankTilePath = NSBundle.mainBundle().pathForResource("blank", ofType: "png", inDirectory: "Maps")
var url: NSURL
if ((tilePath) != nil)
{
url = NSURL.fileURLWithPath(tilePath!)
} else {
url = NSURL.fileURLWithPath(blankTilePath!)
}
return url;
}
这不是很优雅,因为它为每个不属于叠加层的图块加载空白图块。
然而,有一个更好的解决方案,感谢Apple Developer Forum上的用户: junkpile ,尝试加载不存在的覆盖切片的问题是 boundingMapRect 默认设置为 MKMapRectWorld ,即整个世界。
要将此限制为所需的叠加区域,请将子项 MKTileOverlay 。
以下是一个例子:
import MapKit
class CustomTileOverlay : MKTileOverlay {
override var boundingMapRect: MKMapRect {
get {
//North-East Corner of region
let lat1 = 53.46075
let long1 = -1.92618
//South-West Corner of region
let lat2 = 53.43018
let long2 = -1.992885
//Convert to Coordinates
let coord1 = CLLocationCoordinate2DMake(lat1,long1)
let coord2 = CLLocationCoordinate2DMake(lat2,long2)
//Convert to map points
let p1 = MKMapPointForCoordinate (coord1);
let p2 = MKMapPointForCoordinate (coord2);
//Return the MKMapRect
return MKMapRectMake(fmin(p1.x,p2.x), fmin(p1.y,p2.y), fabs(p1.x-p2.x), fabs(p1.y-p2.y));
}
}
}
答案 1 :(得分:0)
我的猜测是,尽管没有真正有效的url
,你总是试图设置tilePath
。添加一些调试并查看。
答案 2 :(得分:0)
当您查看地图上没有瓷砖的区域时会发生这种情况吗?
因为您检查是否有该文件,然后如果该文件不存在则不设置url
,则返回nil。您应该将有效的NSURL返回到透明图像。
答案 3 :(得分:0)
您可以通过创建自定义MKTileOverlay
子类来避免它,如下所示:
@interface MyTileOverlay : MKTileOverlay
@end
@implementation MyTileOverlay
- (NSURL *)URLForTilePath:(MKTileOverlayPath)path
{
NSString *tileKey = [[NSString alloc] initWithFormat:@"%d%d%d", path.x, path.y, path.z];
NSString *tilePath = [[NSBundle mainBundle] pathForResource:tileKey ofType:nil inDirectory:@"TileFolder"];
NSURL *url;
if (tilePath)
{
url = [NSURL fileURLWithPath:tilePath];
}
return url;
}
- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result
{
NSURL *url = [self URLForTilePath:path];
if (url)
{
[super loadTileAtPath:path result:result];
}
}
@end
如果您确定磁贴不存在,那么我们的想法是不会触发磁贴加载。