适用于iOS的离线MapKit解决scheme

快速问你。 我有一个应用程序,我正在这将需要使用地图,但不会有networking连接。 我曾经看到其他人也提过类似的问题,但是我的要求稍有不同,所以我想发一个新的问题。

这是我对应用程序的要求。

  1. 允许使用可定义的注释来捏放/缩放地图
  2. 地图必须离线可用
  3. 地图应限制在某个地理区域
  4. 应用程序不必通过苹果检查。 这是一个将作为信息亭的企业应用程序。

那么,有没有任何人可以build议caching地图块的框架或方法?

感谢您提前出去。

我使用MapKit的默认地图和MKTileOverlay的一个子类来保存已下载的图块,并返回已经caching的图块而不下载它们。

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(fileName)来知道从哪里获取所需的所有图块。 (模拟器caching在Users / YOU / Library / Developer / CoreSimulator / Devices / …而Library是一个隐藏的目录)

caching所有你需要的只是放在你的应用程序包(就像任何其他图像,如果你想从框caching的地图)。 并告诉你的

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

从包中获取拼贴。

所以,现在我可以安装我的应用程序,closuresWi-Fi,我会得到这些地图。

尝试使用http://mapbox.com/ ,它具有iOS SDK和应用程序来构build离线地图。

查看Google地图服务条款 10.3节,您会发现您不允许存储任何Google地图内容。 这意味着您将不仅需要提供自己的地图,而且还需要replace方便的MapKitfunction。 据我所知,你根本无法使用MapKit进行离线应用程序。

不幸的是MapKit框架不支持离线地图访问。 您应该更喜欢MapBox iOS SDK(MapBox iOS SDK是一个工具集,用于构build支持离线caching策略,缩放限制,视网膜显示行为,起始坐标和地图视图拖动减速等的地图应用程序….

find示例链接

快乐的编码

请参阅skobbler / Telenav SDK – 它基于OpenStreetMap,并且是对mapkit(地图渲染,路由和转弯导航)的集成支持(几乎)全面replace,支持离线地图