3

OK this is actually three distinct questions in one thread:

1) I'm using:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [mapView setFrame :CGRectMake(-100,-100,520,520)];
    [mapView setAutoresizesSubviews:true];
    mapView.showsUserLocation = YES;

    locManager = [[CLLocationManager alloc] init];
    locManager.delegate = self;
    [locManager startUpdatingLocation];
    [locManager startUpdatingHeading];

    [bt_toolbar setEnabled:YES];
}


- (IBAction) CreatePicture
{
     CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(mapView.userLocation.coordinate.latitude, mapView.userLocation.coordinate.longitude);

     CGPoint annPoint = [self.mapView convertCoordinate:coord toPointToView:self.mapView];    
     mapPic = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pic.png"]];
     mapPic.frame = CGRectMake(annPoint.x, annPoint.y, 32, 32);
     [self.view addSubview:macPic];
}

to place an image using GCRectMake over the user's coordinates, but sadly the image is not being placed in the right spot:

Coordinate conversion gone wrong

And if i move the map, the picture will always be placed with the exact same offset regarding the user's location. What am i missing? Shouldn't it have been placed directly above the user? I'm guessing the offset (-100, -100) I gave the mapView in the first place is what's causing this (i've got a toolbar below, hence the offset).

2) My iOS 5 simulator is acting crazy, placing my location in Glendale, Phoenix (shouldn't it have been in Cupertino??) for some reason and acting as i were on the move due east; everything works fine in my iPhone 4 though (apart from the incorrect placement of the picture). Any ideas?

3) I've been thinking about using Annotations instead, but i've heard they're static (and i really need them dynamic). Is this true?

Thanks!

João Pereira
  • 3,545
  • 7
  • 44
  • 53
  • 1
    Can you include the part where you add mapPic to your view hierarchy? It sounds like you might be using mapView's coordinate system but placing mapPic in a superview (probably the view controller's view) which has a different coordinate system. – kalperin Dec 13 '11 at 12:36
  • Hi, thanks for replying. It's a simple addSubView, just added it. – João Pereira Dec 13 '11 at 14:52

3 Answers3

6

When adding a subview, its frame origin is relative to that of its superview. In this case you derived an origin from the map view and then added the image to the view controller's view. You would need to convert your image's origin to the self.view's coordinate system like this:

CGPoint imageOrigin = [self.view convertPoint:annPoint fromView:self.mapView];
mapPic.frame.origin = imageOrigin;
[self.view addSubview:macPic];

NB: this is untested code, but the principal is that you need to convert between the mapView's coordinate space (which is what you got from [self.mapView convertCoordinate:coord toPointToView:self.mapView]) to self.view's coordinate space. This example is a little contrived to be illustrative since an even simpler approach would be to use self.view's coordinate space in the first place:

CGPoint annPoint = [self.mapView convertCoordinate:coord toPointToView:self.view];    
kalperin
  • 509
  • 5
  • 20
  • It's not an exact match (the image won't totally overlay the blue dot) but it'll do. Thanks for the headsup! :) – João Pereira Dec 13 '11 at 22:57
  • Does the top left corner of your image line up with the center of your blue dot? Try centering your image view on the point. – kalperin Dec 14 '11 at 04:12
  • It does (line up). Is it possible to line up center of the image instead of the top left corner? If so, how? – João Pereira Dec 14 '11 at 10:01
2

I think you would be better off using a custom MKPinAnnotationView using your own image. as per this answer. Add image behind MKPinAnnotationView

Community
  • 1
  • 1
Nik Burns
  • 3,363
  • 2
  • 29
  • 37
2

MKMapView provides the following methods for translating between view space and geographic coordinates:

– convertCoordinate:toPointToView:
– convertPoint:toCoordinateFromView:
– convertRegion:toRectToView:
– convertRect:toRegionFromView:

These are good for tasks like translating touches to map coordinates. For the task you describe, I think a map overlay would be more appropriate than trying to draw on the map using a subview. An overlay is a kind of annotation that allows you to draw whatever content you like, but lets the map take care of determining when the overlay is visible and needs to be drawn at all.

3) I've been thinking about using Annotations instead, but i've heard they're static (and i really need them dynamic). Is this true?

What do you mean by "static" vs. "dynamic" here? Do you mean that you want to change the content in the overlay view? Or do you want to change the location of the overlay itself? I think it should be possible to update the overlay view as often as you need to. I'm not sure if you can move the overlay by simply adjusting it's boundingMapRect property, but I'd expect that to work. If it doesn't, you can always just remove the overlay and add it again.

Trying to create your own map overlay system instead of using the tools provided by MapKit should be the last thing on your list of options. Life is always easier when you can work with a framework instead of against it, and your code is much less likely to break in the future.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I want to change the location of the overlay itself; more specifically, i want to make it move to a set of coordinates (hence the whole dynamic vs static question). – João Pereira Dec 13 '11 at 22:47
  • Another thing: aren't map overlays kinda restricted, as in limited to drawing polygons? Can I use them to put images up on the map? – João Pereira Dec 13 '11 at 22:54
  • One final thing: @kalperin's answer did the trick for the main question, but since i actually asked three questions it's only fair that you get +50 rep. as well. How can we do this, should i repeat the question, send you the link, you answer and i give you +50? – João Pereira Dec 13 '11 at 22:59
  • @Hal No, you can draw whatever you like in an overlay. From the MKOverlayView docs: "You can subclass MKOverlayView to create overlays based on custom shapes and content." Some subclasses are provided in MapKit that do draw polygons and polylines, but you're not limited to those. I notice that MKOverlay's `boundingMapRect` is marked `readonly`, so I don't know if the map will notice changes, but again, you can always remove it from the map, change it, and add it again. I doubt the user would ever notice. – Caleb Dec 13 '11 at 23:02
  • @Hal I appreciate the consideration w.r.t. the bonus, but don't worry about it. I'd encourage you to try an overlay because I believe it's a better solution, but you should select a 'correct' answer and award any bonus based on what you think is the best answer. A bonus is just that -- nice to get, not something to expect. (And who knows? You might yet get better answers.) Good luck. – Caleb Dec 13 '11 at 23:07
  • You sure? I don't really care rep, i'm cool with awarding 50 more... seriously. Thank you for the insight, I've been tackling this project alone for quite some time now and I'm still uncomfortable with iOS programming in general and I was beginning to ponder calling it quits. – João Pereira Dec 13 '11 at 23:14