Оффлайн карта в iOS

У меня есть большая потребность в создании автономной карты для моего приложения, так как она сделана в основном для Таиланда, где часто бывает трудно получить доступ к интернету. Я использую OpenStreetMap прямо сейчас для моего MKTileOverlay но у меня проблемы с его реализацией для использования в автономном режиме. Я нашел учебник, который говорит, чтобы подкласс 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);
        }];
    }
}

Проблема в том, что НИЧЕГО не загружается вообще, если я не закомментирую код в подклассе. Где я все испортил?

2 ответа

Решение

Я также заинтересован в загрузке карты в автономном режиме.

  1. Прежде всего я загрузил плитки в свою локальную систему (компьютер) с помощью gmapcatcher.

    Вы можете получить некоторую информацию о gmapcatcher здесь. И вы можете скачать это приложение здесь.

    Еще одна важная вещь, если вы хотите скачать файлы, проверьте автономно, и есть много способов сохранить файлы. Для этого сценария выберите OSM в окне настроек (находится слева, где вы будете указывать путь для загрузки в окне настроек)

  2. Просто добавьте созданную папку плиток в проект.

  3. И я не знаю, цель-c, поэтому я внедряю в быстрый и я разместил только этот код.

Вот код

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.

Вам нужен сервер, который отвечает на ваш http://<domain>/{z}/{x}/{y}/image.png с изображением или вы должны сохранить плитки в вашем комплекте приложений, используя путь /tiles/{z}/{x}/{y}/image.png,

Другие вопросы по тегам