2016-12-01 11 views
2

mapView를 통해 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로 타일을 다운로드하라는 요청을합니다.
  • 그런 다음 개체를 캐시로 설정합니다.
  • 문자열 관리
  • 타일, 유형 (레이더 또는 위성, 다른 이미지, 다른 URL)과 날짜를 정렬하고 구분하기 위해 중요한 값이 2 개 있습니다.

캐시 관리가 작동하는 것을 볼 수 있습니다. 오버레이가 더 빨리 렌더링되지만 주된 문제는 해당 좌표에서 타일을로드 및 빌드하지 않는다는 것입니다.

내 mapView는 잘못 작성된 세계의 퍼즐과 같습니다.

내 코드 조각으로 내가 만든 잘못된 것을 볼 수 있습니까?

답변

0

mapKit과 관련된이 메모리/캐시 관리 문제의 이유를 찾을 수 없습니다.

Google지도를 사용하기로 결정 했으므로 구현하는 데 2 ​​시간 미만이 걸렸으며 그 결과는 놀랍습니다.

Apple 솔루션을 사용하여 Apple 커뮤니티를 존중하고 싶었지만 Google Map은 훨씬 더 많은 퍼포먼스를 제공했습니다.