2016-12-01 12 views
2

マップビューに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は間違って作られた世界のパズルのようです。

私のコードでは、私が作った何か間違ったことを見ることができますか?

答えて

0

mapKitでこのメモリ/キャッシュ管理の問題が発生する理由が見つかりませんでした。

私はGoogleMapを試してみることに決めました。実装に2時間もかかりませんでしたが、結果は素晴らしいです。

アップルのソリューションを使用してアップルのコミュニティを尊敬したいと思っていましたが、Googleマップではもっと多くのパフォーマンスが提供されました。