17

主にタイ向けに作成されているため、インターネット接続が難しいことが多いため、アプリのオフライン マップを作成する必要があります。OpenStreetMap現在、自分用に使用してMKTileOverlayいますが、オフラインで使用するために実装する際に問題があります。サブクラス化するというチュートリアルを見つけましたMKTileOverlay。だから、私ViewControllerが持っている地図がある場所には:

 - (void)viewWillAppear:(BOOL)animated {

    CLLocationCoordinate2D coord = {.latitude =  15.8700320, .longitude =  100.9925410};
    MKCoordinateSpan span = {.latitudeDelta =  3, .longitudeDelta =  3};
    MKCoordinateRegion region = {coord, span};
    [mapView setRegion:region];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Map";
    NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
    self.overlay = [[XXTileOverlay alloc] initWithURLTemplate:template];
    self.overlay.canReplaceMapContent = YES;
    [mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay {

    return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
}

のサブクラスにはMKTileOverlay、次のものがあります。

- (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;
    }
    NSData *cachedData = [self.cache objectForKey:[self URLForTilePath:path]];
    if (cachedData) {
        result(cachedData, nil);
    } else {
        NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
        [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            result(data, connectionError);
        }];
    }
}

問題は、サブクラスのコードをコメントアウトしない限り、何もロードされないことです。私はどこを台無しにしていますか?

4

2 に答える 2

1

キャッシュを作成していないようです。いつも空いてるの?

if (cachedData) {
    result(cachedData, nil);
} else {
    NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
    [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // Instantiate a new cache if we don't already have one.
        if (!self.cache) self.cache = [NSCache new];

        // Add the data into the cache so it's there for next time.
        if (data) {
            [self.cache setObject:data forKey:[self URLForTilePath:path]];
        }

        result(data, connectionError);
    }];
}

ここであなたの問題を解決すると思います。NSCache はディスクには保持されない (メモリにのみ保持される) ため、アプリがバックグラウンド化されても保持されますが、完全なオフライン機能 (おそらくコア データ) が必要な場合は、長期的にはより複雑なものが必要になることに注意してください。

于 2016-08-18T09:14:59.437 に答える
1

当社では、オフライン マッピングにMapBoxを使用することにしました。

そこでは、MapBox Studio を使用して独自のマップをデザインおよびスタイル設定し、マップを (選択した範囲のズーム レベルで) 外部ファイルにエクスポートできます。私たちのサイズは約40Mbです。

そこから、MapBox iOS SDKを使用してアプリに簡単に追加できます。

(免責事項:いいえ、私は彼らのために働いていません!私たちは、独自の陸/海の色とスタイルを定義する機能、およびXcodeプロジェクトにマップファイルを含めてオフラインで使用できる機能のために、それらを特に選択しました。)

OpenStreetMap 独自のマップをオフラインにする方法についての正確な質問に感謝しますが、これがお役に立てば幸いです。

于 2016-08-18T10:03:17.463 に答える