MapKit 相关

MapKit学习笔记   

 

1、概述
插入MapView,设置Delegate(一般为Controller),Annotations记录兴趣位置点(AnnotationView用来显示兴趣位置点),annotation是可选的,选中的annotation会显示callout,用来显示信息。

 

2、设置地图显示类型:
mapView.mapType = MKMapTypeStandard;
mapView.mapType = MKMapTypeSatellite;
mapView.mapType = MKMapTypeHybrid;

 

3、显示用户位置
设置为可以显示用户位置:
mapView.showsUserLocation = YES;
判断用户当前位置是否可见(只读属性):
userLocationVisible
得到用户位置坐标:当userLocationVisibleYES
CLLocationCoordinate2D coords = mapView.userLocation.location.coordinate;

 

4、坐标范围
MKCoordinateRegion用来设置坐标显示范围。
包括两部分:CenterCLLocationCoordinate2D struct,包括latitudelongitude),坐标中心
SpanMKCoordinateSpan struct,包括latitudeDeltalongitudeDelta),缩放级别
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000, 2000);
以上代码创建一个以center为中心,上下各1000米,左右各1000米得区域,但其是一个矩形,不符合MapView的横纵比例
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
以上代码创建出来一个符合MapView横纵比例的区域
[mapView setRegion:adjustedRegion animated:YES];
以上代码为:最终显示该区域

 

5Delegate
使用MapView须符合MKMapViewDelegate协议

5.1、地图加载Delegate
当需要从Google服务器取得新地图时
mapViewWillStartLoadingMap:
当成功地取得地图后
mapViewDidFinishLoadingMap:
当取得地图失败后(建议至少要实现此方法)
mapViewDidFailLoadingMap:withError:

5.2、范围变化Delegate
当手势开始(拖拽,放大,缩小,双击)
mapView:regionWillChangeAnimated:
当手势结束(拖拽,放大,缩小,双击)
mapView:regionDidChangeAnimated:

 

判断坐标是否在MapView显示范围内:
CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0);
CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0);
CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0);
CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0);

 

if (leftDegrees > rightDegrees) { // Int’l Date Line in View
    leftDegrees = -180.0 – leftDegrees;
    if (coords.longitude > 0) // coords to West of Date Line
    coords.longitude = -180.0 – coords.longitude;
    }
    If (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) {
       // 坐标在范围内
    }6Annotation

     

    Annotation包含两部分:Annotation ObjectAnnotation View

     

    Annotation Object必须符合协议MKAnnotation,包括两个方法:titlesubtitle,分别用于显示注释的标题和子标题。还有 coordinate属性,返回CLLocationCoordinate2D,表示Annotation的位置
    然后,需使用mapView:viewForAnnotation: 方法来返回MKAnnotationView或者MKAnnotationView的子类用来显示Annotation(注意:这里显示的不是选中Annotation后的弹出框)

     

    你可以子类化MKAnnotationView,然后再drawRect:方法里面进行自己的绘制动作(这个方法很蠢)

     

    你完全可以实例化一个MKAnnotationView,然后更改它的image属性,这样很简单。

     

    7、添加移除Annotation
    添加一个Annotation
    [mapView addAnnotation:annotation];
    添加一个Annotation数组
    [mapView addAnnotations:[NSArray arrayWithObjects:annotation1, annotation2, nil]];
    移除一个Annotation
removeAnnotation:
    移除一个Annotation数组
removeAnnotations:
    移除所有Annotation
    [mapView removeAnnotations:mapView.annotations];

    8、选中Annotation
    一次只能有一个Annotation被选中,选中后会出现CallOut(浮动框)
    简单的CallOut显示TitleSubTitle,但你也可以自定义一个UIView作为CallOut(与自定义的TableViewCell一样)
    可通过代码选中Annotation
selectAnnotation:animated:
    或者取消选择:
deselectAnnotation:animated:

     

    9、显示Annotation
    通过mapView:viewForAnnotation: 方法显示Annotation,每在MapView中加入一个Annotation,就会调用此方法
    示例(与tableView:cellForRowAtIndexPath: 很相似)
    - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
    static NSString *placemarkIdentifier = @”my annotation identifier”;
    if ([annotation isKindOfClass:[MyAnnotation class]]) {
             MKAnnotationView *annotationView = [theMapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier];
        if (annotationView == nil) {
                     annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier];
            annotationView.image = [UIImage imageNamed:@"blood_orange.png"];
        }
        else
            annotationView.annotation = annotation;
        return annotationView;
    }
    return nil;
}

 

