Reputation: 3484
I'm trying to draw a MKCircleRenderer
in a MKMapSnapshotter
.
So what I need:
So what I have:
My code:
+ (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();
}];
}
My annotation is correct, but the MKCircleRenderer
is drawn in a wrong coordinate.
UPDATE 1
After some tryings. I hade only one problem: correct radius size. My circle has 15meters radius value. But when I print on map has a 119 (I dont know about the unit)
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()
}
}
}
Based on this solution: 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);
Upvotes: 3
Views: 1013
Reputation: 438232
Another approach is to draw this MKCircle
yourself, converting the center
and radius
properties into coordinates within the view. This renders the circle within the current context (which I've used for adding MKCircle
overlays to a snapshot image):
// 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];
}
}
Upvotes: 1