打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
iOS 在地图上绘制出你运动的轨迹
分类: IOS 2013-03-26 14:22 2768人阅读 评论(0) 收藏 举报
iOS中的MapKit集成了google地图api的很多功能加上iOS的定位的功能,我们就可以实现将你运行的轨迹绘制到地图上面。这个功能非常有用,比如快递追踪、汽车的gprs追踪、人员追踪等等。这篇文章我们将使用Map Kit和iOS的定位功能,将你的运行轨迹绘制在地图上面。

实现

   在之前的一篇文章描述了如何在地图上显示自己的位置,如果我们将这些位置先保存起来,然后串联起来绘制到地图上面,那就是我们的运行轨迹了。

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

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

  1. -(void) loadRoute 
  2. NSString* filePath = [[NSBundle mainBundle] pathForResource:@”route” ofType:@”csv”]; 
  3. NSString* fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 
  4. NSArray* pointStrings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
  5.  
  6. // while we create the route points, we will also be calculating the bounding box of our route 
  7. // so we can easily zoom in on it. 
  8. MKMapPoint northEastPoint; 
  9. MKMapPoint southWestPoint;  
  10.  
  11. // create a c array of points. 
  12. MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * pointStrings.count); 
  13.  
  14. for(int idx = 0; idx < pointStrings.count; idx++) 
  15. // break the string down even further to latitude and longitude fields. 
  16. NSString* currentPointString = [pointStrings objectAtIndex:idx]; 
  17. NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]]; 
  18.  
  19. CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue]; 
  20. CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue]; 
  21.  
  22. // create our coordinate and add it to the correct spot in the array 
  23. CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); 
  24.  
  25. MKMapPoint point = MKMapPointForCoordinate(coordinate); 
  26.  
  27. // 
  28. // adjust the bounding box 
  29. // 
  30.  
  31. // if it is the first point, just use them, since we have nothing to compare to yet. 
  32. if (idx == 0) { 
  33. northEastPoint = point; 
  34. southWestPoint = point; 
  35. else 
  36. if (point.x > northEastPoint.x) 
  37. northEastPoint.x = point.x; 
  38. if(point.y > northEastPoint.y) 
  39. northEastPoint.y = point.y; 
  40. if (point.x < southWestPoint.x) 
  41. southWestPoint.x = point.x; 
  42. if (point.y < southWestPoint.y) 
  43. southWestPoint.y = point.y; 
  44.  
  45. pointArr[idx] = point; 
  46.  
  47.  
  48. // create the polyline based on the array of points. 
  49. self.routeLine = [MKPolyline polylineWithPoints:pointArr count:pointStrings.count]; 
  50.  
  51. _routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
  52.  
  53. // clear the memory allocated earlier for the points 
  54. free(pointArr); 
  55.  
  56. }  
  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. }   


将这个路径添加到地图上

  1. [self.mapView addOverlay:self.routeLine];  
  1. [self.mapView addOverlay:self.routeLine];   


显示在地图上:

  1. - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay 
  2. MKOverlayView* overlayView = nil; 
  3.  
  4. if(overlay == self.routeLine) 
  5. //if we have not yet created an overlay view for this overlay, create it now. 
  6. if(nil == self.routeLineView) 
  7. self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease]; 
  8. self.routeLineView.fillColor = [UIColor redColor]; 
  9. self.routeLineView.strokeColor = [UIColor redColor]; 
  10. self.routeLineView.lineWidth = 3; 
  11.  
  12. overlayView = self.routeLineView; 
  13.  
  14.  
  15. return overlayView; 
  16.  
  17. }  
  1. - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay  
  2. {  
  3. MKOverlayView* overlayView = nil;  
  4.   
  5. if(overlay == self.routeLine)  
  6. {  
  7. //if we have not yet created an overlay view for this overlay, create it now.  
  8. if(nil == self.routeLineView)  
  9. {  
  10. self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease];  
  11. self.routeLineView.fillColor = [UIColor redColor];  
  12. self.routeLineView.strokeColor = [UIColor redColor];  
  13. self.routeLineView.lineWidth = 3;  
  14. }  
  15.   
  16. overlayView = self.routeLineView;  
  17.   
  18. }  
  19.   
  20. return overlayView;  
  21.   
  22. }   

效果:

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

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


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

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

  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.           
  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. }  


