Google マップの kml ファイルで作成したマップを読み込もうとしています。Google マップ リンク。これは一例にすぎないと言わざるを得ませんが、同じ原理です。
最も簡単な方法は WebView を読み込むことですが、それは私の目には醜いです。
私の質問を読んでくれてありがとう!
よろしくお願いしますCTS
Google マップの kml ファイルで作成したマップを読み込もうとしています。Google マップ リンク。これは一例にすぎないと言わざるを得ませんが、同じ原理です。
最も簡単な方法は WebView を読み込むことですが、それは私の目には醜いです。
私の質問を読んでくれてありがとう!
よろしくお願いしますCTS
にロードするKML
にはMKMapView
:
必要なフレームワーク(MapKit.framework
およびCoreLocation.framework
)をターゲットに追加します。
KMLを読み込んで解析します。
KMLに基づいて注釈を作成します。と
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);
}