玩转Map Kit (part3)

原文地址:http://blog.objectgraph.com/index.php/2009/04/08/iphone-sdk-30-playing-with-map-kit-part-3/

说明:本人E文水平有限,如有不足之处还请指正

--------------------------------------------------------------

有许多人问我如何在地图组件上绘制拆线。从我看到文档中,没有一个提供这样的课程。

你可以使用Quartz在视图上进行绘制。但我觉得直接在地图组件上绘制是没有用的。

如果你已经理解了我先前提交的文章,现在你可以很容易的做到如下:

-显示地图组件的不同风格

-显示当前位置

-获取当前的位置

-创建一个标注

-反转Geocode 的经纬度以获得更多的位置信息

所以,只需要使用这些有限的API,您就可以创建出 不同类型 的应用程序

– Friend Track Apps (Like Loopt)
– Car Park Finder (Just add an annotation where you left the car)

玩转Map Kit (part3)

我发现了获取用户位置的最好的方法,就是使用Core Location.因为它提供了一个很好的委托,可以让我们知道什么时候从GPS异步获得坐标。

因此我可以结合MapKit和core Location API 去放大你当前的位置及放置标注(Annotation)

这里有一些代码:

头文件

#import "FlipsideViewController.h" #import "ParkPlaceMark.h" #import <MapKit/MapKit.h> #import <MapKit/MKReverseGeocoder.h> #import <CoreLocation/CoreLocation.h> @interface MainViewController : UIViewController <FlipsideViewControllerDelegate, MKMapViewDelegate, MKReverseGeocoderDelegate, CLLocationManagerDelegate> { MKMapView *mapView; MKPlacemark *mPlacemark; CLLocationCoordinate2D location; IBOutlet UIButton *mStoreLocationButton; } - (IBAction)showInfo; - (IBAction)storeLocationInfo:(id) sender; @end

代码文件

#import "MainViewController.h" #import "MainView.h" @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { // Custom initialization } return self; } // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; mapView=[[MKMapView alloc] initWithFrame:self.view.frame]; //mapView.showsUserLocation=TRUE; mapView.delegate=self; [self.view insertSubview:mapView atIndex:0]; CLLocationManager *locationManager=[[CLLocationManager alloc] init]; locationManager.delegate=self; locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters; [locationManager startUpdatingLocation]; } - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller { [self dismissModalViewControllerAnimated:YES]; } - (IBAction)showInfo { FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil]; controller.delegate = self; controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:controller animated:YES]; [controller release]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } - (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [super dealloc]; } - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{ } - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark{ NSLog(@"Geocoder completed"); mPlacemark=placemark; [mapView addAnnotation:placemark]; } - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{ NSLog(@"This is called"); MKPinAnnotationView *test=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"parkingloc"]; if([annotation title][email protected]"Parked Location") { [test setPinColor:MKPinAnnotationColorPurple]; } else { [test setPinColor:MKPinAnnotationColorGreen]; } return test; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ mStoreLocationButton.hidden=FALSE; location=newLocation.coordinate; //One location is obtained.. just zoom to that location MKCoordinateRegion region; region.center=location; //Set Zoom level using Span MKCoordinateSpan span; span.latitudeDelta=.005; span.longitudeDelta=.005; region.span=span; [mapView setRegion:region animated:TRUE]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ } - (IBAction)storeLocationInfo:(id) sender{ //Either we can use geocoder to get a placemark or just create our own. /* MKReverseGeocoder *geocoder=[[MKReverseGeocoder alloc] initWithCoordinate:location]; geocoder.delegate=self; [geocoder start]; */ //Our own ParkPlaceMark *placemark=[[ParkPlaceMark alloc] initWithCoordinate:location]; [mapView addAnnotation:placemark]; } @end

您也 可以 使用反向 地理编码器(reverse Geocoder ) 获得地 标(PlaceMark)或 创建自己的标注 (Annotation).下面是一些关于如何通过实现MKAnnotation 协议(protocal)快速创建自己的标注(Annotation)

头文件

#import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface ParkPlaceMark : NSObject<MKAnnotation> { CLLocationCoordinate2D coordinate; } @property (nonatomic, readonly) CLLocationCoordinate2D coordinate; -(id)initWithCoordinate:(CLLocationCoordinate2D) coordinate; - (NSString *)subtitle; - (NSString *)title; @end @end

源文件

#import "ParkPlaceMark.h" @implementation ParkPlaceMark @synthesize coordinate; - (NSString *)subtitle{ return @"Put some text here"; } - (NSString *)title{ return @"Parked Location"; } -(id)initWithCoordinate:(CLLocationCoordinate2D) c{ coordinate=c; NSLog(@"%f,%f",c.latitude,c.longitude); return self; } @end

Download the Files