在图2所示的界面中输入查询地点关键字,然后进行地理信息编码查询,结果会调入自带的苹果地图,如图3所示,界面中的标注点是我们传递给它的。我们可以像使用自带地图应用一样进行查询线路、设置地图类型等操作。
南昌APP开发公司要告诉大家的是,在iOS中想要实现这个功能,需要使用Map Kit中的MKPlacemark和MKMapItem这两个类。因此,还需要在工程中添加MapKit.framework,主要代码如下:
@IBAction func geocodeQuery(sender: AnyObject) {
if (self.txtQueryKey.text == nil) {
return
}
var geocoder = CLGeocoder()
geocoder.geocodeAddressString(self.txtQueryKey.text,
completionHandler: { (placemarks, error) -> Void in
if placemarks.count > 0 {
NSLog("查询记录数:%i", placemarks.count)
let placemark = placemarks[0] as CLPlacemark
let coord = placemark.location.coordinate ①
let address = placemark.addressDictionary ②
var place = MKPlacemark(coordinate:coord, addressDictionary:address) ③
let mapItem = MKMapItem(placemark: place) ④
mapItem.openInMapsWithLaunchOptions(nil) ⑤
}
//关闭键盘
self.txtQueryKey.resignFirstResponder()
})
}
- (IBAction)geocodeQuery:(id)sender {
if (self.txtQueryKey.text == nil || [self.txtQueryKey.text length] == 0) {
return;
}
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:self.txtQueryKey.text
completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"查询记录数:%lu",[placemarks count]);
if ([placemarks count] > 0) {
CLPlacemark* placemark = placemarks[0];
CLLocationCoordinate2D coordinate = placemark.location.coordinate; ①
NSDictionary* address = placemark.addressDictionary; ②
MKPlacemark *place = [[MKPlacemark alloc]
initWithCoordinate:coordinate addressDictionary:address]; ③
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place]; ④
[mapItem openInMapsWithLaunchOptions:nil]; ⑤
//关闭键盘
[_txtQueryKey resignFirstResponder];
}
}];
}
在上述代码中,第③行代码用于实例化MKPlacemark对象。注意,MKPlacemark与CLPlacemark不同,前者是地图上的地标类,后者是定位使用的地标类。其中coordinate参数是地理坐标点,该地理坐标点通过第①行中的placemark.location.coordinate语句取得;addressDictionary参数是该地点信息,它的参数可以通过第②行语句中的placemark.addressDictionary获得。
第④行代码用于实例化MKMapItem对象。MKMapItem类封装了地图上一个点的信息类。我们把需要在地图上显示的点封装到MKMapItem对象中。构造器参数placemark是MKPlacemark类型。
第⑤行代码调用iOS自带的苹果地图应用。openInMapsWithLaunchOptions:方法是MKMapItem类的实例方法,其参数是NSDictionary类型,这个参数可以控制显示地图的初始化信息,它包含一些键,具体如下。
1、MKLaunchOptionsDirectionsModeKey。设定路线模式,它有两个值MKLaunchOptionsDirectionsModeDriving(驾车路线)和MKLaunchOptionsDirectionsModeWalking(步行路线)。
2、MKLaunchOptionsMapTypeKey:设定地图类型。
3、MKLaunchOptionsMapCenterKey:设定地图中心点。
4、MKLaunchOptionsMapSpanKey:设置地图跨度。
5、MKLaunchOptionsShowsTrafficKey:设置显示交通状况。
例如,我们可以使用下面的代码在地图上设置行车路线:
let options = NSDictionary(object: MKLaunchOptionsDirectionsModeDriving,
forKey: MKLaunchOptionsDirectionsModeKey)
let mapItem = MKMapItem(placemark: place)
mapItem.openInMapsWithLaunchOptions(options)
NSDictionary* options =[[NSDictionary alloc]initWithObjectsAndKeys:
MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsDirectionsModeKey, nil];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place];
[mapItem openInMapsWithLaunchOptions:options];
设置行车路线后,会在地图上标注出路线,如图4所示。默认情况下,起点是当前位置,这个位置通过定位服务获得。终点是我们查询的地点,即place变量所包含的信息。
如果有多个点需要标注,可以使用MKMapItem的类方法:
class func openMapsWithItems(_ mapItems: [AnyObject]!,
launchOptions launchOptions: [NSObject : AnyObject]!) -> Bool
+ (BOOL)openMapsWithItems:(NSArray *)mapItems
launchOptions:(NSDictionary *)launchOptions
其中参数mapItems是标注点的集合,launchOptions是启动参数。如果想使用这个方法,则上面的例子可以修改如下:
var geocoder = CLGeocoder()
geocoder.geocodeAddressString(self.txtQueryKey.text,
completionHandler: { (placemarks, error) -> Void in
if placemarks == nil {
return
}
var array = NSMutableArray()
for item in placemarks {
let placemark = item as CLPlacemark
let coord = placemark.location.coordinate
let address = placemark.addressDictionary
var place = MKPlacemark(coordinate:coord, addressDictionary:address)
let mapItem = MKMapItem(placemark: place)
mapItem.openInMapsWithLaunchOptions(nil)
array.addObject(mapItem) ①
}
//关闭键盘
self.txtQueryKey.resignFirstResponder()
if (array.count > 0) {
MKMapItem.openMapsWithItems(array, launchOptions: nil) ②
}
})
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:_txtQueryKey.text completionHandler:^(NSArray
*placemarks, NSError *error) {
NSLog(@”查询记录数:%u”,(unsigned int)[placemarks count]);
NSMutableArray* array = [NSMutableArray new];
for (int i = 0; i < [placemarks count]; i++) {
CLPlacemark* placemark = placemarks[i];
CLLocationCoordinate2D coordinate = placemark.location.coordinate;
NSDictionary* address = placemark.addressDictionary;
MKPlacemark *place = [[MKPlacemark alloc]
initWithCoordinate:coordinate addressDictionary:address];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place];
[array addObject:mapItem]; ①
}
//关闭键盘
[_txtQueryKey resignFirstResponder];
if ([array count] > 0) {
[MKMapItem openMapsWithItems:array launchOptions:nil]; ②
}
}];
与传递单个标注点不同的是,我们需要进行循环遍历,然后把地图地标对象MKMapItem放到集合中,如第①行代码所示。第②行代码用于在循环完成后启动自带苹果地图。运行结果如图5所示,可以发现,传递的两个地标点都标注处理了。