-->

Trouble converting MapKit user coordinates to scre

2020-07-22 18:20发布

问题:

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:

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!

回答1:

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];    


回答2:

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



回答3:

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.