tag style bar apple app ios mapkit openstreetmap offline-caching mktileoverlay

ios - style - image share facebook



Caché fuera de línea del mapa (2)

Tengo una gran necesidad de hacer un mapa fuera de línea para mi aplicación, ya que está hecho principalmente para Tailandia, donde la conexión a Internet a menudo es difícil de conseguir. Estoy usando OpenStreetMap ahora mismo para mi MKTileOverlay pero tengo problemas para implementarlo para uso sin conexión. He encontrado un tutorial que dice a la subclase MKTileOverlay . Entonces, en mi ViewController donde está el mapa tengo:

- (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]; }

En mi subclase de MKTileOverlay , tengo:

- (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); }]; } }

El problema es que NADA se carga, a menos que comente el código en la subclase. ¿Dónde estoy metiendo la pata?


En nuestra empresa, decidimos utilizar MapBox para nuestro mapeo fuera de línea.

Allí, puede diseñar y diseñar sus propios mapas con MapBox Studio, luego exportarlos (en un rango de niveles de zoom elegido) a un archivo externo. El nuestro es de unos 40Mb de tamaño.

Desde allí, puede usar el SDK de MapBox para agregarlo fácilmente a su aplicación.

(Descargo de responsabilidad: no, ¡no trabajo para ellos! Los elegimos específicamente por la capacidad de definir nuestros propios colores y estilo terrestres / marinos, y la capacidad de incluir los archivos de mapas en nuestro proyecto Xcode y utilizarlos fuera de línea).

Aprecio que tu pregunta exacta fuera cómo desconectar los mapas propios de OpenStreetMap, pero espero que esto te sea útil.


Parece que no estás llenando el caché. ¿Siempre va a estar vacío?

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''s there for next time. if (data) { [self.cache setObject:data forKey:[self URLForTilePath:path]]; } result(data, connectionError); }]; }

Creo que eso resolverá tu problema aquí. Recuerde que NSCache no persiste en el disco (solo en la memoria), por lo que si bien sobrevive a la aplicación que está en segundo plano, necesitará algo más complejo a largo plazo si desea una capacidad total sin conexión (probablemente, Core Data).