2012-05-15 2 views
0

Я пытаюсь использовать оверлей, чтобы нарисовать маршрут в MKMapView. Это мой код:Большие проблемы с рисованием/пониманием MKOverlayView на MKMapView

Создать представление (вызывается, на нажатие кнопки):

NSArray *route = [UCGeoConverter generateCoordinatesFromKML:self.kmlResponse]; 
    if (!self.routeView) { 
     NSLog(@"create route"); 
     self.routeView = [[UCRouteView alloc] initWithRoute:route mapView:self.mapview]; 
     [self.mapview addOverlay:self.routeView]; 
    } 

Теперь это мой файл UCRouteView.h. Он наследует MKOverlayView и реализует MKOverlay.

#import <Foundation/Foundation.h> 
#import <MapKit/MapKit.h> 
#import "UCLocation.h" 

@interface UCRouteView : MKOverlayView <MKOverlay> 
{ 
    MKMapView* _mapView; 
    NSArray* _points; 
    UIColor* _lineColor; 
} 

-(id) initWithRoute:(NSArray*)routePoints mapView:(MKMapView*)mapView; 

@property (strong, nonatomic) id delegate; 
@property (nonatomic) MKCoordinateRegion region; 
@property (nonatomic, retain) NSArray* points; 
@property (nonatomic, retain) MKMapView* mapView; 
@property (nonatomic, retain) UIColor* lineColor; 
@end 

Теперь для реализации. Здесь у меня большие проблемы. Во-первых, похоже, что делегирование не работает, так как никто из методов не вызвал (за исключением init .. очевидно), я установил делегат в себя. У меня проблемы с пониманием того, как это работает, поэтому я был бы признателен, если вы, ребята, могли бы помочь мне здесь, это очень важно! БЛАГОДАРЯ столько

#import "UCRouteView.h" 

@implementation UCRouteView 

@synthesize mapView  = _mapView; 
@synthesize points  = _points; 
@synthesize lineColor = _lineColor; 
@synthesize delegate = _delegate; 
@synthesize region  = _region; 

-(id) initWithRoute:(NSArray*)routePoints mapView:(MKMapView*)mapView 
{ 
    self.delegate = self; 
    self = [super initWithFrame:CGRectMake(0, 0, mapView.frame.size.width, mapView.frame.size.height)]; 

    [self setMapView:mapView]; 
    [self setPoints:routePoints]; 

    // determine the extents of the route points and zoom to that area. 
    CLLocationDegrees maxLat = -90; 
    CLLocationDegrees maxLon = -180; 
    CLLocationDegrees minLat = 90; 
    CLLocationDegrees minLon = 180; 

    for(int idx = 0; idx < self.points.count; idx++) 
    { 
     UCLocation* currentLocation = [self.points objectAtIndex:idx]; 
     if(currentLocation.coordinates.latitude > maxLat) 
      maxLat = currentLocation.coordinates.latitude; 
     if(currentLocation.coordinates.latitude < minLat) 
      minLat = currentLocation.coordinates.latitude; 
     if(currentLocation.coordinates.longitude > maxLon) 
      maxLon = currentLocation.coordinates.longitude; 
     if(currentLocation.coordinates.longitude < minLon) 
      minLon = currentLocation.coordinates.longitude; 
    } 

    _region.center.latitude  = (maxLat + minLat)/2; 
    _region.center.longitude = (maxLon + minLon)/2; 
    _region.span.latitudeDelta = maxLat - minLat; 
    _region.span.longitudeDelta = maxLon - minLon; 

    [self.mapView setRegion:_region]; 
    return self; 
} 
- (MKMapRect)boundingMapRect 
{ 
    // 1. Problem: this returns the MapRect where the overlay is in, right? 
    // So why not just return the MapRect which is visible right now? 
    return self.mapView.visibleMapRect; 
} 

-(BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale 
{ 
    // 2. just return YES to make sure it draws 
    return YES; 
} 

-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay 
{ 
    // 3. this never gets called? what's wrong? 
    NSLog(@"mapview viewForOverlay"); 
    return self; 
} 

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context 
{  
    // does not get called either. I know the drawing code as is works to draw a route, 
    // but I think I'm missing something here aswell.. 
    NSLog(@"draw route"); 
    // only draw lines if not in the middle of a transition and we 
    // acutally have some points to draw. 
    if(self.points && self.points.count > 0) 
    { 
     // set the color to draw the route 
     if(nil == self.lineColor) 
      self.lineColor = [UIColor blueColor]; 

     CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor); 
     CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0); 

     // Draw them with a 2.0 stroke width 
     CGContextSetLineWidth(context, 2.0); 

     for(int idx = 0; idx < self.points.count; idx++) 
     { 
      UCLocation* location = [self.points objectAtIndex:idx]; 
      CGPoint point = [_mapView convertCoordinate:location.coordinates toPointToView:self]; 

      // set starting point and 'move' to it 
      if(idx == 0) 
      { 
       // TODO: set special annotation for start/endpoint 
       CGContextMoveToPoint(context, point.x, point.y); 
      } 
      else 
      { 
       CGContextAddLineToPoint(context, point.x, point.y); 
      } 
     } 
     CGContextStrokePath(context); 
    } 
} 
    @end 

ответ

0

Во-первых, вы пытаетесь вызвать сеттер на self, прежде чем он был создан (т.е. ваш self.delegate = self приходит перед тем[super init...]). Это не будет работать нигде в любом объекте.

Что более важно, однако, что delegate вы собираетесь установить? Ваш класс UCRouteView является подклассом MKOverlayView, который не имеет свойства delegate (а также не имеет своих суперклассов). Ваши методы, на самом деле, от <MKMapViewDelegate>, что указывает на то, что вы предназначили, чтобы установить делегата mapView. Таким образом, правильный вызов будет [[self mapView] setDelegate:self] (или, если вы предпочитаете синтаксис точки, self.mapView.delegate = self.

Я еще не просмотрел остальную часть вашего кода ... посмотрите, не делает ли внесенные выше изменения, по крайней мере, (я не совсем уверен, что ваша классная архитектура здесь оптимальна, но на этом этапе нам не нужно справляться.)

+0

спасибо, я посмотрю на это – MJB

+0

@MJB Это исправить вашу проблему –

+0

это помогло. – MJB

Смежные вопросы