尝试在MKMapView中加载创建的Map

时间:2013-01-28 13:02:55

标签: ios google-maps mkmapview mapkit

我正在尝试加载我在Google-Maps中使用kml文件创建的地图。 The Google Maps Link.我不得不说这只是一个例子,但原则是一样的。

最简单的方法是加载WebView,但这在我看来很难看。

感谢您阅读我的问题!

最好的问候CTS

1 个答案:

答案 0 :(得分:4)

KML加载到MKMapView

  1. Add the necessary frameworksMapKit.frameworkCoreLocation.framework)到您的目标;

  2. 加载并解析KML;

  3. 根据KML创建注释;以及

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

  5. 因此,这可能看起来像:

    #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子类,每次出现items时会创建一个rowElementName数组,对于每一行,它将获取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 wrote a simple routine要做到这一点:

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