地图应用经常会涉及到线路的绘制问题,ios下可以使用MKMapView进行地图开发,使用MKOverlayView进行线路的绘制。
使用MKMapView添加MKMap.framework 和CoreLocation.framework并导入MapKit.h头文件。
新建一个基于视图的工程,修改头文件:
// // CloViewController.h // LocationMapTest // // Created by Cloay on 12-6-18. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import <UIKit/UIKit.h> #import <MapKit/MapKit.h> #import "CloMKAnnotation.h" @interface CloViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate, UIActionSheetDelegate>{ MKMapView *cloMapView; MKPolyline *routeLine; } @property (nonatomic, strong) NSMutableArray *locations; @end
修改实现代码,在.m中添加如下代码:
// // CloViewController.m // LocationMapTest // // Created by Cloay on 12-6-18. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "CloViewController.h" @interface CloViewController () @end @implementation CloViewController @synthesize locations; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. cloMapView = [[MKMapView alloc] initWithFrame:[self.view bounds]]; [cloMapView setMapType:MKMapTypeHybrid]; //设置地图类型 地图/卫星/两者结合 [cloMapView setShowSUSErLocation:YES]; //显示当前位置 [cloMapView setDelegate:self]; CLLocationManager *locationManager = [[CLLocationManager alloc] init]; //设置CLLocationManager实例委托和精度 [locationManager setDelegate:self]; [locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; //设置距离筛选器,表示至少移动100米才通知委托更新 [locationManager setDistanceFilter:100.f]; //启动更新请求 // [locationManager startUpdatingLocation]; locations = [[NSMutableArray alloc] init]; float latitude = 39.8127; //维度 float longitude = 116.2967; //经度 for (int i = 0; i < 10; i++) { [locations addObject:[NSString stringWithFormat:@"%f,%f", latitude + 0.01*i, longitude + 0.01*i]]; // NSLog(@"locations:%i",locations.count); } //地图初始 CLLocationCoordinate2D coords; coords.latitude = 39.9127; coords.longitude = 116.3967; float zoomlevel = 0.22; MKCoordinateRegion region = MKCoordinateRegionMake(coords, MKCoordinateSpanMake(zoomlevel, zoomlevel)); [cloMapView setRegion:[cloMapView regionThatFits:region] animated:YES]; [cloMapView addOverlay:[self makePolylineWithLocations:locations]]; [self.view addSubview:cloMapView]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. cloMapView = nil; } - (void)dealloc{ [cloMapView release]; [super dealloc]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } //显示菜单选项 - (void)showActionSheet :(id)sender{ UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"添加足迹" otherButtonTitles:@"分享",@"详细",@"删除", nil]; [actionSheet setDelegate:self]; [actionSheet showInView:self.view]; [actionSheet release]; } //根据坐标点生成线路 - (MKPolyline *)makePolylineWithLocations:(NSMutableArray *)newLocations{ MKMapPoint *pointArray = malloc(sizeof(CLLocationCoordinate2D)* newLocations.count); for(int i = 0; i < newLocations.count; i++) { // break the string down even further to latitude and longitude fields. NSString* currentPointString = [newLocations objectAtIndex:i]; NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]]; CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue]; // NSLog(@"latitude-> %f", latitude); CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue]; CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); // NSLog(@"point-> %f", point.x); if (i == 0 || i == locations.count - 1) {//这里只添加起点和终点作为测试 CloMKAnnotation *ann = [[CloMKAnnotation alloc] init]; [ann setCoordinate:coordinate]; [ann setTitle:[NSString stringWithFormat:@"纬度:%f", latitude]]; [ann setSubtitle:[NSString stringWithFormat:@"经度:%f", longitude]]; [cloMapView addAnnotation:ann]; } pointArray[i] = MKMapPointForCoordinate(coordinate); } routeLine = [MKPolyline polylineWithPoints:pointArray count:newLocations.count]; free(pointArray); return routeLine; } #pragma mark- #pragma CLLocationManager delegate method //位置变化后会调用 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ //可在此处更新用户位置信息 // cloMapView.userLocation NSLog(@"oldLocation:%@", [oldLocation description]); NSLog(@"newLocation:%@", [newLocation description]); NSLog(@"distance:%@", [newLocation distanceFromLocation:oldLocation]); //位置变化添加新位置点 [locations addObject:[NSString stringWithFormat:@"%f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude]]; //删除进线路,更新新轨迹 [cloMapView removeOverlay:routeLine]; [cloMapView addOverlay:[self makePolylineWithLocations:locations]]; } #pragma MKMapView delegate method //添加坐标点大头针 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{ if (![annotation isKindOfClass:[CloMKAnnotation class]]) { return nil; } static NSString *identifier = @"Annotation"; MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (pinAnnotationView == nil) { pinAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease]; } pinAnnotationView.animatesDrop = YES; pinAnnotationView.canShowCallout = YES; pinAnnotationView.draggable = YES; UIButton *detailBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [detailBtn addTarget:self action:@selector(showActionSheet:) forControlEvents:UIControlEventTouchUpInside]; pinAnnotationView.rightCalloutAccessoryView = detailBtn; return pinAnnotationView; } - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState{ } //画线 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{ NSLog(@"return overLayView..."); if ([overlay isKindOfClass:[MKPolyline class]]) { MKPolylineView *routeLineView = [[[MKPolylineView alloc] initWithPolyline:routeLine] autorelease]; routeLineView.strokeColor = [UIColor blueColor]; routeLineView.lineWidth = 3; return routeLineView; } return nil; } @end
这里主要是为了测试,初始时 locations坐标点自定义的,实际中是根据用户的位置动态生成的一系列坐标点。具体可在