Подтвердить что ты не робот

Автономный кэш карты

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

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

4b9b3361

Ответ 1

В нашей компании мы решили использовать MapBox для нашего автономного сопоставления.

Здесь вы можете создавать и создавать свои собственные карты с помощью MapBox Studio, а затем экспортировать свои карты (в выбранном диапазоне уровней масштабирования) во внешний файл. Наш размер составляет около 40 МБ.

Оттуда вы можете использовать MapBox iOS SDK, чтобы легко добавить его в свое приложение.

(Отказ от ответственности: нет, я не работаю для них! Мы специально выбрали их для определения наших собственных цветов и стилей земли/моря и возможности иметь файлы карт, включенные в наш проект Xcode, и пригодные для использования в автономном режиме.)

Я очень ценю ваш точный вопрос: как отключить собственные карты OpenStreetMap, но я надеюсь, что это будет полезно для вас.

Ответ 2

Похоже, вы не заполняете кеш. Он всегда будет пустым?

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) {

        // Instantiate a new cache if we don't already have one.
        if (!self.cache) self.cache = [NSCache new];

        // Add the data into the cache so it there for next time.
        if (data) {
            [self.cache setObject:data forKey:[self URLForTilePath:path]];
        }

        result(data, connectionError);
    }];
}

Я думаю, что это решит вашу проблему. Помните, что NSCache не сохраняется на диске (только для памяти), поэтому, когда он выйдет из фонового рисунка приложения, вам понадобится что-то более сложное в долгосрочной перспективе, если вы хотите полностью автономную возможность (возможно, базовые данные).