Swift 3 Add a custom note to MKMapSnapShotter

I learn Swift 3 myself, and my current training project assumes that the user can click a photo and get a map snapshot with the current location pinned.

I have relied on this answer since August 2015 and this answer since June 2016 for guidance, but I still cannot find the right path.

Now I can ...

  • Get photo from clipboard
  • Get a map snapshot

But I just can't put a pin. I know that my code is incomplete and inefficient - so this is not just a debugging issue. Here's what I worked for (like many of the options based on the links above):

let snapShotter = MKMapSnapshotter(options: mapSnapshotOptions) snapShotter.start() { snapshot, error in guard let snapshot = snapshot else { return } let image = snapshot.image let annotation = MKPointAnnotation() annotation.coordinate = needleLocation // is a CLLocationCoordinate2D annotation.title = "My Title" let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotation") // I want to push the final image to a global variable // can't figure out how to define finalImage as the pinned map self.myMap = finalImage } // close snapShotter.start 

I was stuck for a few days, so of course I would appreciate any ideas. Thanks!

+7
source share
2 answers

To visualize MKMapSnapshot with annotation views, you must manually draw an image snapshot and an image annotation view in a new graphics context and get a new image from that context. In Swift 3:

 let rect = imageView.bounds let snapshot = MKMapSnapshotter(options: options) snapshot.start { snapshot, error in guard let snapshot = snapshot, error == nil else { print(error ?? "Unknown error") return } let image = UIGraphicsImageRenderer(size: options.size).image { _ in snapshot.image.draw(at: .zero) let pinView = MKPinAnnotationView(annotation: nil, reuseIdentifier: nil) let pinImage = pinView.image var point = snapshot.point(for: location.coordinate) if rect.contains(point) { point.x -= pinView.bounds.width / 2 point.y -= pinView.bounds.height / 2 point.x += pinView.centerOffset.x point.y += pinView.centerOffset.y pinImage?.draw(at: point) } } // do whatever you want with this image, eg DispatchQueue.main.async { imageView.image = image } } 

This was adapted from fooobar.com/questions/143990 / ... , which itself was adapted from a WWDC 2013 video MapKit port in perspective .

Here is an example snapshot from a .satelliteFlyover :

enter image description here

+20
source

I was getting an error from Rob code that defines "rect" because my MKMapSnapshotter image is a UIImage. However .bounds is a property of UIImageView, not UIImage. Thus, the definition of the rectangle causes an error.

Here's how I set up the options:

  let mapSnapshotOptions = MKMapSnapshotOptions() // Set the region of the map that is rendered. let needleLocation = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude) let region = MKCoordinateRegionMakeWithDistance(needleLocation, 1000, 1000) mapSnapshotOptions.region = region // Set the scale of the image. We'll just use the scale of the current device, which is 2x scale on Retina screens. mapSnapshotOptions.scale = UIScreen.main.scale // Set the size of the image output. mapSnapshotOptions.size = CGSize(width: 300, height: 300) // Show buildings and Points of Interest on the snapshot mapSnapshotOptions.showsBuildings = true mapSnapshotOptions.showsPointsOfInterest = false 

So is there any other way to access the .bounds property? Or did I incorrectly create my picture?

0
source

All Articles