IOS开发中绘制地图线路
地图应用经常会涉及到线路的绘制问题,ios下可以使用MKMapView进行地图开发,使用
MKOverlayView进行线路的绘制。
使用MKMapView添加MKMap.framework 和CoreLocation.framework并导入
MapKit.h头文件。
新建一个基于视图的工程,修改头文件:
1 #import <UIKit/UIKit.h> 2 #import <MapKit/MapKit.h> 3 #import "CloMKAnnotation.h" 4 @interface CloViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate, UIActionSheetDelegate>{ 5 MKMapView *cloMapView; 6 MKPolyline *routeLine; 7 } 8 9 @property (nonatomic, strong) NSMutableArray *locations;
修改实现代码,在.m中添加如下代码:
1 #import "CloViewController.h" 2 3 @interface CloViewController () 4 5 @end 6 7 @implementation CloViewController 8 @synthesize locations; 9 10 - (void)viewDidLoad 11 { 12 [super viewDidLoad]; 13 // Do any additional setup after loading the view, typically from a nib. 14 cloMapView = [[MKMapView alloc] initWithFrame:[self.view bounds]]; 15 [cloMapView setMapType:MKMapTypeHybrid]; //设置地图类型 地图/卫星/两者结合 16 [cloMapView setShowsUserLocation:YES]; //显示当前位置 17 [cloMapView setDelegate:self]; 18 19 CLLocationManager *locationManager = [[CLLocationManager alloc] init]; 20 //设置CLLocationManager实例委托和精度 21 [locationManager setDelegate:self]; 22 [locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; 23 //设置距离筛选器,表示至少移动100米才通知委托更新 24 [locationManager setDistanceFilter:100.f]; 25 //启动更新请求 26 // [locationManager startUpdatingLocation]; 27 28 locations = [[NSMutableArray alloc] init]; 29 float latitude = 39.8127; //维度 30 float longitude = 116.2967; //经度 31 for (int i = 0; i < 10; i++) { 32 33 [locations addObject:[NSString stringWithFormat:@"%f,%f", latitude + 0.01*i, longitude + 0.01*i]]; 34 // NSLog(@"locations:%i",locations.count); 35 } 36 37 //地图初始 38 CLLocationCoordinate2D coords; 39 coords.latitude = 39.9127; 40 coords.longitude = 116.3967; 41 float zoomlevel = 0.22; 42 MKCoordinateRegion region = MKCoordinateRegionMake(coords, MKCoordinateSpanMake(zoomlevel, zoomlevel)); 43 [cloMapView setRegion:[cloMapView regionThatFits:region] animated:YES]; 44 45 [cloMapView addOverlay:[self makePolylineWithLocations:locations]]; 46 [self.view addSubview:cloMapView]; 47 48 } 49 50 - (void)viewDidUnload 51 { 52 [super viewDidUnload]; 53 // Release any retained subviews of the main view. 54 cloMapView = nil; 55 } 56 57 - (void)dealloc{ 58 [cloMapView release]; 59 [super dealloc]; 60 } 61 62 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 63 { 64 return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 65 } 66 67 68 //显示菜单选项 69 - (void)showActionSheet :(id)sender{ 70 UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:nil 71 delegate:self 72 cancelButtonTitle:@"取消" 73 destructiveButtonTitle:@"添加足迹" 74 otherButtonTitles:@"分享",@"详细",@"删除", nil]; 75 [actionSheet setDelegate:self]; 76 [actionSheet showInView:self.view]; 77 [actionSheet release]; 78 } 79 80 //根据坐标点生成线路 81 - (MKPolyline *)makePolylineWithLocations:(NSMutableArray *)newLocations{ 82 MKMapPoint *pointArray = malloc(sizeof(CLLocationCoordinate2D)* newLocations.count); 83 for(int i = 0; i < newLocations.count; i++) 84 { 85 // break the string down even further to latitude and longitude fields. 86 NSString* currentPointString = [newLocations objectAtIndex:i]; 87 NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]]; 88 CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue]; 89 // NSLog(@"latitude-> %f", latitude); 90 CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue]; 91 CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); 92 // NSLog(@"point-> %f", point.x); 93 94 if (i == 0 || i == locations.count - 1) {//这里只添加起点和终点作为测试 95 CloMKAnnotation *ann = [[CloMKAnnotation alloc] init]; 96 [ann setCoordinate:coordinate]; 97 [ann setTitle:[NSString stringWithFormat:@"纬度:%f", latitude]]; 98 [ann setSubtitle:[NSString stringWithFormat:@"经度:%f", longitude]]; 99 [cloMapView addAnnotation:ann]; 100 } 101 pointArray[i] = MKMapPointForCoordinate(coordinate); 102 } 103 104 routeLine = [MKPolyline polylineWithPoints:pointArray count:newLocations.count]; 105 free(pointArray); 106 return routeLine; 107 } 108 #pragma mark- 109 #pragma CLLocationManager delegate method 110 //位置变化后会调用 111 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ 112 //可在此处更新用户位置信息 113 // cloMapView.userLocation 114 NSLog(@"oldLocation:%@", [oldLocation description]); 115 NSLog(@"newLocation:%@", [newLocation description]); 116 NSLog(@"distance:%@", [newLocation distanceFromLocation:oldLocation]); 117 //位置变化添加新位置点 118 [locations addObject:[NSString stringWithFormat:@"%f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude]]; 119 //删除进线路,更新新轨迹 120 [cloMapView removeOverlay:routeLine]; 121 [cloMapView addOverlay:[self makePolylineWithLocations:locations]]; 122 123 } 124 125 #pragma MKMapView delegate method 126 //添加坐标点大头针 127 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{ 128 if (![annotation isKindOfClass:[CloMKAnnotation class]]) { 129 return nil; 130 } 131 static NSString *identifier = @"Annotation"; 132 MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 133 if (pinAnnotationView == nil) { 134 pinAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease]; 135 } 136 pinAnnotationView.animatesDrop = YES; 137 pinAnnotationView.canShowCallout = YES; 138 pinAnnotationView.draggable = YES; 139 UIButton *detailBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 140 [detailBtn addTarget:self action:@selector(showActionSheet:) forControlEvents:UIControlEventTouchUpInside]; 141 pinAnnotationView.rightCalloutAccessoryView = detailBtn; 142 143 return pinAnnotationView; 144 } 145 146 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState{ 147 148 } 149 150 //画线 151 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{ 152 NSLog(@"return overLayView..."); 153 if ([overlay isKindOfClass:[MKPolyline class]]) { 154 MKPolylineView *routeLineView = [[[MKPolylineView alloc] initWithPolyline:routeLine] autorelease]; 155 routeLineView.strokeColor = [UIColor blueColor]; 156 routeLineView.lineWidth = 3; 157 return routeLineView; 158 } 159 return nil; 160 } 161 162 @end
这里主要是为了测试,初始时 locations坐标点自定义的,实际中是根据用户的位置动态生成的一系列坐标点。具体可在下面方法中实现
1 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
另外用户的实时位置可用
1 cloMapView.userLocation = newLocation进行设置,然后显示在地图上。
运行效果
如果你错过了一天,那么你就真的错过了一天……ues.hk