问题 使用MKPolylineRenderer创建MKMapSnapshotter


我以为iOS 7的 MKMapSnapshotters将是一个拍摄快照的简单方法 MKMapView,好处是您可以在不将地图加载到视图中的情况下执行此操作。即使添加引脚和覆盖图似乎更多工作(因为需要核心图形)。 WWDC视频提供了创建一个非常好的例子 MKMapSnapshotter 添加一个 MKAnnotationView

但是,对于没有很多核心图形体验的人来说,创建一个不是很明显的 MKMapSnapshotter 从一个 MKPolylineRenderer

我试过这样做,但路径不准确。它准确地绘制了大约10%的线,但随后直接绘制了剩余的路径。

这是我的代码:

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

[snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
          completionHandler:^(MKMapSnapshot *snapshot, NSError *error)
{
            if (error == nil)
            {
                UIImage *mapSnapshot = [snapshot image];

                UIGraphicsBeginImageContextWithOptions(mapSnapshot.size,
                                                       YES,
                                                       mapSnapshot.scale);

                [mapSnapshot drawAtPoint:CGPointMake(0.0f, 0.0f)];

                CGContextRef context = UIGraphicsGetCurrentContext();

                //Draw the points from the MKPolylineRenderer in core graphics for mapsnapshotter...
                MKPolylineRenderer *overlay = (MKPolylineRenderer *)[self.mapView rendererForOverlay:[_mapView.overlays lastObject]];

                if (overlay.path)
                {
                    CGFloat zoomScale = 3.0;

                    [overlay applyStrokePropertiesToContext:context
                                                atZoomScale:zoomScale];

                    CGContextAddPath(context, overlay.path);
                    CGContextSetLineJoin(context, kCGLineJoinRound);
                    CGContextSetLineCap(context, kCGLineCapRound);
                    CGContextStrokePath(context);
                }

                UIImage *pathImage = UIGraphicsGetImageFromCurrentImageContext();

                [map addMapIcon:pathImage];
                UIGraphicsEndImageContext();
            }
}];

对于如何做到这一点,有没有人有一个很好的可行的例子?


10703
2018-03-27 15:39


起源



答案:


刚遇到同样的问题,这段代码似乎有效:

UIImage * res = nil;
UIImage * image = snapshot.image;

UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
[image drawAtPoint:CGPointMake(0, 0)];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetStrokeColorWithColor(context,  [COLOR_FLASHBLUE CGColor]);
CGContextSetLineWidth(context,2.0f);
CGContextBeginPath(context);

CLLocationCoordinate2D coordinates[[polyline pointCount]];
[polyline getCoordinates:coordinates range:NSMakeRange(0, [polyline pointCount])];

for(int i=0;i<[polyline pointCount];i++)
{
    CGPoint point = [snapshot pointForCoordinate:coordinates[i]];

    if(i==0)
    {
        CGContextMoveToPoint(context,point.x, point.y);
    }
    else{
        CGContextAddLineToPoint(context,point.x, point.y);

    }
}

CGContextStrokePath(context);

res = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

12
2018-03-28 15:12



有趣的是,您必须明确移动并添加行而不是使用CGContextAddPath。谢谢,我还没有尝试过,但会检查出来:) - PostCodeism
我不确定你是否必须这样做。我不知道zoomlevel,所以不得不使用pointForCoordiinate方法。 - Sander Backus
这对我也有用。我仍然很想知道为什么CGContextAddPath不起作用> _ < - PostCodeism
Tjhis很棒!!! - user523234
初始的目的是什么? [image drawAtPoint:CGPointMake(0, 0)]; ?此外,我在此之前已将一些引脚注释作为图像绘制到快照图像上,当我添加路线时,引脚消失。我是否需要在不同的环境中做某些事情? - shim


答案:


刚遇到同样的问题,这段代码似乎有效:

UIImage * res = nil;
UIImage * image = snapshot.image;

UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
[image drawAtPoint:CGPointMake(0, 0)];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetStrokeColorWithColor(context,  [COLOR_FLASHBLUE CGColor]);
CGContextSetLineWidth(context,2.0f);
CGContextBeginPath(context);

CLLocationCoordinate2D coordinates[[polyline pointCount]];
[polyline getCoordinates:coordinates range:NSMakeRange(0, [polyline pointCount])];

for(int i=0;i<[polyline pointCount];i++)
{
    CGPoint point = [snapshot pointForCoordinate:coordinates[i]];

    if(i==0)
    {
        CGContextMoveToPoint(context,point.x, point.y);
    }
    else{
        CGContextAddLineToPoint(context,point.x, point.y);

    }
}

CGContextStrokePath(context);

res = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

12
2018-03-28 15:12



有趣的是,您必须明确移动并添加行而不是使用CGContextAddPath。谢谢,我还没有尝试过,但会检查出来:) - PostCodeism
我不确定你是否必须这样做。我不知道zoomlevel,所以不得不使用pointForCoordiinate方法。 - Sander Backus
这对我也有用。我仍然很想知道为什么CGContextAddPath不起作用> _ < - PostCodeism
Tjhis很棒!!! - user523234
初始的目的是什么? [image drawAtPoint:CGPointMake(0, 0)]; ?此外,我在此之前已将一些引脚注释作为图像绘制到快照图像上,当我添加路线时,引脚消失。我是否需要在不同的环境中做某些事情? - shim