2014-09-03 138 views
1

我想创建一个将几个MKShapes组合在一起的MKOverlay,但是我遇到了合成MKOverlayRenderer的问题。如何渲染复合MKOverlay

我想避免把这些全部作为单独的MKOverlay和MKOverlayRenderers,因为a)这是很多文件,b)它们在概念上是相同的东西。

这是我的。从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]; 
} 

的结果是丑陋的。半径线应该始于圆的中心,并且editCircle应该沿着圆的边。

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.