October 8, 2013

Map Snapshots

By

Continuing the snapshotting topic from my earlier post, this post looks at the snapshotting capability included in MapKit.

To take a map snapshot in iOS 7, you can use the new MKMapSnapshotter class. This class takes snapshots asynchronously, always returning the best possible map image. For example, if you request a snapshot of a map before the tiles have loaded, MKMapSnapshotter will create the snapshot image when the tiles are available.

Taking a snapshot is easy. You simply create an MKMapSnapshotOptions instance, pass it to an MKMapSnapshotter, and call the MKMapSnapshotter’s Start method. When the snapshot is complete, you can get the image from the Image property of the MKMapSnapshot instance that is passed to the MKMapSnapshotCompletionHandler.

For example, the following code sets up map options to take a snapshot of a 500m region around the map’s center:

var coord = new CLLocationCoordinate2D(42.346751, -71.096946);
var region = MKCoordinateRegion.FromDistance (coord, 500, 500);
map.SetCenterCoordinate (coord, false);
snapshot.TouchUpInside += (sender, e) => {
  var options = new MKMapSnapshotOptions {
      Size = mapImageView.Bounds.Size,
      Region = region,
      MapType = MKMapType.Hydrid
  };
  var snapper = new MKMapSnapshotter (options);
  snapper.Start ((snap, err) => {
      if (err == null) {
          mapImageView.Image = snap.Image;
      }
  });
};

This results in the image snapshot shown below:

As you can see, the snapshot does not need to match the map exactly. You can snapshot a portion of the map, as well as alter other aspects of the map snapshot from the original map, such as the size. You can even have the snapshot be a different map type than the displayed map. In fact, you don’t even need to have a displayed map, as the¬†MKMapSnapshotter instance is completely independent of any MKMapView you may have in the application.

For example, setting the MapType to MKMapType.Standard in the MKMapSnapshotOptions results in a standard map snapshot, while the map itself remains a hybrid type:

The code from this post is available here.

TwitterFacebookGoogle+LinkedInEmail