2

I am clearly not getting this. I'm trying to work out how to rotate a custom image of map annotations. i.e. multiple icons pointing different directions. I have loop'ed over a whole bunch of airplane data and I want to simply show the direction the plane is heading.

Review the code that I have managed to piece together to get at least half of it working and provide a suggestive idea on how to turn the image based on a variable.

Abstract View of the loop'ed data

             NSMutableArray *locations = [[NSMutableArray alloc]init];
             CLLocationCoordinate2D location;

             MKPointAnnotation *myAnn;
             myAnn = [[MKPointAnnotation alloc]init];
             location.latitude = nLatitudeFloat;
             location.longitude = nLongitudeFloat;
             myAnn.coordinate = location;
             myAnn.title = nRealname;

             //Add the Annotation object to the list so when the map is presented all points are listed on the map.
             [locations addObject:myAnn];

             //[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
             [self.mapView addAnnotations:locations];

Update of the annotation:

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    // If it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;

    // Handle any custom annotations.
    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        // Try to dequeue an existing pin view first.
        MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomPinAnnotationView"];

        if (!pinView)
        {
            // If an existing pin view was not available, create one.
            pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomPinAnnotationView"];
            pinView.canShowCallout = YES;

            pinView.image = [UIImage imageNamed:@"airplane21.png"] ;
            pinView.calloutOffset = CGPointMake(0, 32);
            pinView.transform = CGAffineTransformMakeRotation(30);    <------AT THE MOMENT I HAVE JUST HARD CODED THIS TO SEE IF IT WORKS. IT ROTATES THE ENTIRE ANNOTATION

            // Add a detail disclosure button to the callout.
            //UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            //pinView.rightCalloutAccessoryView = rightButton;

            // Add an image to the left callout.
            UIImageView *iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"airplane21.png"]];
            pinView.leftCalloutAccessoryView = iconView;
            iconView.transform = CGAffineTransformMakeRotation(30);  
        } else {
            pinView.annotation = annotation;
        }
        return pinView;
    }
    return nil;
}

Any ideas?

I have seen this by the way. I just wasn't confident to know if it would be suitable or not. Rotate annotation image on MKMapView

Community
  • 1
  • 1
Jeremy
  • 366
  • 5
  • 15

1 Answers1

1

I had the same problem and I have a solution that seems to work.

You need to first make a custom annotation that can hold the data that you want (ex. coordinates, your plane heading). When you loop through your data make sure you're using that custom annotation. For example

CustomAnnotation* annotation = [[CustomAnnotation alloc] init];
annotation.coordinates = ...
annotation.bearing = ...

Then in your viewForAnnotation method, you can get that info by doing something like

if ([annotation isKindOfClass:[CustomAnnotation class]]) {
    CustomAnnotation* myAnn = (CustomAnnotation*)annotation;
    double bearing = myAnn.bearing; // or whatever it's called

    ...
}

Hope this helped.

Edit: For rotating your image, I found the following code snippet somewhere. It works but it pixellates your image a little bit.

@interface UIImage (RotationMethods)
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end

@implementation UIImage (RotationMethods)

static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees
{
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    //UIGraphicsBeginImageContext(rotatedSize); // For iOS < 4.0
    UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 0.0);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    // Rotate the image context
    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

@end

Stick that in your .m, and on any UIImage you can now do [someUIImage imageRotatedByDegrees:yourDegrees];

So now in your viewForAnnotation method you can do something like

UIImage* image = [[UIImage imageNamed:@"yourImage.png"] imageRotatedByDegrees:degrees];
annView.image = image;
Patosai
  • 750
  • 1
  • 6
  • 16
  • Thanks...let me give that a go. I'm slightly behind on my work so I'll hopefully get to this today to try. – Jeremy Jun 10 '15 at 01:28
  • Well hey, it's been a month :P – Patosai Jun 10 '15 at 03:16
  • Yes. Its been mad busy and priorities have shifted. Anyway. Still working on it. I have the custom annotation but because I'm pulling through a large dataset via a completely different function and it simply doesn't want to play nice. I think I may need to rethink this. Would you happen to have a demo example to download so I could review? If not, no probs I'll keep looking. Thanks for your help even after a month hehe. :-P – Jeremy Jun 11 '15 at 01:10
  • Hey thanks I've got it half working but the Annotation popup is moving entirely around the image. That said what you recommended does work. So I'll give you the tick. Once fully identified I will put it up as well so if anyone else is having the same issue they can see a possible solution. – Jeremy Jun 15 '15 at 00:58
  • Awesome. Another thing - if you want to rotate just the image I believe you have to apply a transform to the annotation image itself and not the entire annotation, otherwise if you have text that pops up, that will be rotated as well. – Patosai Jun 15 '15 at 14:55
  • Yeah I think you are correct in saying that...Do you have any code snippets as an example? So far the code examples I have attempted have not helped so much. – Jeremy Jun 16 '15 at 01:27
  • If I could give you another tick I would! Awesome sauce! I am doing one tricky thing where I'm not using an image but rather a custom icon using PaintCode2. But man I'm stoked with just using an image. I'll upload the total result shortly. Extra tick for @Patosai ! – Jeremy Jun 16 '15 at 03:59
  • 1
    Okay I worked out how to fix up the blurred image in the code we need to change one line to allow for the newer type of iOS i.e. iOS > 4.0 instead of UIGraphicsBeginImageContext(rotatedSize); Use UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 0.0); This will use the proper image without the fuzzy edges. – Jeremy Jun 16 '15 at 21:06
  • 2
    Just tried it, the image does look a little better! Nice find. I stuck it in the code above. – Patosai Jun 16 '15 at 23:58