10、取得真实地址
示例:
初始化MKReverseGeocoder

MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinates];
geocoder.delegate = self;
[geocoder start];
如果无法处理坐标,则调用reverseGeocoder:didFailWithError: 方法

 

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog(@”Error resolving coordinates: %@”, [error localizedDescription]);
geocoder.delegate = nil;
[geocoder autorelease];
}
如果成功,则调用reverseGeocoder:didFindPlacemark: 并把信息存储在MKPlacemark
didFindPlacemark:(MKPlacemark *)placemark {
NSString *streetAddress = placemark.thoroughfare;
NSString *city = placemark.locality;
NSString *state = placemark.administrativeArea;
NSString *zip = placemark.postalCode;
// Do something with information
geocoder.delegate = nil;
[geocoder autorelease];
}

*******************************************************
 
User Location:
MapViews 用Core Location 来保存用户的路径并在地图上用一个蓝色的点表示出来。 你可以打开:mapView.showUserLocation = YES;
 
如果地图跟踪的是用户的未知,你可以通过只读的属性userLcoationVisible 来检测用户当前的位置是不是可见的。如果是YES,就是可见的。
 
你可以首先设定 showsUserLocation 为 YES来得到用户当前指定的坐标。然后访问userLocation 属性。这个属性返回一个MKUserLocation的实例变量。 MKUserLocation 是一个对象,有一个属性叫做location(CLLocation 类型)。 一个CLLocation 包含一个coordinate属性指向一个坐标的集合,所有的这些意味着你可以得到实际的坐标从MKUserLocation对象里:下属那个:
CLLocationCoordinae2D coords = mapView.userLocation.location.coordinate;
 
Coordinate Regions
如果你不告诉要显示什么或者找出世界上的当前某个具体的位置,那么map view 就不那么smart了。 通过map view, 做到这些工作的关键是 MKCoordinateRegion, 一个结构包含两部分数据,同时也定义了在map view种要显示的位置。
 
第一个成员是 center 。 这是另外一个结构类型是:CLLocationCoordinate2D,  一个CLLocationCoordinate2D包含两个浮点数值,经度和纬度。 这个点代表着map view的中间。
 
第二个叫做span。 是MKCoordinateSpan类型的结构。 它有两个程序叫做 latitudeDelta and longitudeDelta。 这两个程序被用来设定地图的缩放级别——在center周围应该显示多大的区域。
这些值代表经度和纬度的距离。如果latitudeDelta and longitudeDelta是很小的,地图将会被缩放的十分密集,如果大的话,地图将会被放大并显示一个较大的区域。
 
 
Convert degree to distance
每一个纬度代表69英里,或者是111km,不论你在那里。这样就使作为MKCoordinateSpan的参数的 latitudeDelta被传递的时候更容易计算。
 
经度所代表的距离就不是那么容易去计算了。为了做同样的计算,你必须使用纬度,因为它代表的距离取决与你在的地方相对与赤道的距离。 为了计算经度所代表的距离,你必须执行一些数学计算。 实际上apple已经提供了一些方法做这样的计算:
MKCoordinateRegionmakeWithDistance() 创建一个region。 你提供坐标作为center , 距离(m)为经度和纬度的span。 例如创建一个region 来显示指定区域位置 1km。 通过调用 CLLocationCoordinate2D 
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center, 2000, 2000);
 
为了显示每个边周围的1km, 我们必须指定2000m 为每个span:1000m向左,1000m向右,1000m向上,1000m向下。 调用之后,viewRegion 将会包含一个格式化的MKCoordinateRegion,当然你可以使用了。剩下的就是比率转换问题了。
 
横总比:
MKMapView 类优一个实例方法将会适应一个坐标区域来匹配map view的横纵比例。 regionThatFits:
使用的时候你只需在你创建的坐标区域里面传递,同时它会返回一个新的坐标区域来适应map view的比例。
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion[;
 
设定区域显示:
一旦创建好坐标区域,你可以告诉map view 来显示通过setRegion:animated:方法创建的区域。如果你传递YES给第二个参数,mapView将会缩放移动等。
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000,2000);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];

你可能感兴趣的:(MapKit)