2

こんにちはMKTileOverlay、OpenStreetMap のタイルを に表示するために使用していiOS7 Appます。これらのタイルをキャッシュする機能を実装したいと思います。NSHipster ( http://nshipster.com/mktileoverlay-mkmapsnapshotter-mkdirections/ ) の投稿を見て、それに応じて実行しました。

これは私の MKTileOverlay サブクラスです。

#import "DETileOverlay.h"

@implementation DETileOverlay

- (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:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
             result(data, connectionError);
         }];
    }
}

@end

次に、次のように使用します。

#import "DETileOverlay.h"

@interface DEMapViewController : UIViewController <MKMapViewDelegate> {
}
@property (nonatomic, retain) DETileOverlay *overlay;

-(void)viewDidLoad {
[super viewDidLoad];
    self.overlay = [[DETileOverlay alloc] initWithURLTemplate:@"http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"];
        self.overlay.canReplaceMapContent = YES;
        self.overlay.mapView = map;
        [map addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}

// iOS 7
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)ovl
    {
   MKTileOverlayRenderer *renderer = [[MKTileOverlayRenderer alloc]initWithOverlay:ovl];

        return renderer;
    }


    - (void)          mapView:(MKMapView *)mapView
        didUpdateUserLocation:(MKUserLocation *)userLocation
    {
        MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 300, 300);

        [map setRegion:region animated:YES];
    }

アプリを起動すると、タイルが読み込まれません。サブクラスで loadTileAtPath をオーバーライドしなければ、すべて正常に動作します。私は何を間違っていますか?

本当にありがとう。

4

2 に答える 2

2

コメントに基づいて解決したと言っていますが、コードに基づいてタイルをキャッシュに追加することはありません。それがなければ、キャッシュを取得できず、常にタイルを要求することになると思います。したがって、completionHandler では、結果のタイルを次のようにキャッシュに追加する必要があります。

....
} else { 
    NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
    [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        // Should inspect the response to see if the request completed successfully!!
        [self.cache setObject:data forKey:[self URLForTilePath:path]];
        result(data, connectionError);
    }];
}
于 2014-07-22T17:29:42.910 に答える