マップビューにMKTileOverlayを追加して、衛星とレーダーのアニメーションを作成するためにMapKitを使用しています。MKTileOverlayとPINCacheライブラリのiOS/MapKitキャッシュ管理の問題
UISliderとPlayButtonを使用して、MKOverlayRendererのアルファで再生してGIFのようなアニメーションを作成できました(スライダの位置に合わせて0または0.75に設定しました)。
アニメーションは非常に滑らかです。すべての衛星とレーダータイルがmapViewに正しくロードされています。
キャッシュ管理に関する問題が発生しました。
MapKitが私のtileOverlayにキャッシュを使用していないことに気がつきました。その理由は、タイルを保存するためにライブラリPINCacheを使用して、アニメーションを再生するたびにイメージをリクエストしてダウンロードしないようにしています。
私の実装:
私は私のタイル画像を得るために、私のURLを構築するために方法URLForTilePath
をオーバーライドします。
- (NSURL *)URLForTilePath:(MKTileOverlayPath)path{
double latMin, latMax, longMin, longMax;
path.contentScaleFactor = 1.0;
NSMutableArray *result = [[NSMutableArray alloc] init];
result = getBBoxForCoordinates((int)path.x, (int)path.y, (int)path.z);
longMin = [[result objectAtIndex:0] doubleValue];
latMin = [[result objectAtIndex:1] doubleValue];
longMax = [[result objectAtIndex:2] doubleValue];
latMax = [[result objectAtIndex:3] doubleValue];
NSString *finalURL = self.url;
finalURL = [finalURL stringByReplacingOccurrencesOfString:@"DATE"
withString:_date];
NSString *bbox = [NSString stringWithFormat:@"bbox=%f,%f,%f,%f", longMin, latMin, longMax, latMax];
finalURL = [finalURL stringByReplacingOccurrencesOfString:@"BBOX"
withString:bbox];
return [NSURL URLWithString:finalURL];
}
そしてURLForTilePath
を呼ぶ鍵方式は、loadTileAtPath
の私の実装です:
- (void)loadTileAtPath:(MKTileOverlayPath)path
result:(void (^)(NSData *data, NSError *error))result
{
if (!result)
{
return;
}
NSString *str = self.isRadar == true ? [NSString stringWithFormat:@"Radar%@", self.date] : [NSString stringWithFormat:@"Satellite%@", self.date];
NSData *cachedData = [[PINCache sharedCache] objectForKey:str];
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) {
NSString *str = self.isRadar == true ? [NSString stringWithFormat:@"Radar%@", self.date] : [NSString stringWithFormat:@"Satellite%@", self.date];
[[PINCache sharedCache] setObject:data forKey:str block:nil];
result(data, connectionError);
}];
}
}
基本的に私が達成しようとしているものです:
- チェック私は、データをキャッシュしている場合、そうならオブジェクトを取得します。
- そうでない場合は、
URLForTilePath
で指定されたURLのタイルをダウンロードするようにリクエストします。 - 次に、オブジェクトをキャッシュに設定します。
- 文字列
str
はキャッシュ管理のキーです - タイル、種類(レーダーやサテライト、別のイメージ、別のURL)と日付をソートして区別するために2つの重要な値があります。
キャッシュ管理が動作していることがわかります。オーバーレイは高速にレンダリングされますが、私が直面している主な問題は、座標に合わせてタイルをロードしてビルドしないことです。
私のmapViewは間違って作られた世界のパズルのようです。
私のコードでは、私が作った何か間違ったことを見ることができますか?