首页 > 代码库 > iOS开发之在地图上绘制出你运行的轨迹

iOS开发之在地图上绘制出你运行的轨迹

首先我们看下如何在地图上绘制曲线。在Map Kit中提供了一个叫MKPolyline的类,我们可以利用它来绘制曲线,先看个简单的例子。

    使用下面代码从一个文件中读取出经纬度,然后创建一个路径:MKPolyline实例。

 1 -(void) loadRoute
 2 {
 3 NSString* filePath = [[NSBundle mainBundle] pathForResource:@”route” ofType:@”csv”];
 4 NSString* fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
 5 NSArray* pointStrings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
 6 
 7 // while we create the route points, we will also be calculating the bounding box of our route
 8 // so we can easily zoom in on it.
 9 MKMapPoint northEastPoint;
10 MKMapPoint southWestPoint; 
11 
12 // create a c array of points.
13 MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * pointStrings.count);
14 
15 for(int idx = 0; idx < pointStrings.count; idx++)
16 {
17 // break the string down even further to latitude and longitude fields.
18 NSString* currentPointString = [pointStrings objectAtIndex:idx];
19 NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];
20 
21 CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
22 CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];
23 
24 // create our coordinate and add it to the correct spot in the array
25 CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
26 
27 MKMapPoint point = MKMapPointForCoordinate(coordinate);
28 
29 //
30 // adjust the bounding box
31 //
32 
33 // if it is the first point, just use them, since we have nothing to compare to yet.
34 if (idx == 0) {
35 northEastPoint = point;
36 southWestPoint = point;
37 }
38 else
39 {
40 if (point.x > northEastPoint.x)
41 northEastPoint.x = point.x;
42 if(point.y > northEastPoint.y)
43 northEastPoint.y = point.y;
44 if (point.x < southWestPoint.x)
45 southWestPoint.x = point.x;
46 if (point.y < southWestPoint.y)
47 southWestPoint.y = point.y;
48 }
49 
50 pointArr[idx] = point;
51 
52 }
53 
54 // create the polyline based on the array of points.
55 self.routeLine = [MKPolyline polylineWithPoints:pointArr count:pointStrings.count];
56 
57 _routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x -southWestPoint.x, northEastPoint.y - southWestPoint.y);
58 
59 // clear the memory allocated earlier for the points
60 free(pointArr);
61 
62 }
63 将这个路径MKPolyline对象添加到地图上
64 
65 [self.mapView addOverlay:self.routeLine];
66 显示在地图上:
67 
68 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay
69 {
70 MKOverlayView* overlayView = nil;
71 
72 if(overlay == self.routeLine)
73 {
74 //if we have not yet created an overlay view for this overlay, create it now.
75 if(nil == self.routeLineView)
76 {
77 self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease];
78 self.routeLineView.fillColor = [UIColor redColor];
79 self.routeLineView.strokeColor = [UIColor redColor];
80 self.routeLineView.lineWidth = 3;
81 }
82 
83 overlayView = self.routeLineView;
84 
85 }
86 
87 return overlayView;
88 
89 }

然后我们在从文件中读取位置的方法改成从用gprs等方法获取当前位置。

第一步:创建一个CLLocationManager实例
第二步:设置CLLocationManager实例委托和精度
第三步:设置距离筛选器distanceFilter
第四步:启动请求
代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)viewDidLoad {
[super viewDidLoad];
 
noUpdates = 0;
locations = [[NSMutableArray alloc] init];
 
locationMgr = [[CLLocationManager alloc] init];
locationMgr.delegate = self;
locationMgr.desiredAccuracy =kCLLocationAccuracyBest;
locationMgr.distanceFilter = 1.0f;
[locationMgr startUpdatingLocation];
 
 
}

上面的代码我定义了一个数组,用于保存运行轨迹的经纬度。

每次通知更新当前位置的时候,我们将当前位置的经纬度放到这个数组中,并重新绘制路径,代码如下:

 1 - (void)locationManager:(CLLocationManager *)manager 
 2 didUpdateToLocation:(CLLocation *)newLocation 
 3 fromLocation:(CLLocation *)oldLocation{
 4 noUpdates++;
 5 
 6 [locations addObject: [NSString stringWithFormat:@"%f,%f",[newLocation coordinate].latitude, [newLocation coordinate].longitude]];
 7 
 8 [self updateLocation];
 9 if (self.routeLine!=nil) {
10 self.routeLine =nil;
11 }
12 if(self.routeLine!=nil)
13 [self.mapView removeOverlay:self.routeLine];
14 self.routeLine =nil;
15 // create the overlay
16 [self loadRoute];
17 
18 // add the overlay to the map
19 if (nil != self.routeLine) {
20 [self.mapView addOverlay:self.routeLine];
21 }
22 
23 // zoom in on the route. 
24 [self zoomInOnRoute];
25 
26 }
我们将前面从文件获取经纬度创建轨迹的代码修改成从这个数组中取值就行了:

// creates the route (MKPolyline) overlay
-(void) loadRoute
{


// while we create the route points, we will also be calculating the bounding box of our route
// so we can easily zoom in on it. 
MKMapPoint northEastPoint; 
MKMapPoint southWestPoint; 

// create a c array of points. 
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * locations.count);
for(int idx = 0; idx < locations.count; idx++)
{
// break the string down even further to latitude and longitude fields. 
NSString* currentPointString = [locations objectAtIndex:idx];
NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];

CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];

CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);

MKMapPoint point = MKMapPointForCoordinate(coordinate);


if (idx == 0) {
northEastPoint = point;
southWestPoint = point;
}
else 
{
if (point.x > northEastPoint.x) 
northEastPoint.x = point.x;
if(point.y > northEastPoint.y)
northEastPoint.y = point.y;
if (point.x < southWestPoint.x) 
southWestPoint.x = point.x;
if (point.y < southWestPoint.y) 
southWestPoint.y = point.y;
}

pointArr[idx] = point;

}

self.routeLine = [MKPolyline polylineWithPoints:pointArr count:locations.count];

_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x -southWestPoint.x, northEastPoint.y - southWestPoint.y);

free(pointArr);

}
这样我们就将我们运行得轨迹绘制google地图上面了。