2012-05-09 17 views
11

Domanda veloce per voi. Ho una app su cui sto lavorando che richiederà l'uso di mappe, ma non avrà una connessione di rete. Ho visto gli altri fare domande simili su questo, ma le mie esigenze sono leggermente diverse, quindi ho voluto postare una nuova domanda.Offline MapKit soluzione per iOS

Ecco i miei requisiti per l'app.

  1. Consenti pizzico/zoom di una mappa con annotazioni definibili
  2. mappa deve essere disponibile non in linea
  3. mappa dovrebbe essere limitato a una determinata area geo
  4. App non deve passare l'ispezione di Apple. Questa è un'app aziendale che fungerà da chiosco.

Quindi, esiste un framework o un metodo per la cache delle mappe che chiunque può suggerire?

Grazie uscire in anticipo.

+0

Ho paura che Caleb abbia ragione. Anche se potessi in qualche modo memorizzare nella cache i dati delle mappe, non faresti uso di questi termini. –

risposta

1

Controllare la sezione 10.3 dello Google Maps Terms of Service e scoprirai che non sei autorizzato a memorizzare alcun contenuto di Google Maps. Ciò significa che dovrai fornire non solo la tua mappa, ma anche sostituire la pratica funzionalità MapKit. Non puoi davvero usare MapKit affatto per le applicazioni offline, per quanto ne so.

1

Sfortunatamente MapKit Framework non supporta l'accesso alla mappa offline. Si dovrebbe preferire MapBox iOS SDK (MapBox iOS SDK è un set di strumenti per la creazione di applicazioni mappe che supportano la politica di caching offline, i limiti di zoom, il comportamento display retina, a partire coordinare, e guarda la mappa trascinando decelerazione ecc ....

Find the example link

felice Coding

1

Vedere la skobbler/Telenav SDK - si basa su OpenStreetMap ed è un (quasi) completa sostituzione stack a MapKit (mappa rendering, il routing & turno da navigazione turn) con supporto integrato per le mappe offline

9

Ho usato la mappa predefinita di MapKit e una sottoclasse di MKTileOverlay per poter salvare le tessere scaricate e restituire le tessere già memorizzate nella cache senza scaricarle.

1) Variazione di origine per la mappa predefinita da MapKit e utilizzare una sottoclasse di MKTileOverlay (Usato "Open Street Map" qui)

- (void)viewDidLoad{ 
    [super viewDidLoad]; 
    static NSString * const template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png"; 

    VHTileOverlay *overlay = [[VHTileOverlay alloc] initWithURLTemplate:template]; 
    overlay.canReplaceMapContent = YES; 
    [self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels]; 
} 

2) sottoclasse da MKTileOverlay

@interface VHTileOverlay() // MKTileOverlay subclass 
@property (nonatomic, strong) NSOperationQueue *operationQueue; 
@end 

@implementation VHTileOverlay 

-(instancetype)initWithURLTemplate:(NSString *)URLTemplate{ 

    self = [super initWithURLTemplate:URLTemplate]; 
    if(self){ 
     self.directoryPath = cachePath; 
     self.operationQueue = [NSOperationQueue new]; 
    } 
    return self; 
} 


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

    NSString *pathToFilfe = [[self URLForTilePath:path] absoluteString]; 
    pathToFilfe = [pathToFilfe stringByReplacingOccurrencesOfString:@"/" withString:@"|"]; 
    // @"/" - those are not approriate for file's url... 

    NSData *cachedData = [self loadFileWithName:pathToFilfe]; 
    if (cachedData) { 
     result(cachedData, nil); 
    } else { 
     NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]]; 
     __block VHTileOverlay *weakSelf = self; 
     [NSURLConnection sendAsynchronousRequest:request 
              queue:self.operationQueue 
           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
            NSLog(@"%@",[weakSelf URLForTilePath:path]); 

            if(data){ 
             [self saveFileWithName:[[weakSelf URLForTilePath:path] absoluteString] imageData:data]; 
            } 
            result(data, connectionError); 
     }]; 
    } 
} 

-(NSString *)pathToImageWithName:(NSString *)fileName 
{ 
    NSString *imageFilePath = [[OfflineMapCache sharedObject].cachePath stringByAppendingPathComponent:fileName]; 
    return imageFilePath; 
} 

- (NSData *)loadFileWithName:(NSString *)fileName 
{ 
    NSString *imagePath = [self pathToImageWithName:fileName]; 
    NSData *data = [[NSData alloc] initWithContentsOfFile:imagePath]; 
    return data; 
} 

- (void)saveFileWithName:(NSString *)fileName imageData:(NSData *)imageData 
{ 
// fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"|"]; 
// NSString *imagePath = [self pathToImageWithName:fileName]; 
// [imageData writeToFile:imagePath atomically:YES]; 
} 

Rimuovere il commento " saveFileWithName "ed eseguirlo sul simulatore. Puoi anche aggiungere NSLog (fileName) per sapere dove trovare tutte le tessere che ti servono. (La cache del simulatore è in Users/YOU/Library/Developer/CoreSimulator/Devices/... E Library è una directory nascosta)

Dopo aver memorizzato nella cache tutto ciò che serve è sufficiente inserire il pacchetto della tua app (proprio come qualsiasi altra immagine , se vuoi dalla mappa nella cache della casella).E dillo al tuo

- (void)loadTileAtPath:(MKTileOverlayPath)path 
       result:(void (^)(NSData *data, NSError *error))result 

per ottenere le tessere dal fascio.

Così ora posso installare la mia app, disattivare il wi-fi e otterrò comunque quelle mappe.

+0

Ho provato a usare il tuo codice ma ci sono molti problemi, puoi mettere un progetto semplice –

Problemi correlati