-3

Google マップの kml ファイルで作成したマップを読み込もうとしています。Google マップ リンク。これは一例にすぎないと言わざるを得ませんが、同じ原理です。

最も簡単な方法は WebView を読み込むことですが、それは私の目には醜いです。

私の質問を読んでくれてありがとう!

よろしくお願いしますCTS

4

1 に答える 1

4

にロードするKMLにはMKMapView

  1. 必要なフレームワーク(MapKit.frameworkおよびCoreLocation.framework)をターゲットに追加します。

  2. KMLを読み込んで解析します。

  3. KMLに基づいて注釈を作成します。と

  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私が作成したサブクラスであり、itemsの出現ごとに1つの配列を作成し、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は、それを行うための簡単なルーチンを作成しました。

- (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);
}
于 2013-01-28T14:39:26.997 に答える