在 MKMapSnapshotter 上绘制一个 MKCircleRenderer
Draw a MKCircleRenderer on MKMapSnapshotter
我正在尝试在 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()
}
}
}
基于此解决方案:
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);
另一种方法是自己绘制此 MKCircle
,将 center
和 radius
属性转换为视图内的坐标。这会在当前上下文中呈现圆圈(我用它来向快照图像添加 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];
}
}
我正在尝试在 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()
}
}
}
基于此解决方案:
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);
另一种方法是自己绘制此 MKCircle
,将 center
和 radius
属性转换为视图内的坐标。这会在当前上下文中呈现圆圈(我用它来向快照图像添加 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];
}
}