3

Is it possible to display a static image instead of the default MapView, where the current location is always the center of the image?

I want to display an image where the center is current position and add pins on it depending on coordinates (distance and direction). I want to calculate distance between too and maybe rotate the image/pins depending on which direction the phone is pointing.

I thought it might be easiest to do with a MKMapView and replace it with a static image, as I can use all the build-in functionality, but right now it seems impossible to change the map to a static image?

I could also just paint directly on an image, but how would that work, and should I do that? I guess it would be something with polar coordinates.

Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
Emil Moe
  • 389
  • 5
  • 18

3 Answers3

8

With iOS7, you have MKMapSnapshotter which can render a snapshot of a map region in a background thread. You can then take an image of that snapshot.

MKMapSnapshotOptions* options = [MKMapSnapshotOptions new];
//Setup options here:
options.camera = ...
options.region = ...

MKMapSnapshotter* snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) completionHandler:^(MKMapSnapshot* snapshot, NSError* error) {

    // get the image associated with the snapshot

    UIImage *image = snapshot.image;

    dispatch_async(dispatch_get_main_queue(), ^ {
        //Make sure to access UIKit UI elements on the main thread!
        [self.imageView setImage: image];
    });
}
Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • You can use `- (void)startWithCompletionHandler:(MKMapSnapshotCompletionHandler)completionHandler` to execute in the background more easily. – Andrew Robinson Aug 28 '14 at 22:50
  • Nice but per Apple doc, you have to draw pins yourself: `Snapshotter objects do not capture the visual representations of any overlays or annotations that your app creates. If you want those items to appear in the final snapshot, you must draw them on the resulting snapshot image.`which is sadly more painful than Google Maps Static API. – Skoua Jun 24 '16 at 12:45
  • Adding the pins is actually as easy as just drawing them on top of the image. On the other hand, Google Maps license agreement forbids you to share snapshots outside of the device they were taken on. – Léo Natan Jun 24 '16 at 12:47
5

You could use Google's static map API if you want. That's pretty straightforward. Here is a static image from somewhere in Copenhagen, DK:

NSData *data = [NSData dataWithContentsOfURL:@"http://maps.googleapis.com/maps/api/staticmap?center=55.675861+12.584574&zoom=15&size=400x400&sensor=false"];
UIImage *img = [UIImage imageWithData:data];

You can then add markers as you want - take a look here on how to add them. Here is a test URL for adding a red marker with the text "M" in the middle:

http://maps.googleapis.com/maps/api/staticmap?center=55.675861+12.584574&zoom=15&size=400x400&sensor=false&markers=color:red%7Clabel:M%7C55.675861+12.584574

Decoding the marker part of the URL:

markers=color:red%7Clabel:M%7C55.675861+12.584574

You get this:

markers=color:red|label:M|55.675861 12.584574

Edit:

Here is an approach that scrapes an image of the map control. If we extract the important part of the answer this is basically how you could do it:

UIGraphicsBeginImageContextWithOptions(map.bounds.size, map.opaque, 0.0);
[map.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Note that map is required to derive from UIView, which means you can use this trick on a variety of controls.

Edit 2:

You should also take a look at this article. Really well written an covers a lot of topics in relation to this with overlays, pins and so on.

Community
  • 1
  • 1
Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
  • Would it be possible to change that static map to another image (nothing to do with a map) and still use the functionality? And what if the person moves, then I need to reposition everything. – Emil Moe Feb 27 '14 at 14:51
  • I edited the answer to include a link to another answer where I extracted the important part. – Morten Kristensen Feb 27 '14 at 15:04
0

I have written a handy category on UIImageView that allows for easy map preview creation based on MKMapView - it's supposed to work exactly the same way as AFNetworking for async image downs. Hope you will find it useful. BGMapPreview

cryptic_star
  • 1,863
  • 3
  • 26
  • 47