【问题标题】:ios kmlviewer load remote url instead of local fileios kmlviewer 加载远程 url 而不是本地文件
【发布时间】:2012-12-11 19:17:49
【问题描述】:

我使用的是 Apple 的 kmlviewer 示例,但它从本地目录中获取 kml 文件。我想要做的是使用 url 远程调用该文件。

这是来自 Apple 的原始代码:

NSString *path = [[NSBundle mainBundle] pathForResource:@"KML_Sample" ofType:@"kml"];
NSURL *url = [NSURL fileURLWithPath:path];
kmlParser = [[KMLParser alloc] initWithURL:url];
[kmlParser parseKML];

如何调用位于 url 中的远程文件为:http://www.domain.com/route.kml

最好的问候。

【问题讨论】:

    标签: ios nsstring mkmapview


    【解决方案1】:

    我在 KMLParser 中添加了一个 Initializer 来使用 NSData:

    在 KMLParser.h 文件中,添加:

    -(id) initWithData: (NSData *) data;
    

    在 KMLParser.m 文件中添加:

    -(id) initWithData: (NSData *)data
    {
        if (self = [super init]) {
            _styles = [[NSMutableDictionary alloc] init];
            _placemarks = [[NSMutableArray alloc] init];
            _xmlParser = [[NSXMLParser alloc] initWithData:data];
    
            [_xmlParser setDelegate:self];
        }
        return self;
    }
    

    【讨论】:

      【解决方案2】:

      MapViewController.h

          .....
          NSMutableData   *webData;
          KMLParser       *kml;
          .....
          @property (nonatomic, retain) NSMutableData   *webData;
      

      MapViewController.m

      - (IBAction)showKmlData:(id)sender  //Let's say you want to download kml data with a button tap, you create a method for that (you may not act like this, but the content is the same):
      {
          NSURL *path = [NSURL URLWithString:@"http://www.domain.com/route.kml"];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL:path];
          NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      
          [connection release];
          [request release];
      }
      
      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
      {
         self.webData =[NSMutableData data];
      }
      
      
      -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
      {   
          [webData appendData:data];
      }
      
      -(void)connectionDidFinishLoading:(NSURLConnection *)connection
      {
          NSString *fileName = [[[NSURL URLWithString:kmlStr] path] lastPathComponent];
          //NSString *fileName = @"route.kml"; 
          NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
          NSString *folder = [pathArr objectAtIndex:0];
      
          NSString *filePath = [folder stringByAppendingPathComponent:fileName];
          NSURL *fileURL = [NSURL fileURLWithPath:filePath];  
          NSError *writeError = nil;
      
          [webData writeToURL: fileURL options:0 error:&writeError];
      
          if( writeError) {
              NSLog(@" Error in writing file %@' : \n %@ ", filePath , writeError );
              return;
          }
      
          kml = [[KMLParser parseKMLAtPath:filePath] retain];
      
          NSArray *annotations = [kml points];
      
          if ([[mapview overlays] count] == 0) {
              [mapview addAnnotations:annotations];
      
              NSArray *overlays = [kml overlays];
              [mapview addOverlays:overlays];
              MKMapRect flyTo = MKMapRectNull;
      
              for (id <MKOverlay> overlay in overlays) {
                  if (MKMapRectIsNull(flyTo)) {
                      flyTo = [overlay boundingMapRect];
                  } else {
                      flyTo = MKMapRectUnion(flyTo, [overlay boundingMapRect]);
                  }
              }
      
              for (id <MKAnnotation> annotation in annotations) {
                  MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
                  MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
                  if (MKMapRectIsNull(flyTo)) {
                      flyTo = pointRect;
                  } else {
                      flyTo = MKMapRectUnion(flyTo, pointRect);
                  }
              }
      
              mapview.visibleMapRect = flyTo;
          }
      
          [mapview addAnnotations:annotations];
          NSArray *overlays = [kml overlays];
          [mapview addOverlays:overlays];
      }
      
      -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
      {
          UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!" message:@"An error has occured." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
          [alert show];
          [alert release];
      }
      

      【讨论】:

      • 别忘了您需要将&lt;NSURLConnectionDataDelegate&gt; 添加到 .h 文件(适用于 iOS 5+)。
      【解决方案3】:

      我会下载文件并将其保存在本地文档或临时目录中。基本步骤是:

      • 用你想要的 URL 创建一个 NSURLRequest
      • 使用该 NSURLRequest 创建一个 NSURLConnection
      • 创建一个 NSMutableData 成员变量来存储从 NSURLConnection 接收到的数据。
      • 实现 NSURLConnection 委托的方法:
        • connection:didReceiveResponse(确保成功,即 http 200)
        • connection:didReceiveData(将接收到的数据附加到您的 NSMutableData 变量中)
        • connection:didFailWithError(处理错误)
        • connectionDidFinishLoading(现在收到所有数据,将其写入本地文件)

      请参阅 Apple 提供的这个非常有用的示例项目,其中展示了如何按照我上面概述的步骤下载文件并将其保存在本地: http://developer.apple.com/library/ios/#samplecode/URLCache/Introduction/Intro.html

      这里的 Apple 文档中也有一个很好的分步指南: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html

      然后,一旦您在本地拥有文件,使用 KMLParser 使用指向您将文件保存到的任何位置的 URL 打开将是微不足道的。

      【讨论】:

      • 虽然文档非常详细,但对于 iOS 5+,它应该是 NSURLConnectionDataDelegate,而不是 NSURLConnectionDelegate(如 iOS 4.3 to iOS 5.0 API Differences 中的模糊描述)。
      【解决方案4】:

      没有NSURLRequestNSURLConnection 很简单:

      NSURL *url = [NSURL URLWithString:@"http://www.domain.com/route.kml"];
      kmlParser = [[KMLParser parseKMLAsURL:url] retain];
      
      NSArray *overlays = [kmlParser overlays];
      [mapView addOverlays:overlays];
      

      等等。用于注释。

      至于parseKMLAtURL,它在Apple SDK的KMLViewer的另一个版本(1.1)中实现为:

      + (KMLParser)parseKMLAtURL:(NSURL *)url
      {
          NSXMLParser *xml = [[NSXMLParser alloc] initWithContentsOfURL:url];
          KMLParser *parser = [[KMLParser alloc] init];
          [xmlParser setDelegate:parser];
          [xml parse];
          [parser _assignStyles];
          return [parser autorelease];
      }
      

      【讨论】:

      • 这种方法的缺点是initWithContentsOfURL: 是一个同步操作,这意味着只要它运行,UI 就不会响应(如this SO answer 中所述)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 2021-11-22
      • 2011-08-12
      相关资源
      最近更新 更多