0

I've been following the WWDC Sesion 127- Customizing Maps With Overlays. They say you can get the image to use as a MKOverlay either from the apps bundle or from the network. I would like to know if the image can be generated by the phone using it's APIs.

Has anyone done it? Can you maybe provide a tutorial?

Thanks.

[EDIT] I would also actually need a tutorial on how to add that image, created by the phone or downloadded from the network, to the map. All I see is the WWDC demo but you need the ticket to the conference, wich I obviously dont have.

subharb
  • 3,374
  • 8
  • 41
  • 72
  • what do you mean by "if the image can be generated by the phone using it's APIs" ? What is the source of your image ? File (.jpg, .png, etc) or NSData ? – Mutix Feb 24 '12 at 09:52

1 Answers1

1

Here is some code for drawing using Quartz into an UIImage. Hope it is helpful, and you can get the idea

void mainFunction() {
    // background size
    CGSize sizeBack = CGSizeMake(layerFrame.size.width*scaledFactor,layerFrame.size.height*scaledFactor);
    UIGraphicsBeginImageContext(sizeBack);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetRGBFillColor(context, 0., 0., 0., 1.);
    drawBorder(context, scaledRect);

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if (destinationLayer) {
       [destinationLayer setContents:(id)img.CGImage];
    }
}

CGPathRef createRoundedRectanglePath(CGRect mainRect, CGFloat roundRatio) {

    roundRatio = fabs(roundRatio);
    roundRatio = MIN(1, roundRatio);
    CGFloat offset = roundRatio * MIN(mainRect.size.width, mainRect.size.height)/2;

    CGPoint c1 = CGPointMake(0,0);
    CGPoint c2 = CGPointMake(mainRect.size.width,0);
    CGPoint c3 = CGPointMake(mainRect.size.width,mainRect.size.height);
    CGPoint c4 = CGPointMake(0,mainRect.size.height);

    CGPoint pA = CGPointMake(c1.x + offset, c1.y);
    CGPoint pB = CGPointMake(c2.x - offset, c2.y);
    CGPoint pC = CGPointMake(c2.x, c2.y + offset);
    CGPoint pD = CGPointMake(c3.x, c3.y - offset);
    CGPoint pE = CGPointMake(c3.x - offset, c3.y);
    CGPoint pF = CGPointMake(c4.x + offset, c4.y);
    CGPoint pG = CGPointMake(c4.x, c4.y - offset);
    CGPoint pH = CGPointMake(c1.x, c1.y + offset);


    CGMutablePathRef result = CGPathCreateMutable();
    CGPathMoveToPoint(result, NULL, pA.x, pA.y);

    CGPathAddLineToPoint(result, NULL, pB.x, pB.y);
    CGPathAddQuadCurveToPoint(result, NULL, c2.x, c2.y, pC.x, pC.y);

    CGPathAddLineToPoint(result, NULL, pD.x, pD.y);
    CGPathAddQuadCurveToPoint(result, NULL, c3.x, c3.y, pE.x, pE.y);

    CGPathAddLineToPoint(result, NULL, pF.x, pF.y);
    CGPathAddQuadCurveToPoint(result, NULL, c4.x, c4.y, pG.x, pG.y);

    CGPathAddLineToPoint(result, NULL, pH.x, pH.y);
    CGPathAddQuadCurveToPoint(result, NULL, c1.x, c1.y, pA.x, pA.y);

    CGPathCloseSubpath(result);

    CGPathRef path = CGPathCreateCopy(result);
    CGPathRelease(result);
    return path;
}

void drawBorder(CGContextRef context, CGRect rect) {
    CGContextSaveGState(context);
    /* Outside Path */
    CGPathRef thePath = createRoundedRectanglePath(rect, 0.2);

    /* Fill with Gradient Color */
    CGFloat locations[] = { 0.0, 1.0 };
    CGColorRef startColor = [UIColor colorWithRed:1.
                                            green:1.
                                             blue:1.
                                            alpha:1.].CGColor;
    CGColorRef endColor = [UIColor colorWithRed:208./255.                                          
                                          green:208./255.
                                           blue:208./255.
                                          alpha:1.].CGColor;


    NSArray *colors = [NSArray arrayWithObjects:(id)startColor, (id)endColor, nil];

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), 0);
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), rect.size.height);

    CGContextAddPath(context, thePath);
    CGContextClip(context);
    drawLinearGradient(context, startPoint, endPoint, locations, (CFArrayRef*)colors);

    /* Stroke path */
    CGPathRelease(thePath);
    thePath = createRoundedRectanglePath(rect, 0.2);
    CGContextSetStrokeColor(context, CGColorGetComponents([UIColor colorWithRed:0 green:0 blue:1. alpha:1.].CGColor));
    CGContextAddPath(context, thePath);
    CGContextSetLineWidth(context, 1.);
    CGContextDrawPath(context, kCGPathStroke);
    CGContextRestoreGState(context);
    CGPathRelease(thePath);
}
Ganzolo
  • 1,394
  • 12
  • 23
  • thanks, but what also would like to know is if I make that image using Quartz, will I then be able to add it to a map as an MKOverlay? – subharb Feb 24 '12 at 11:44
  • 1
    Yes this is possible, you need to subclass MKOverlayView, then override this method "drawMapRect:zoomScale:inContext:". In this method you can use quartz to draw directly your content. So you don't even need to make an UIImage! – Ganzolo Feb 24 '12 at 12:08
  • Do you happen to know a tutorial where I can do this? Im quite new to MKOverlays and Quartz, so it's all like witchcraft for me... – subharb Feb 24 '12 at 13:51
  • Look I found someone doing exactly this :) http://stackoverflow.com/questions/5283741/how-do-i-create-an-image-overlay-and-add-to-mkmapview – Ganzolo Feb 24 '12 at 16:15