适用于iOS的离线MapKit解决scheme
快速问你。 我有一个应用程序,我正在这将需要使用地图,但不会有networking连接。 我曾经看到其他人也提过类似的问题,但是我的要求稍有不同,所以我想发一个新的问题。
这是我对应用程序的要求。
- 允许使用可定义的注释来捏放/缩放地图
- 地图必须离线可用
- 地图应限制在某个地理区域
- 应用程序不必通过苹果检查。 这是一个将作为信息亭的企业应用程序。
那么,有没有任何人可以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,支持离线地图