【问题标题】:Plotting a users route taken on a map using MKPolyline使用 MKPolyline 在地图上绘制用户路线
【发布时间】:2014-02-25 05:24:41
【问题描述】:

我对 Objective-c 很陌生。

在我的应用程序中,我试图将用户采取的路线绘制到地图上。

这是我目前所拥有的只是获取用户当前位置的信息:

#import "StartCycleViewController.h"
#import "CrumbPath.h"


@interface StartCycleViewController ()

@property (nonatomic, strong) CLLocationManager *locationManager;

@property (nonatomic, strong) IBOutlet MKMapView *map;

@property (nonatomic, strong) UIView *containerView;





@end

@implementation StartCycleViewController

@synthesize cycleLocation = _cycleLocation;
@synthesize currentCycleLocation = _currentCycleLocation;






 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization
    }
    return self;
 }

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self startCycleLocation];

    _containerView = [[UIView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.containerView];

    [self.containerView addSubview:self.map];
    // Do any additional setup after loading the view.
}


- (void)dealloc
{
    self.locationManager.delegate = nil;
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


#pragma mark - startCycleLocation

- (void)startCycleLocation{

    if (!_cycleLocation){
        _cycleLocation = [[CLLocationManager alloc]init];
        _cycleLocation.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        _cycleLocation.distanceFilter = 10;
        _cycleLocation.delegate = self;

    }
    [_cycleLocation startUpdatingLocation];

}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation     *)newLocation fromLocation:(CLLocation *)oldLocation {

    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) {
    self.longitudeLabel.text = [NSString stringWithFormat:@"%.8f",    currentLocation.coordinate.longitude];
    self.latitudeLabel.text = [NSString stringWithFormat:@"%.8f",    currentLocation.coordinate.latitude];

    }
}



- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"%@",error);

    if ( [error code] != kCLErrorLocationUnknown ){
        [self stopLocationManager];
    }
}

- (void) stopLocationManager {
    [self.cycleLocation stopUpdatingLocation];
}



@end

我在网上浏览了一下,发现我应该使用MKPolyline并给它坐标。但我只是不确定如何存储位置,然后使用MKPolyline 发送它们来绘制点,在应用程序运行时连续绘制。

【问题讨论】:

    标签: objective-c location mapkit core-location mkpolyline


    【解决方案1】:

    您应该只创建一个NSMutableArray 来保存您在viewDidLoad 中实例化的位置。所以有didUpdateToLocation(或者,如果支持iOS 6及更高版本,你应该使用didUpdateToLocations)只需将一个位置添加到一个数组,然后从该数组构建一个MKPolyline,将MKPolyline添加到地图中,然后然后删除旧的MKPolyline。或者您可以将所有线段添加为单独的 MKPolyline 对象,但想法是相同的,创建一个模型来保存您的位置(例如 NSMutableArray),然后将适当的 MKPolyline 对象添加到地图视图。

    例如,您可以执行以下操作:

    #pragma mark - CLLocationManagerDelegate
    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation *location = [locations lastObject];
    
        if (location.horizontalAccuracy < 0)
            return;
    
        [self.locations addObject:location];
        NSUInteger count = [self.locations count];
    
        if (count > 1) {
            CLLocationCoordinate2D coordinates[count];
            for (NSInteger i = 0; i < count; i++) {
                coordinates[i] = [(CLLocation *)self.locations[i] coordinate];
            }
    
            MKPolyline *oldPolyline = self.polyline;
            self.polyline = [MKPolyline polylineWithCoordinates:coordinates count:count];
            [self.mapView addOverlay:self.polyline];
            if (oldPolyline)
                [self.mapView removeOverlay:oldPolyline];
        }
    }
    

    记得指定地图是如何绘制MKPolyline的。因此,将您的视图控制器设置为您的MKMapViewdelegate,然后您可以执行以下操作:

    #pragma mark - MKMapViewDelegate
    
    - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
    {
        if ([overlay isKindOfClass:[MKPolyline class]])
        {
            MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
    
            renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
            renderer.lineWidth   = 3;
    
            return renderer;
        }
    
        return nil;
    }
    
    // for iOS versions prior to 7; see `rendererForOverlay` for iOS7 and later
    
    - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
    {
        if ([overlay isKindOfClass:[MKPolyline class]])
        {
            MKPolylineView *overlayView = [[MKPolylineView alloc] initWithPolyline:overlay];
    
            overlayView.strokeColor     = [[UIColor blueColor] colorWithAlphaComponent:0.7];
            overlayView.lineWidth       = 3;
    
            return overlayView;
        }
    
        return nil;
    }
    

    【讨论】:

    • 感谢您的回复:) 对不起,我还是新手!我已经实现了代码并且遇到了一些错误,我相信它都是基本的东西。我尝试使用 [mapView setDelegate:self] 将视图控制器设置为 MKMapView 的委托;对吗?
    • 我还收到以下错误@self.location addObject“没有可见的@interface for NSArray 声明sddObject”和@self.mapview“未在类型对象上找到”。我再次确定我做错了什么!
    • @user3254994 是的,要为MKMapView 指定委托,您可以在类似的代码中执行此操作(或者您可以通过转到“连接检查器”在 IB 中执行此操作)。关于self.locations 的错误是因为您将其定义和/或实例化为NSArray 而不是NSMutableArray。使用后者。
    • @user3254994 当您在 Interface Builder (IB) 中定义了不正确的插座时,您通常会收到该错误。在“连接检查器”(IB 右侧面板中的最后一个选项卡)中检查您的IBOutlet 定义,并与您的代码中的IBOutlet 定义进行比较。听起来 IB 中存在与名称为 map 的不存在属性的连接
    • @AceN - 是的,你必须在你的地图视图委托中实现mapview:rendererForOverlay:(或者,Swift 中的mapView(_:rendererFor:))(并且显然也设置了地图视图的delegate)。如果没有,则不会呈现(可见的)叠加层。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2016-10-29
    相关资源
    最近更新 更多