在没有MKMapView的情况下生成MKPolyline的小缩略图?

时间:2015-12-01 19:15:01

标签: ios objective-c uiimage mkmapview mkoverlay

我们的应用程序包含几个MKPolyline边界,这些边界都创建一个封闭的多边形。这些主要是在MKMapView上显示为MKOverlay,但我正在寻找一种解决方案,将这些多边形显示为小缩略图,而不是在MKMapView上可见,而是作为标准UIImage或UIImageView显示。

为了清楚起见,我希望这些小缩略图只显示为具有笔触颜色和填充颜色但没有任何地图背景的小形状。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:0)

你走了。

+ (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color{
    // load the image
    UIImage *img = [UIImage imageNamed:name];

    // begin a new image context, to draw our colored image onto
    UIGraphicsBeginImageContext(img.size);

    // get a reference to that context we created
    CGContextRef context = UIGraphicsGetCurrentContext();

    // set the fill color
    [color setFill];

    // translate/flip the graphics context (for transforming from CG* coords to UI* coords
    CGContextTranslateCTM(context, 0, img.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // set the blend mode to color burn, and the original image
    CGContextSetBlendMode(context, kCGBlendModeColorBurn);
    CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
    CGContextDrawImage(context, rect, img.CGImage);

    // set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
    CGContextClipToMask(context, rect, img.CGImage);
    CGContextAddRect(context, rect);
    CGContextDrawPath(context,kCGPathFill);

    // generate a new UIImage from the graphics context we drew onto
    UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //return the color-burned image
    return coloredImg;
}

请查看此original帖子了解详细说明。

答案 1 :(得分:0)

我必须在自己的应用中执行完全相同的操作。这是我的解决方案:我生成一个UIView,它表示路径的形状。在您的情况下,路径为MKPolyline

这是我的代码:

+ (UIView *)createShapeForGPX:(GPX *)gpx
                withFrameSize:(CGSize)frameSize
                    lineColor:(UIColor *)lineColor {

    // Array of coordinates (Adapt this code with your coordinates)
    // Note : in my case I have a double loops because points are in paths 
    // and I can have many paths for one route. So I concact all points 
    // into one array to simplify the code for your case. If you also have
    // many paths, you have to change a little bit next code.
    NSMutableArray<NSValue *> *dataPoints = [NSMutableArray new];
    for (NSArray *path in gpx.paths) {
        for (NSDictionary *point in path) {
            double latitude = [point[@"latitude"] doubleValue];
            double longitude = [point[@"longitude"] doubleValue];
            [dataPoints addObject:[NSValue valueWithCGPoint:CGPointMake(longitude, latitude)]];
        }
    }

    // Graph bounds (You need to calculate topRightCoordinate and bottomleftCoordinate. You can do it in previous for loop)
    double lngBorder = gpx.topRightCoordinate.longitude - gpx.bottomLeftCoordinate.longitude;
    double latBorder = gpx.topRightCoordinate.latitude - gpx.bottomLeftCoordinate.latitude;

    double middleLng = gpx.bottomLeftCoordinate.longitude + (lngBorder / 2.f);
    double middleLat = gpx.bottomLeftCoordinate.latitude + (latBorder / 2.f);

    double boundLength = MAX(lngBorder, latBorder);

    // *** Drawing ***
    CGFloat margin = 4.f;
    UIView *graph = [UIView new];
    graph.frame = CGRectMake(0, 0, frameSize.width - margin, frameSize.height - margin);

    CAShapeLayer *line = [CAShapeLayer layer];
    UIBezierPath *linePath = [UIBezierPath bezierPath];

    float xAxisMin = middleLng - (boundLength / 2.f);
    float xAxisMax = middleLng + (boundLength / 2.f);
    float yAxisMin = middleLat - (boundLength / 2.f);
    float yAxisMax = middleLat + (boundLength / 2.f);

    int i = 0;
    while (i < dataPoints.count) {

        CGPoint point = [dataPoints[i] CGPointValue];

        float xRatio = 1.0-((xAxisMax-point.x)/(xAxisMax-xAxisMin));
        float yRatio = 1.0-((yAxisMax-point.y)/(yAxisMax-yAxisMin));

        float x = xRatio*(frameSize.width - margin / 2);
        float y = (1.0-yRatio)*(frameSize.height - margin);

        if (i == 0) {
            [linePath moveToPoint:CGPointMake(x, y)];
        } else {
            [linePath addLineToPoint:CGPointMake(x, y)];
        }
        i++;
    }

    // Line
    line.lineWidth = 0.8;
    line.path = linePath.CGPath;
    line.fillColor = [[UIColor clearColor] CGColor];
    line.strokeColor = [lineColor CGColor];
    [graph.layer addSublayer:line];

    graph.backgroundColor = [UIColor clearColor];

    // Final view (add margins)
    UIView *finalView = [UIView new];
    finalView.backgroundColor = [UIColor clearColor];
    finalView.frame = CGRectMake(0, 0, frameSize.width, frameSize.height);
    graph.center = CGPointMake(CGRectGetMidX(finalView.bounds), CGRectGetMidY(finalView.bounds));
    [finalView addSubview:graph];

    return finalView;
}

在我的情况下,GPX类包含几个值:
-NSArray<NSArray<NSDictionary *> *> *paths;:包含所有路径的所有点。就您而言,我认为是您的MKPolyline
-topRightCoordinatebottomLeftCoordinate:两个CLLocationCoordinate2D代表我的路径的右上和左下虚拟坐标(您也必须计算它们)。

您可以这样调用此方法: UIView *shape = [YOURCLASS createShapeForGPX:gpx withFrameSize:CGSizeMake(32, 32) lineColor:[UIColor blackColor]];

此解决方案基于问题how to draw a line graph in ios? Any control which will help me show graph data in ios,该问题提供了从点绘制图形的解决方案。

也许所有这些代码对您都不有用(例如边距),但它应该可以帮助您找到自己的解决方案。

这是它在我的应用中(在UITableView中的显示方式):

enter image description here