2012-05-09 2 views
11

Быстрый вопрос для вас. У меня есть приложение, над которым я работаю, это потребует использования карт, но не будет сетевого подключения. Я видел, как другие задавали подобные вопросы по этому поводу, но мои требования немного разные, поэтому я хотел опубликовать новый вопрос.Оффлайн MapKit решение для iOS

Вот мои требования к приложению.

  1. Разрешить щепотку/зум карты с задаваемыми аннотациями
  2. Карта должна быть доступна в автономном режиме
  3. Карта должна быть ограничена определенной географической области
  4. App не должны пройти проверку компании Apple. Это корпоративное приложение, которое будет служить киоском.

Итак, есть ли какой-либо каркас или метод кеширования плиток, которые могут предложить любой?

Спасибо за участие.

+0

Я боюсь, что Калеб прав. Даже если вы можете каким-то образом кэшировать данные карты - вы не будете использовать ее. –

ответ

1

Проверьте раздел 10.3 раздела Google Maps Terms of Service, и вы обнаружите, что вам запрещено хранить содержимое Google Карт. Это означает, что вам необходимо предоставить не только собственную карту, но и заменить удобные функциональные возможности MapKit. Насколько мне известно, вы действительно не можете использовать MapKit для автономных приложений.

3

Попробуйте использовать http://mapbox.com/, который имеет как SDK iOS, так и приложение для построения автономных карт.

+1

Любые бесплатные решения? – BoilingLime

1

К сожалению MapKit Framework не поддерживает автономный доступ к карте. Вы должны предпочесть MapBox IOS SDK (MapBox IOS SDK представляет собой набор инструментов для создания карт приложений, которые поддерживают автономную политику кэширования, масштабированию ограничения, сетчатку поведения дисплея, начиная с координатами, и посмотреть на карту перетаскивания замедления и т.д ....

Find the example link

Счастливый Coding

1

Смотрите skobbler/Telenav SDK - он основан на OpenStreetMap и является (почти) полной замены стека на MapKit (карта рендеринга, маршрутизации & поворота к повороту навигации) со встроенной поддержкой автономных карт

9

Я использовал карту по умолчанию из MapKit и подкласс MKTileOverlay, чтобы иметь возможность сохранять загруженные фрагменты и возвращать уже кэшированные фрагменты, не загружая их.

1) Изменить источник для вашей карты по умолчанию от MapKit и использовать подкласс MKTileOverlay (используется "открытая карта улиц" здесь)

- (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) подкласс от 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]; 
} 

раскомментировать " saveFileWithName "и запустить его на симуляторе. Вы также можете добавить NSLog (имя_файла), чтобы узнать, где получить все необходимые вам плитки. (Кэш симулятора находится в разделе «Пользователи/YOU/Библиотека/Разработчик/CoreSimulator/Devices/... И библиотека - скрытая директория)

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

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

, чтобы получить плитки из пачки.

Итак, теперь я могу установить приложение, отключить Wi-Fi, и все равно получаю эти карты.

+0

Я пытался использовать ваш код, но есть много проблем, можете ли вы поставить простой проект –

Смежные вопросы