2013-06-19 19 views
7

nella mia app Voglio utilizzare le mappe offline e con queste mappe utilizzare i file gpx per avere un percorso. Ho trovato openstreetmap per farlo, ma ci sono alcuni servizi migliori? (la soluzione migliore con curve di livello) grazieIOS: utilizzare le mappe offline

+0

http://www.mapbox.com? – Wain

risposta

9

Le mappe offline richiedono un po 'di esperienza in iOS poiché non ci sono molti progetti ed esempi là fuori. Tuttavia, hai un progetto chiamato Route-Me che potrebbe darti un punto di partenza. Lo abbiamo usato per sviluppare Metro Valencia Offline che è riuscito ad arrivare all'App Store. Ho scritto un small tutorial su come aggiungere Route-Me al progetto.

Fondamentalmente è possibile utilizzare qualsiasi feed di mappe che si possa desiderare (OpenStreetMaps è uno di questi e anche quello che abbiamo utilizzato). Quello che dovrete fare è:

  1. Scarica le tessere mappa (https://metacpan.org/pod/Geo::OSM::Tiles)
  2. metterli in un database SQLite (http://shikii.net/blog/downloads/map2sqlite-bin.zip)
  3. Modifica Route-Me per le piastrelle da alimentare dal database anziché dal sito OpenStreetMaps
+0

puoi spiegarmi questa eccezione? "SimpleMap [1020: 907] *** Termine dell'app a causa di eccezione non rilevata 'NSInternalInconsistencyException', motivo: 'Grafica e memoria sono eccessivamente tassate se [contenuti minZoom] è più di 1.5 più piccoli di [tileSource minZoom]'" – CrazyDev

+3

Che è in realtà un NSAssert lanciato da Route-Me che non ho mai compreso appieno. Ho commentato e non ho mai avuto alcun problema. L'NSAssert può essere trovato su 'RMMapContents.m' all'interno del metodo' setTileSource: 'PS. Ce n'è un altro in 'setMinZoom:' ma ho lasciato quest'ultimo così com'è. –

+0

wow fantastico, ora funziona !! grazie ... posso scrivere qui se ho altre domande? – CrazyDev

1

C'è anche SDK Nutiteq Maps: http://developer.nutiteq.com, mappe offline per iOS e Android, supporta Xamarin IDE (C#) e lingue native (Java, ObjectiveC, Swift). Non è tanto routing e navigazione (come ad esempio Skobbler), ma più focalizzato su mappe complesse con livelli interattivi (punti, linee e poligoni in cima alle mappe). Un vantaggio è che è possibile utilizzare le proprie origini di mappe di base (interne, di terze parti), non solo OpenStreetMap, che fornisce l'SDK stesso.

Disclaimer: Sono uno sviluppatore.

0

Ho usato la mappa predefinita di MapKit e una sottoclasse di MKTileOverlay per poter salvare le piastrelle 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. (cache Simulator è in Utenti/TE/Library/Developer/CoreSimulator/Devices/... e la biblioteca è una directory nascosta)

Dopo aver memorizzato nella cache tutto ciò che serve appena messo in bundle della tua app (proprio come un qualsiasi altra immagine, se vuoi dalla mappa nella cache della casella). e informare il

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

per ottenere piastrelle da pacco.

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

Problemi correlati