【问题标题】:Offline Map in iOSiOS 中的离线地图
【发布时间】:2016-08-09 16:22:21
【问题描述】:

我非常需要为我的应用制作离线地图,因为它主要是为泰国制作的,那里通常很难获得互联网连接。我现在正在为我的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);
        }];
    }
}

问题是根本没有加载任何东西,除非我注释掉子类中的代码。我在哪里搞砸了?

【问题讨论】:

  • 您需要将所有的图块存储在本地。
  • @rmaddy 我想是这样的。你知道我该怎么做吗?
  • @rmaddy 我在nshipster.com/mktileoverlay-mkmapsnapshotter-mkdirections 找到了一些关于子类化 MKTileOverlay 的教程,但我仍然遇到问题。你能帮忙聊天吗?
  • @rmaddy 请检查帖子以获取更新。

标签: ios mkmapview mapkit offline-caching mktileoverlay


【解决方案1】:

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

  1. 首先,我在 gmapcatcher 的帮助下将图块下载到本地系统(计算机)中。

    您可以获得有关gmapcatcher here 的一些信息。你也可以download this application here

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

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

  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 委托方法中,我通过提供磁贴文件夹的路径来创建 MKTileOverlay。由于我已将其放入项目中,因此它将位于捆绑包中。

rendererForOverlay 委托方法中,我将返回 MKTileOverlayRenderer.

【讨论】:

    【解决方案2】:

    您需要一个服务器来响应您的http://<domain>/{z}/{x}/{y}/image.png 并使用图像,或者您必须使用路径/tiles/{z}/{x}/{y}/image.png 将磁贴保存在您的应用程序包中。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多