我们将前面从文件获取经纬度创建轨迹的代码修改成从这个数组中取值就行了:

  1. // creates the route (MKPolyline) overlay 
  2. -(void) loadRoute 
  3.   
  4.      
  5.     // while we create the route points, we will also be calculating the bounding box of our route 
  6.     // so we can easily zoom in on it.  
  7.     MKMapPoint northEastPoint;  
  8.     MKMapPoint southWestPoint;  
  9.      
  10.     // create a c array of points.  
  11.     MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * locations.count); 
  12.     for(int idx = 0; idx < locations.count; idx++) 
  13.     { 
  14.         // break the string down even further to latitude and longitude fields.  
  15.         NSString* currentPointString = [locations objectAtIndex:idx]; 
  16.         NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]]; 
  17.      
  18.         CLLocationDegrees latitude  = [[latLonArr objectAtIndex:0] doubleValue]; 
  19.         CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue]; 
  20.           
  21.         CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); 
  22.  
  23.         MKMapPoint point = MKMapPointForCoordinate(coordinate); 
  24.  
  25.      
  26.         if (idx == 0) { 
  27.             northEastPoint = point; 
  28.             southWestPoint = point; 
  29.         } 
  30.         else  
  31.         { 
  32.             if (point.x > northEastPoint.x)  
  33.                 northEastPoint.x = point.x; 
  34.             if(point.y > northEastPoint.y) 
  35.                 northEastPoint.y = point.y; 
  36.             if (point.x < southWestPoint.x)  
  37.                 southWestPoint.x = point.x; 
  38.             if (point.y < southWestPoint.y)  
  39.                 southWestPoint.y = point.y; 
  40.         } 
  41.  
  42.         pointArr[idx] = point; 
  43.  
  44.     } 
  45.      
  46.     self.routeLine = [MKPolyline polylineWithPoints:pointArr count:locations.count]; 
  47.  
  48.     _routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y); 
  49.      
  50.     free(pointArr); 
  51.      
  1. // creates the route (MKPolyline) overlay  
  2. -(void) loadRoute  
  3. {  
  4.    
  5.       
  6.     // while we create the route points, we will also be calculating the bounding box of our route  
  7.     // so we can easily zoom in on it.   
  8.     MKMapPoint northEastPoint;   
  9.     MKMapPoint southWestPoint;   
  10.       
  11.     // create a c array of points.   
  12.     MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * locations.count);  
  13.     for(int idx = 0; idx < locations.count; idx++)  
  14.     {  
  15.         // break the string down even further to latitude and longitude fields.   
  16.         NSString* currentPointString = [locations objectAtIndex:idx];  
  17.         NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];  
  18.       
  19.         CLLocationDegrees latitude  = [[latLonArr objectAtIndex:0] doubleValue];  
  20.         CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];  
  21.            
  22.         CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);  
  23.   
  24.         MKMapPoint point = MKMapPointForCoordinate(coordinate);  
  25.   
  26.       
  27.         if (idx == 0) {  
  28.             northEastPoint = point;  
  29.             southWestPoint = point;  
  30.         }  
  31.         else   
  32.         {  
  33.             if (point.x > northEastPoint.x)   
  34.                 northEastPoint.x = point.x;  
  35.             if(point.y > northEastPoint.y)  
  36.                 northEastPoint.y = point.y;  
  37.             if (point.x < southWestPoint.x)   
  38.                 southWestPoint.x = point.x;  
  39.             if (point.y < southWestPoint.y)   
  40.                 southWestPoint.y = point.y;  
  41.         }  
  42.   
  43.         pointArr[idx] = point;  
  44.   
  45.     }  
  46.       
  47.     self.routeLine = [MKPolyline polylineWithPoints:pointArr count:locations.count];  
  48.   
  49.     _routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);  
  50.       
  51.     free(pointArr);  
  52.       
  53. }  


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

扩展:

    如果你想使用其他的地图,比如百度地图,其实也很方便。可以将百度地图放置到UIWebView中间,通过用js去绘制轨迹。

总结:这篇文章我们介绍了一种常见的技术实现:在地图上绘制出你运行的轨迹。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
两元钱,海聊户外宝追踪队友行程
乐图
两步路APP扫盲
伺服驱动器是通过放大plc发出的脉冲信号来驱动伺服电机的吗?
苹果iOS 11版本为地图增加VR功能
iOS 谷歌地图App迎来更新 获了不少新功能
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服