iOS 中的离线地图

Offline Map in iOS

我非常需要为我的应用程序制作离线地图,因为它主要是为泰国制作的,那里通常很难获得互联网连接。我现在正在为我的 MKTileOverlay 使用 OpenStreetMap,但在实现它以供离线使用时遇到问题。我找到了一个教程,说要子类化 MKTileOverlay。所以,在我的 ViewController 地图所在的地方,我有:

 -(void) viewWillAppear:(BOOL)animated {
CLLocationCoordinate2D coord = {.latitude =  15.8700320, .longitude =  100.9925410};
MKCoordinateSpan span = {.latitudeDelta =  3, .longitudeDelta =  3};
MKCoordinateRegion region = {coord, span};
[mapView setRegion:region];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Map";
    NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
    self.overlay = [[XXTileOverlay alloc] initWithURLTemplate:template];
    self.overlay.canReplaceMapContent = YES;
    [mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels];


}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay {

        return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];

}

在我的 MKTileOverlay 子类中,我有:

- (NSURL *)URLForTilePath:(MKTileOverlayPath)path {
    return [NSURL URLWithString:[NSString stringWithFormat:@"http://tile.openstreetmap.org/{%ld}/{%ld}/{%ld}.png", (long)path.z, (long)path.x, (long)path.y]];
}

- (void)loadTileAtPath:(MKTileOverlayPath)path
                result:(void (^)(NSData *data, NSError *error))result
{
    if (!result) {
        return;
    }
    NSData *cachedData = [self.cache objectForKey:[self URLForTilePath:path]];
    if (cachedData) {
        result(cachedData, nil);
    } else {
        NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
        [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            result(data, connectionError);
        }];
    }
}

问题是什么都没有加载,除非我注释掉子类中的代码。我哪里搞砸了?

您需要一个用图像响应您的 http://<domain>/{z}/{x}/{y}/image.png 的服务器,或者您必须使用路径 /tiles/{z}/{x}/{y}/image.png.

将图块保存在您的应用程序包中

我也有兴趣在离线模式下加载地图。

  1. 首先,我在 gmapcatcher.

    的帮助下将图块下载到我的本地系统(计算机)中

    您可以获得一些关于 gmapcatcher here. And you can download this application here 的信息。

    如果您想下载文件,还有一件重要的事情离线检查,有很多方法可以保存文件。对于这种情况 select OSM 在设置 window 中(位于左侧,您将在设置 window 中指定要下载的路径)

  2. 只需将创建的 tiles 文件夹添加到项目中即可。

  3. 我不知道 objective-c 所以我在 swift 中实施并且我只发布了该代码。

这是代码

import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.mapView.delegate = self

        let baseURL = NSBundle.mainBundle().bundleURL.absoluteString
        let urlTemplate = baseURL.stringByAppendingString("OSM_sat_tiles/{z}/{x}/{y}.png")
        //OSM_sat_tiles is the folder name which has the tiles.
        let layer = MKTileOverlay(URLTemplate: urlTemplate)
        layer.canReplaceMapContent = true
        self.mapView.addOverlay(layer)
    }

    func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
        if overlay is MKTileOverlay {
            let renderer = MKTileOverlayRenderer(overlay:overlay)
            renderer.alpha = 0.8
            return renderer
        }
        return MKTileOverlayRenderer(overlay: overlay)
    }
}

我会简要介绍一下代码。

viewDidLoad 委托方法中,我通过提供 tiles 文件夹的路径来创建 MKTileOverlay。因为我已经放在项目中,所以它会在包中。

并且在 rendererForOverlay 委托方法中我返回 MKTileOverlayRenderer.