2016-08-09 2 views
17

인터넷 연결이 자주 어려워지는 태국을 주로 대상으로하므로 내 앱의 오프라인지도를해야 할 필요가 있습니다. 지금 MKTileOverlay에 대해 OpenStreetMap을 사용하고 있지만 오프라인으로 사용하기 위해 구현하는 데 문제가 있습니다. MKTileOverlay 하위 클래스라는 튜토리얼을 발견했습니다. 그래서, 내 ViewController지도는 어디 있습니다지도의 오프라인 캐시

MKTileOverlay의 내 서브 클래스에서
- (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]; 
} 

, 내가 가진 : 나는 주석 않는

- (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); 
     }]; 
    } 
} 

문제는, 아무것도 전혀로드되지 가져옵니다이다 서브 클래스의 코드. 내가 어디에서 엉망 이냐?

+0

어디에서 loadTileAtPath 메서드를 호출합니까? – ldindu

+0

나는 경로를 요구하고 그것을 얻는 방법을 모르기 때문에 그것을 부르는 방법을 확신 할 수 없기 때문에 나는 그것을 부르지 않을 것이다. @ldindu – user717452

+0

@ldindu지도가 처음으로로드되는 경로를 어떻게 전달합니까? 정상적인 initWithUrlTemplate을 사용하면 방금 발생하지만이 설정으로 단서가 없습니다. – user717452

답변

1

저희 회사에서는 오프라인 매핑을 위해 MapBox을 사용하기로했습니다.

MapBox Studio를 사용하여지도를 디자인하고 스타일을 지정한 다음 선택한 범위의 확대/축소 수준에서지도를 외부 파일로 내보낼 수 있습니다. 우리의 크기는 약 40Mb입니다.

거기에서 MapBox iOS SDK을 사용하여 쉽게 앱에 추가 할 수 있습니다.

(면책 조항 : 아니오, 우리는 작동하지 않습니다! 우리는 우리 자신의 육지/해채 색 및 스타일을 정의 할 수있는 능력과 Xcode 프로젝트에 맵 파일을 포함시킬 수있는 능력을 특별히 선택했습니다. 오프라인에서 사용할 수 있습니다.)

정확한 질문은 OpenStreetMap의 자체지도를 오프라인으로 만드는 방법 이었지만 감사합니다. 유용하다고 생각합니다.

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는 디스크에만 머물러 있지 않으므로 (메모리에만 적용됨) 앱이 백그라운드에서 살아남을 때까지는 전체 오프라인 기능 (Core Data)을 원한다면 장기적으로 더 복잡한 것이 필요합니다.

관련 문제