2017-03-09 54 views
0

我是iOS开发新手,我正在努力从iOS6移植一些涉及使用MKOverlay的代码。MKOverlayRenderer在渲染MKOverlay时被截断,但通过缩小来修复

当叠加半径或坐标发生变化时,渲染器应该实时更新相应的显示。

这部分工作,但如果我拖动覆盖太多,它达到了一些边界和渲染被切断。我无法找到任何文档或有关此行为的帮助。

CircleOverlayRenderer类:

- (id)initWithOverlay:(id<MKOverlay>)overlay 
{ 
    self = [super initWithOverlay:overlay]; 
    if (self) { 
     CircleZone *bOverlay = (CircleZone *)overlay; 
     [RACObserve(bOverlay, coordinate) subscribeNext:^(id x) { 
      [self setNeedsDisplay]; 
     }]; 
     [RACObserve(bOverlay, radius) subscribeNext:^(id x) { 
      [self setNeedsDisplay]; 
     }]; 
    } 
    return self; 
} 

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context 
{ 
    CGRect rect = [self rectForMapRect:[self.overlay boundingMapRect]]; 

    CGContextSaveGState(context); 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextSetFillColorSpace(context, colorSpace); 
    CGColorSpaceRelease(colorSpace); 

    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    CGContextSetFillColor(context, color); 
    CGContextSetAllowsAntialiasing(context, YES); 

    // outline 
    { 
     CGContextSetAlpha(context, 0.8); 
     CGContextFillEllipseInRect(context, rect); 
    } 

    // red 
    { 
     CGContextSetAlpha(context, 0.5); 
     CGRect ellipseRect = CGRectInset(rect, 0.01 * rect.size.width/2, 0.01 * rect.size.height/2); 
     CGContextFillEllipseInRect(context, ellipseRect); 
    } 

    CGContextRestoreGState(cox); 
} 

CircleOverlay类:

- (MKMapRect)boundingMapRect 
{ 
    MKMapPoint center = MKMapPointForCoordinate(self.coordinate); 
    double mapPointsPerMeter = MKMapPointsPerMeterAtLatitude(self.coordinate.latitude); 
    double mapPointsRadius = _radius * mapPointsPerMeter; 

    return MKMapRectMake(center.x - mapPointsRadius, center.y - mapPointsRadius, 
         mapPointsRadius * 2.0, mapPointsRadius * 2.0); 
} 

下面是我看到这个问题的一些屏幕截图:

问题拖动重叠时太太多: Problem when dragging overlay too much

更改半径时出现问题: Problem when changing the radius

如果我继续缩放地图,问题确实消失。在地图磁贴刷新后,重叠不再被切断...

如果有人有类似的问题,请帮助我,这让我疯狂!

回答

0

看看radius的例子,它让我怀疑boundingMapRect,鉴于它的种植情况。看boundingMapRect的实现,依赖MKMapPointsPerMeterAtLatitude(尤其是当你看到一个大的区域时)令人担忧。例如,如果您试图找出与某个其他坐标相距10米的坐标,但在查看非常大的跨度时,该功能非常有用,但它并不总能很好地工作。

相反,我可能会建议一些获取圆圈所在位置的MKCoordinateRegion,然后将其转换为MKMapRect。一个简单的实现可能是这样的:

- (MKMapRect)boundingMapRect { 
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.coordinate, _radius * 2, _radius * 2); 

    CLLocationCoordinate2D upperLeftCoordinate = CLLocationCoordinate2DMake(region.center.latitude - region.span.latitudeDelta/2, region.center.longitude - region.span.longitudeDelta/2); 
    CLLocationCoordinate2D lowerRightCoordinate = CLLocationCoordinate2DMake(region.center.latitude + region.span.latitudeDelta/2, region.center.longitude + region.span.longitudeDelta/2); 

    MKMapPoint upperLeft = MKMapPointForCoordinate(upperLeftCoordinate); 
    MKMapPoint lowerRight = MKMapPointForCoordinate(lowerRightCoordinate); 

    return MKMapRectMake(MIN(upperLeft.x, lowerRight.x), 
         MIN(upperLeft.y, lowerRight.y), 
         ABS(upperLeft.x - lowerRight.x), 
         ABS(upperLeft.y - lowerRight.y)); 
} 

你必须用这个来调整,以确保它优雅地处理180度经线的交叉,当圆涵盖了北极,但它说明了基本的想法: MKCoordinateRegion为圆,然后将其转换为MKMapRect

+0

我以为剪裁最初受到'boundingMapRect'的影响,但实际上改变'boundingMapRect'只会改变圆的大小。不幸的是,我仅限于我的问题中的2个链接,但拖动叠加层实际上会导致沿着相同的地图块裁剪。谢谢你让我知道'MKMapPointsPerMeterAtLatitude'的不准确性,但是在不同的缩放比例下裁剪差别很大,似乎是与比例无关的。 (更缩放它,它在更小的半径处剪辑) – kudos

+0

我仍然认为,不正确的'boundingMapRect'(调整大小时的大小错误或拖动过程中的错误位置)将按照您在问题中说明的方式显示。请注意,如果'boundingMapRect'太小,它可以表现为不呈现整个叠加层,但是具有直接裁剪,但不一定如此。地图使用矩形图块,所以它使用'boundingMapRect'来知道哪些图块需要重新渲染。这可能是错误的大小,或者是错误的地方(或两者)。 – Rob

+0

@ kudos - 您的图像看起来像是在手势中呈现地图,但是“boundingMapRect”可能会返回过期的值。或者你可能需要确保'boundingMapRect'计算当前的'MKMapRect',但是返回整个手势中那个和所有先前计算值的联合。但是当你随后在地图上缩小时,我会毫不犹豫地根据叠加层的正确渲染得出任何结论。这可能是瓷砖更大。这可能是很多事情。没有可重现的问题例子很难说。 – Rob