8

在我的应用程序中,我想使用离线地图,并使用此地图使用 gpx 文件来获得路线。我找到了 openstreetmap 来做这件事,但是有更好的服务吗?(水平曲线的最佳解决方案)谢谢

4

4 回答 4

11

离线地图需要一点 iOS 经验,因为那里没有很多项目和示例。但是,您有一个名为Route-Me 的项目,它可以为您提供一个起点。我们用它来开发Metro Valencia Offline并成功进入 App Store。我写了一个关于如何将 Route-Me 添加到项目中的小教程。

基本上你可以使用任何你想要的地图提要(OpenStreetMaps 是其中之一,也是我们使用的)。你需要做的是:

  1. 下载地图图块 ( https://metacpan.org/pod/Geo::OSM::Tiles )
  2. 将它们放入 SQLite 数据库 ( http://shikii.net/blog/downloads/map2sqlite-bin.zip )
  3. 修改 Route-Me 以从数据库而不是从 OpenStreetMaps 网站提供瓷砖
于 2013-06-19T11:59:33.207 回答
2

您还可以测试:skobbler's/Telenav:http: //developer.skobbler.com/support#download它基于 OpenStreetMap,并且具有完整的离线功能(GPX 跟踪导航、地图渲染、路由和重新路由)

于 2014-09-30T13:00:56.210 回答
1

还有 Nutiteq Maps SDK: http: //developer.nutiteq.com,适用于 iOS 和 Android 的离线地图,支持 Xamarin IDE (C#) 和原生语言(Java、ObjectiveC、Swift)。与其说是路由和导航(例如 Skobbler),不如说是针对具有交互层的复杂地图(地图顶部的点、线和多边形)。一个优点是您可以使用自己的基本地图源(内部、第 3 方),而不仅仅是 SDK 本身提供的 OpenStreetMap。

免责声明:我是它的开发者。

于 2015-04-02T06:34:14.540 回答
1

我使用 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(fileName) 以了解从何处获取所需的所有图块。(模拟器缓存在Users/YOU/Library/Developer/CoreSimulator/Devices/...而Library是一个隐藏目录)

缓存所有内容后,您只需将其放入应用程序的包中(就像任何其他图像一样,如果您想从盒子缓存地图中获取)。并告诉你

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

从捆绑中获取瓷砖。

所以现在我可以安装我的应用程序,关闭 wi-fi,无论如何我都会得到这些地图。

于 2015-08-27T08:56:16.937 回答