2012-05-09 27 views
11

Câu hỏi nhanh cho bạn. Tôi có một ứng dụng mà tôi đang làm việc trên đó sẽ yêu cầu sử dụng bản đồ, nhưng sẽ không có kết nối mạng. Tôi đã thấy những người khác hỏi những câu hỏi tương tự về điều này, nhưng yêu cầu của tôi hơi khác một chút, vì vậy tôi muốn đăng một câu hỏi mới.Giải pháp MapKit ngoại tuyến dành cho iOS

Dưới đây là các yêu cầu của tôi đối với ứng dụng.

  1. phép nhúm/zoom của một bản đồ với các chú thích định nghĩa
  2. Bản đồ phải có sẵn ẩn
  3. Bản đồ nên được giới hạn trong một khu vực địa lý nhất định
  4. App không phải vượt qua kiểm tra của Apple. Đây là một ứng dụng doanh nghiệp sẽ hoạt động như một kiốt.

Vì vậy, có bất kỳ khung hoặc phương pháp lưu vào bộ nhớ đệm bản đồ mà bất kỳ ai cũng có thể đề xuất không?

Cảm ơn bạn đã đi trước.

+0

Tôi e rằng Caleb đúng. Ngay cả khi bạn bằng cách nào đó có thể lưu trữ dữ liệu bản đồ - bạn sẽ không sử dụng thuật ngữ đó. –

Trả lời

1

Kiểm tra mục 10.3 của Google Maps Terms of Service và bạn sẽ thấy rằng bạn không được phép lưu trữ bất kỳ nội dung nào của Google Maps. Điều đó có nghĩa là bạn sẽ cần cung cấp không chỉ bản đồ của riêng bạn mà còn thay thế chức năng MapKit tiện dụng. Bạn thực sự không thể sử dụng MapKit cho tất cả các ứng dụng ngoại tuyến, theo như tôi có thể nói.

3

Hãy thử sử dụng http://mapbox.com/ có cả iOS SDK và ứng dụng để tạo bản đồ ngoại tuyến.

+1

Bất kỳ giải pháp miễn phí nào? – BoilingLime

1

Thật không may MapKit Framework không hỗ trợ Truy cập bản đồ ngoại tuyến. Nếu bạn thích MapBox iOS SDK (MapBox iOS SDK là một bộ công cụ để xây dựng bản đồ các ứng dụng có hỗ trợ chính sách bộ nhớ đệm ẩn, giới hạn phóng to, hành vi hiển thị võng mạc, bắt đầu phối hợp, và xem bản đồ kéo giảm tốc độ vv ....

Find the example link

Chúc mừng Mã hóa

1

Xem skobbler/Telenav SDK - nó dựa trên OpenStreetMap và là một (gần như) hoàn toàn ngăn xếp thay thế để mapkit (bản đồ vẽ, định tuyến & lần lượt bởi navigation lượt) với sự hỗ trợ tích hợp cho đồ ngoại tuyến

9

Tôi đã sử dụng bản đồ mặc định từ MapKit và một lớp con của MKTileOverlay để có thể lưu các ô đã tải xuống và trả lại các ô đã được lưu vào bộ nhớ cache mà không cần tải xuống chúng.

1) Thay đổi nguồn cho bản đồ mặc định của bạn từ MapKit và sử dụng một lớp con của MKTileOverlay (sử dụng "mở bản đồ đường phố" ở đây)

- (void)viewDidLoad{ 
    [super viewDidLoad]; 
    static NSString * const template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png"; 

    VHTileOverlay *overlay = [[VHTileOverlay alloc] initWithURLTemplate:template]; 
    overlay.canReplaceMapContent = YES; 
    [self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels]; 
} 

2) lớp con từ MKTileOverlay

@interface VHTileOverlay() // MKTileOverlay subclass 
@property (nonatomic, strong) NSOperationQueue *operationQueue; 
@end 

@implementation VHTileOverlay 

-(instancetype)initWithURLTemplate:(NSString *)URLTemplate{ 

    self = [super initWithURLTemplate:URLTemplate]; 
    if(self){ 
     self.directoryPath = cachePath; 
     self.operationQueue = [NSOperationQueue new]; 
    } 
    return self; 
} 


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

    NSString *pathToFilfe = [[self URLForTilePath:path] absoluteString]; 
    pathToFilfe = [pathToFilfe stringByReplacingOccurrencesOfString:@"/" withString:@"|"]; 
    // @"/" - those are not approriate for file's url... 

    NSData *cachedData = [self loadFileWithName:pathToFilfe]; 
    if (cachedData) { 
     result(cachedData, nil); 
    } else { 
     NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]]; 
     __block VHTileOverlay *weakSelf = self; 
     [NSURLConnection sendAsynchronousRequest:request 
              queue:self.operationQueue 
           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
            NSLog(@"%@",[weakSelf URLForTilePath:path]); 

            if(data){ 
             [self saveFileWithName:[[weakSelf URLForTilePath:path] absoluteString] imageData:data]; 
            } 
            result(data, connectionError); 
     }]; 
    } 
} 

-(NSString *)pathToImageWithName:(NSString *)fileName 
{ 
    NSString *imageFilePath = [[OfflineMapCache sharedObject].cachePath stringByAppendingPathComponent:fileName]; 
    return imageFilePath; 
} 

- (NSData *)loadFileWithName:(NSString *)fileName 
{ 
    NSString *imagePath = [self pathToImageWithName:fileName]; 
    NSData *data = [[NSData alloc] initWithContentsOfFile:imagePath]; 
    return data; 
} 

- (void)saveFileWithName:(NSString *)fileName imageData:(NSData *)imageData 
{ 
// fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"|"]; 
// NSString *imagePath = [self pathToImageWithName:fileName]; 
// [imageData writeToFile:imagePath atomically:YES]; 
} 

Bỏ ghi chú " saveFileWithName "và chạy nó trên trình mô phỏng. Bạn cũng có thể thêm NSLog (tên tệp) để biết nơi cần lấy tất cả các ô mà bạn cần. (Bộ nhớ cache giả lập nằm trong Users/YOU/Library/Developer/CoreSimulator/Devices/... Và Thư viện là một thư mục ẩn)

Sau khi lưu trữ tất cả những gì bạn cần chỉ cần đưa vào gói ứng dụng của bạn (giống như bất kỳ hình ảnh nào khác , nếu bạn muốn từ bản đồ lưu trong hộp).Và thông báo cho bạn

- (void)loadTileAtPath:(MKTileOverlayPath)path 
       result:(void (^)(NSData *data, NSError *error))result 

để nhận các lát từ gói.

Vì vậy, bây giờ tôi có thể cài đặt ứng dụng của mình, tắt wi-fi và tôi sẽ vẫn nhận những bản đồ đó.

+0

Tôi đã cố gắng sử dụng mã của bạn nhưng có nhiều vấn đề, bạn có thể đặt một dự án đơn giản không –

Các vấn đề liên quan