3

我正在尝试更新我的瓦片地图代码以使用 iOS 7MKTileOverlayMKTileOverlayRenderer,并且我可以使用一些指针来使事情更好地工作。

首先,这里是 iOS6 代码:AppleTileOverlay.mTileOverlayView.m。这在 iOS 7 中仍然可以很好地工作,当我替换TileOverlayView一个在所有方面都相同的类时,除了它是一个子类MKOverlayRenderer而不是MKOverlayView.

我正在测试的新作品是一个子类,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}

从为 URL 返回 nil 的方法。

所以问题是:我可以避免这些错误消息,还是应该坚持使用旧的覆盖类?

4

4 回答 4

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 开发者论坛上的 User: 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)); 
            }
        }
    }
于 2015-10-29T11:46:42.613 回答
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

如果您确定瓷砖不存在,这个想法是不触发瓷砖加载。

于 2015-01-06T10:30:23.157 回答
0

当您查看没有图块的地图区域时,是否会发生这种情况?

因为您检查您是否有文件,然后url如果文件不存在则不设置,因此您返回 nil。您应该将有效的 NSURL 返回到透明图像。

于 2013-10-17T20:53:25.607 回答
0

我的猜测是,url尽管没有真实有效的tilePath. 添加一些调试,看看。

于 2013-10-17T17:02:52.513 回答