尝试在MKMapView中加载创build的地图

我试图加载我在Google-Maps中使用kml文件创build的地图。 Google地图链接。 我不得不说这只是一个例子,但它是一样的原则。

最简单的方法是加载一个WebView,但这在我眼中是丑陋的。

感谢您阅读我的问题!

最好的问候CTS

KML加载到MKMapView

  1. 将必要的框架 ( MapKit.frameworkCoreLocation.framework )添加到您的目标;

  2. 加载和parsingKML;

  3. 在KML的基础上创build您的注释; 和

  4. 设置您的地图region以包含注释。

因此,这可能看起来像:

 #import <MapKit/MapKit.h> - (void)loadKml:(NSURL *)url { // parse the kml Parser *parser = [[Parser alloc] initWithContentsOfURL:url]; parser.rowElementName = @"Placemark"; parser.elementNames = @[@"name", @"Snippet", @"coordinates", @"description"]; parser.attributeNames = nil; [parser parse]; // add annotations for each of the entries for (NSDictionary *locationDetails in parser.items) { MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; annotation.title = locationDetails[@"name"]; annotation.subtitle = locationDetails[@"Snippet"]; NSArray *coordinates = [locationDetails[@"coordinates"] componentsSeparatedByString:@","]; annotation.coordinate = CLLocationCoordinate2DMake([coordinates[1] floatValue], [coordinates[0] floatValue]); [self.mapView addAnnotation:annotation]; } // update the map to focus on the region that encompasses all of your annotations MKCoordinateRegion region; if ([self.mapView.annotations count] > 1) { region = [self regionForAnnotations:self.mapView.annotations]; region = MKCoordinateRegionMake(region.center, MKCoordinateSpanMake(region.span.latitudeDelta * 1.05, region.span.longitudeDelta * 1.05)); // expand the region by 5% } else { id<MKAnnotation> annotation = self.mapView.annotations[0]; region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 100.0, 100.0); } [self.mapView setRegion:region animated:YES]; } 

我的Parser类只是我写的一个NSXMLParser子类,它将在每次出现rowElementName时创build一个items数组,并且对于每一行,它将获取elementNames数组中列出的元素。

Parser.h:

 #import <Foundation/Foundation.h> @interface Parser : NSXMLParser @property (nonatomic, strong) NSString *rowElementName; // this is the element name that identifies a new row of data in the XML @property (nonatomic, strong) NSArray *attributeNames; // this is the array of attributes we might want to retrieve for that element name @property (nonatomic, strong) NSArray *elementNames; // this is the list of sub element names for which we're retrieving values @property (nonatomic, strong) NSMutableArray *items; // after parsing, this is the array of parsed items @end 

Parser.m:

 #import "Parser.h" @interface Parser () <NSXMLParserDelegate> @property (nonatomic, strong) NSMutableDictionary *item; // while parsing, this is the item currently being parsed @property (nonatomic, strong) NSMutableString *elementValue; // this is the element within that item being parsed @end @implementation Parser - (id)initWithContentsOfURL:(NSURL *)url { self = [super initWithContentsOfURL:url]; if (self) { self.delegate = self; } return self; } - (id)initWithData:(NSData *)data { self = [super initWithData:data]; if (self) { self.delegate = self; } return self; } - (id)initWithStream:(NSInputStream *)stream { self = [super initWithStream:stream]; if (self) { self.delegate = self; } return self; } #pragma mark - NSXMLParserDelegate methods - (void)parserDidStartDocument:(NSXMLParser *)parser { self.items = [[NSMutableArray alloc] init]; if (!self.rowElementName) NSLog(@"%s Warning: Failed to specify row identifier element name", __FUNCTION__); } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:self.rowElementName]) { self.item = [[NSMutableDictionary alloc] init]; for (NSString *attributeName in self.attributeNames) { id attributeValue = [attributeDict valueForKey:attributeName]; if (attributeValue) [self.item setObject:attributeValue forKey:attributeName]; } } else if ([self.elementNames containsObject:elementName]) { self.elementValue = [[NSMutableString alloc] init]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if (self.elementValue) { [self.elementValue appendString:string]; } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:self.rowElementName]) { [self.items addObject:self.item]; self.item = nil; } else if ([self.elementNames containsObject:elementName]) { [self.item setValue:self.elementValue forKey:elementName]; self.elementValue = nil; } } @end 

最后,我的loadKml使用的唯一的其他实用程序方法是regionForAnnotations ,它根据一系列注释来定义一个区域。 Rob Mooney写了一个简单的例程来做到这一点:

 - (MKCoordinateRegion)regionForAnnotations:(NSArray *)annotations { CLLocationDegrees minLat = 90.0; CLLocationDegrees maxLat = -90.0; CLLocationDegrees minLon = 180.0; CLLocationDegrees maxLon = -180.0; for (id <MKAnnotation> annotation in annotations) { if (annotation.coordinate.latitude < minLat) { minLat = annotation.coordinate.latitude; } if (annotation.coordinate.longitude < minLon) { minLon = annotation.coordinate.longitude; } if (annotation.coordinate.latitude > maxLat) { maxLat = annotation.coordinate.latitude; } if (annotation.coordinate.longitude > maxLon) { maxLon = annotation.coordinate.longitude; } } MKCoordinateSpan span = MKCoordinateSpanMake(maxLat - minLat, maxLon - minLon); CLLocationCoordinate2D center = CLLocationCoordinate2DMake((maxLat - span.latitudeDelta / 2), maxLon - span.longitudeDelta / 2); return MKCoordinateRegionMake(center, span); }