Автономное решение MapKit для iOS

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

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

Allow pinch/zoom of a map with definable annotations Map must be available offline Map should be restricted to a certain geo area App does not have to pass Apple inspection. This is an enterprise app that will serve as a kiosk.

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

Спасибо, выходи заранее.

 Rok Jarc10 мая 2012 г., 03:49
Боюсь, Калеб прав. Даже если бы вы могли каким-то образом кэшировать данные карты - вы бы не согласились с этим.

Ответы на вопрос(5)

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

Найти пример ссылки

Счастливое Кодирование

 02 авг. 2018 г., 13:15
спасибо, но у меня есть вопрос:is it free?

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

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

 06 дек. 2014 г., 20:09
Есть бесплатные решения?

чтобы иметь возможность сохранять загруженные плитки и возвращать уже кэшированные плитки без их загрузки.

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

Раскомментируйте & quot; saveFileWithName & quot; и запустить его на симуляторе. Вы также можете добавить NSLog (fileName), чтобы узнать, где взять все нужные вам плитки. (Кэш симулятора находится в Users / YOU / Library / Developer / CoreSimulator / Devices / ... А Library - это скрытый каталог)

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

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

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

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

 04 сент. 2017 г., 18:56
Я пытался использовать ваш код, но есть много проблем, вы можете поставить простой проект
 02 авг. 2018 г., 16:48
Можете ли вы предложить простой проект? Спасибо вам

Условия использования Google Maps и вы обнаружите, что вам не разрешено хранить какой-либо контент Google Карт. Это означает, что вам необходимо предоставить не только свою собственную карту, но и заменить удобную функциональность MapKit. Насколько я могу судить, вы действительно не можете использовать MapKit для автономных приложений.

Ваш ответ на вопрос