2014-09-03 2 views
1

Я хочу создать MKOverlay, который объединяет несколько MKShapes вместе, но у меня проблемы с композиционным MKOverlayRenderer.Как сделать композитный MKOverlay

Я бы хотел сделать все это как отдельный MKOverlays и MKOverlayRenderers, потому что a) это много файлов, и б) они концептуально одинаковы.

Вот что у меня есть. От MyOverlay.h:

@property (nonatomic) CLLocationCoordinate2D coordinate; 
@property (nonatomic, readonly) MKMapRect boundingMapRect; 
@property (strong, nonatomic, readonly) MKCircle *circle; 
@property (strong, nonatomic, readonly) MKCircle *editCircle; 
@property (strong, nonatomic, readonly) MKPolyline *radiusLine; 

От MyOverlay.m:

- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate { 
    self = [super init]; 
    if (self) { 
     _coordinate = coordinate; 
     _circle = [MKCircle circleWithCenterCoordinate:_coordinate radius:_radius]; 
     _editCircle = [MKCircle circleWithCenterCoordinate:_coordinate radius:_radius * 0.1]; 
     CLLocationCoordinate2D offset = [self translateCoord:_coordinate distanceLat:0.0 distanceLong:_radius]; 
     CLLocationCoordinate2D coords[2]; 
     coords[0] = _coordinate; 
     coords[1] = offset; 
     _radiusLine = [MKPolyline polylineWithCoordinates:coords count:2]; 
     _boundingMapRect = MKMapRectUnion(MKMapRectUnion(_circle.boundingMapRect, _editCircle.boundingMapRect), _radiusLine.boundingMapRect); 
    } 
    return self; 
} 

От MyOverlayRenderer.m:

@interface MyOverlayRenderer() 

@property (nonatomic, strong) MKCircleRenderer *circleRenderer; 
@property (nonatomic, strong) MKCircleRenderer *editCircleRenderer; 
@property (nonatomic, strong) MKPolylineRenderer *radiusLineRenderer; 
@property (nonatomic) MKMapRect circleBoundingMapRect; 
@property (nonatomic) MKMapRect editCircleBoundingMapRect; 
@property (nonatomic) MKMapRect radiusLineBoundingMapRect; 

@end 

@implementation MyOverlayRenderer 

- (instancetype)initWithMyOverlay:(MyOverlay *)overlay { 
    self = [super initWithOverlay: overlay]; 
    if (self) { 
     _circleRenderer = [[MKCircleRenderer alloc] initWithCircle: overlay.circle]; 
     _circleRenderer.lineWidth = 2.0; 
     _circleRenderer.strokeColor = overlay.color; 
     _circleBoundingMapRect = overlay.circle.boundingMapRect; 
     CGFloat red, green, blue, alpha; 
     [overlay.color getRed:&red green:&green blue:&blue alpha:&alpha]; 
     _circleRenderer.fillColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha * 0.2]; 
     _editCircleRenderer = [[MKCircleRenderer alloc] initWithCircle:overlay.editCircle]; 
     _editCircleRenderer.fillColor = overlay.color; 
     _editCircleBoundingMapRect = overlay.editCircle.boundingMapRect; 
     _radiusLineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay.radiusLine]; 
     _radiusLineRenderer.lineWidth = 1.5; 
     _radiusLineRenderer.strokeColor = overlay.color; 
     _radiusLineRenderer.lineDashPattern = @[@2.0, @2.0]; 
     _radiusLineBoundingMapRect = overlay.radiusLine.boundingMapRect; 
    } 
    return self; 
} 

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { 
    double x = MKMapRectGetMidX(mapRect); 
    double y = MKMapRectGetMidY(mapRect); 
    CGContextSaveGState(context); 
    [_circleRenderer drawMapRect:_circleBoundingMapRect zoomScale:zoomScale inContext:context]; 
    CGContextRestoreGState(context); 
    CGContextSaveGState(context); 
    CGContextMoveToPoint(context, x, y); 
    [_editCircleRenderer drawMapRect:_editCircleBoundingMapRect zoomScale:zoomScale inContext:context]; 
    CGContextRestoreGState(context); 
    CGContextMoveToPoint(context, x, y); 
    [_radiusLineRenderer drawMapRect:_radiusLineBoundingMapRect zoomScale:zoomScale inContext:context]; 
} 

Результаты некрасиво. РадиусLine должен начинаться в центре круга, а отредактированный цикл должен быть по краю круга.

myOverlay Results

Я считаю, что моя ошибка в методе drawMapRect:zoomScale:inContext: - это только последний код, который я попробовал там - но я не уверен, что ошибка ....

ответ

1

Да, в проблема была в drawMapRect:zoomScale:inContext:. Я должен был перевести на начало каждого из элементов моего композита, прежде чем рисовать их. Это работает:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { 
    CGPoint p; 

    CGContextSaveGState(context); 
    p = [self pointForMapPoint:_circleMapRect.origin]; 
    CGContextTranslateCTM(context, p.x, p.y); 
    [_circleRenderer drawMapRect:_circleBoundingMapRect zoomScale:zoomScale inContext:context]; 

    CGContextRestoreGState(context); 
    CGContextSaveGState(context); 
    p = [self pointForMapPoint:_editCircleBoundingMapRect.origin]; 
    CGContextTranslateCTM(context, p.x, p.y); 
    [_editCircleRenderer drawMapRect:_editCircleBoundingMapRect zoomScale:zoomScale inContext:context]; 

    CGContextRestoreGState(context); 
    CGContextSaveGState(context); 
    p = [self pointForMapPoint:_radiusLineBoundingMapRect.origin]; 
    CGContextTranslateCTM(context, p.x, p.y); 
    [_radiusLineRenderer drawMapRect:_radiusLineBoundingMapRect zoomScale:zoomScale inContext:context]; 
    CGContextRestoreGState(context); 
} 

Much better.

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