【问题标题】:Draw a MKCircleRenderer on MKMapSnapshotter在 MKMapSnapshotter 上绘制一个 MKCircleRenderer
【发布时间】:2015-05-26 20:15:24
【问题描述】:

我正在尝试在MKMapSnapshotter 中绘制MKCircleRenderer

所以我需要:

所以我有什么:

我的代码:

+ (void)renderMapRegion:(MKCoordinateRegion)region
               withSize:(CGSize)size
             annotation:(MKAnnotationView *)annotation
         circleRenderer:(MKCircleRenderer *)circleRenderer
             completion:(CMMapViewRendererCallback)block
{
    MKMapSnapshotOptions *options = [MKMapSnapshotOptions new];
    options.region = region;
    options.scale = [UIScreen mainScreen].scale;
    options.size = size;

    MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];

    [snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
              completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {

                  if (error) {
                      block(nil, error);
                      return;
                  }

                  UIImage *image = snapshot.image;

                  UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
                  {
                      [image drawAtPoint:CGPointMake(0.0f, 0.0f)];
                      CGContextRef c = UIGraphicsGetCurrentContext();

                      if (circleRenderer.path) {
                          [circleRenderer applyFillPropertiesToContext:c atZoomScale:[UIScreen mainScreen].scale];
                          CGContextAddPath(c, circleRenderer.path);
                          CGContextFillPath(c);
                      }

                      CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
                      CGPoint point = [snapshot pointForCoordinate:annotation.annotation.coordinate];
                      if (CGRectContainsPoint(rect, point)) {
                          point.x = point.x + annotation.centerOffset.x - (annotation.bounds.size.width / 2.0f);
                          point.y = point.y + annotation.centerOffset.y - (annotation.bounds.size.height / 2.0f);
                          [annotation.image drawAtPoint:point];
                      }

                      UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext();
                      block(compositeImage,nil);
                  }

                  UIGraphicsEndImageContext();

              }];
}

我的注释是正确的,但是MKCircleRenderer 绘制的坐标有误。

更新 1

经过一番尝试。我只有一个问题:正确的半径大小。我的圈子有 15 米的半径值。但是当我在地图上打印时有一个 119(我不知道单位)

private func renderMap(#placemark: CLPlacemark?, annotationView: MKAnnotationView) {
        self.tempPlaceMark = placemark
        let region = MKCoordinateRegionMakeWithDistance(annotationView.annotation.coordinate, 5000, 5000)
        let circle = MKCircle(centerCoordinate: annotationView.annotation.coordinate, radius: radius!)
        var render = MKCircleRenderer(circle: circle)
        render.fillColor = Color.YellowColor

        CMMapViewRenderer.renderMapRegion(region, withSize: self.mapView.frame.size, annotation: annotationView, circleRenderer: render) { (image: UIImage!, error: NSError!) -> Void in
            dispatch_async(dispatch_get_main_queue()) {
                if error == nil {
                    self.tempCoordinate = annotationView.annotation.coordinate
                    self.tempSnapshotImage = image
                }
                self.dismissProgress()
            }
        }
    }

基于此解决方案:https://stackoverflow.com/a/8288467/846780

CGPoint circlePoint = [snapshot pointForCoordinate:annotation.annotation.coordinate];
CGRect boundingRect = [circleRenderer rectForMapRect:circleRenderer.circle.boundingMapRect];
CGFloat radius = boundingRect.size.width / 2;
CGContextSetStrokeColorWithColor(c, circleRenderer.fillColor.CGColor);
CGContextSetFillColorWithColor(c, circleRenderer.fillColor.CGColor);
CGContextSetLineWidth(c, 1);
CGContextSetShouldAntialias(c, YES);
CGContextAddArc(c, circlePoint.x, circlePoint.y, radius, 0, 2 * M_PI, true);
CGContextDrawPath(c, kCGPathFill);

【问题讨论】:

  • 您的circleRenderer 似乎是使用地图坐标绘制的,并未转换为快照的点坐标。
  • 我认为是这样,但是如何在特定位置绘制circleRenderer?
  • 您可以将您的圆圈捕获为新图像(上下文)并使用点坐标放置它。
  • 顺便说一句,与其把你的工作解决方案放在你的问题中,你可能会post your own answer to your question,这看起来很奇怪。

标签: ios objective-c iphone core-graphics


【解决方案1】:

另一种方法是自己绘制MKCircle,将centerradius 属性转换为视图内的坐标。这会在当前上下文中呈现圆圈(我已将其用于将 MKCircle 叠加层添加到快照图像中):

// use whatever colors you want

[[UIColor blueColor] setStroke];
[[[UIColor cyanColor] colorWithAlphaComponent:0.7] setFill];

// in my code, I'm iterating through the `overlays` objects, so I test to 
// see if it's a circle and cast appropriately

if ([overlay isKindOfClass:[MKCircle class]]) {
    CLLocationCoordinate2D coordinate = [(MKCircle *)overlay coordinate];
    CGPoint center = [snapshot pointForCoordinate:coordinate];
    CLLocationDistance radiusInMeters = [(MKCircle *)overlay radius];
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coordinate, radiusInMeters, 0);
    CGRect rect = [self.mapView convertRegion:region toRectToView:self.mapView];
    CGFloat radiusInPoints = rect.size.height;

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radiusInPoints startAngle:0 endAngle:M_PI * 2.0 clockwise:TRUE];

    if (CGRectIntersectsRect([path bounds], CGRectMake(0, 0, image.size.width, image.size.height))) {
        [path stroke];
        [path fill];
    }
}

【讨论】:

  • 我在这个类中没有 self.mapView 实例。我怎样才能得到“正确”?
  • 您的rectForMapRect 方法完成了同样的事情。给猫剥皮的两种方法。那么唯一的问题是您是否要使用 CoreGraphics 或 UIBezierPath。顺便说一句,如果相机不是直向下看,我们的两种方法都不能很好地工作(尽管rectForMapRect 可能会让你更接近)。我真的很讨厌这种可怕的“你必须自己绘制注释和覆盖”的愚蠢。
  • 唯一困难的是将半径圆转换为图像。这两种方法都让我感到困惑。
  • 如何转换circleRenderer.circle.radius?
  • 我不确定你为什么需要转换它。您正在从boundingRect 计算半径。没关系。您计算要绘制的圆弧的中心和半径与我不同,但我怀疑我们生成相同的值,并且您的方法很好(如果您没有地图视图,它可能会更好) .所以不要出汗。唯一的问题是,在计算了中心和半径之后,您是想用 Core Graphics 画圆还是只用stroke/fillUIBezierPath。两者都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
  • 2020-07-13
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多