Skip to content

Instantly share code, notes, and snippets.

@franciscojma86
Last active July 7, 2020 00:22
Show Gist options
  • Save franciscojma86/9826205 to your computer and use it in GitHub Desktop.
Save franciscojma86/9826205 to your computer and use it in GitHub Desktop.
MKSnapshotter Implementation
#import "MyViewController.h"
#import <MapKit/MapKit.h>
@interface MyViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *mapImageView;
@end
//helper method to get the rect in the map for an array of points
MKMapRect MapRectBoundingMapPoints(MKMapPoint points[], NSUInteger pointCount){
double minX = INFINITY, maxX = -INFINITY, minY = INFINITY, maxY = -INFINITY;
NSInteger i;
for (i = 0; i < pointCount; i++) {
MKMapPoint p = points[i];
minX = MIN(p.x, minX);
minY = MIN(p.y, minY);
maxX = MAX(p.x, maxX);
maxY = MAX(p.y, maxY);
}
return MKMapRectMake(minX, minY, maxX - minX, maxY - minY);
}
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self prepareSnapshot];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark map snapshooting
-(MKMapSnapshotOptions *)snapshotOptionsWithRegion:(MKCoordinateRegion)coordinateRegion
{
//create the optionn for the snapshotter
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc]init];
//we passed the region previously created
options.region = coordinateRegion;
options.scale = [[UIScreen mainScreen] scale]; // get the scale depending on the device resolution
options.size = self.mapImageView.frame.size;//this is the image view that is going to display the snapshot
//you can also define a camera for the options, to rotate heading pitch and other variables, but we won't do this here.
return options;
}
-(void)createSnapshotWithOptions:(MKMapSnapshotOptions *)options fristCoords:(CLLocationCoordinate2D)firstCoords secondCoords:(CLLocationCoordinate2D)secondCoords
{
//create the snapshotter
MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc]initWithOptions:options];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
if (error) {
NSLog(@"error %@",error);
return ;
}
UIImage *image = snapshot.image;
//create a pin to get the pin image
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc]initWithAnnotation:nil reuseIdentifier:@""];
pin.pinColor = MKPinAnnotationColorPurple;
UIImage *firstPointPinImage = pin.image;
pin.pinColor = MKPinAnnotationColorGreen;
UIImage *secondPointPinImage = pin.image;
CGPoint firstPoint = [snapshot pointForCoordinate:firstCoords];
CGPoint secondPoint = [snapshot pointForCoordinate:secondCoords];
//move the pin so that the "base" of the pin points to the right spot
CGPoint pinCenterOffset = pin.centerOffset;
firstPoint.x -= pin.bounds.size.width / 2.0;
firstPoint.y -= pin.bounds.size.height / 2.0;
firstPoint.x += pinCenterOffset.x;
firstPoint.y += pinCenterOffset.y;
secondPoint.x -= pin.bounds.size.width / 2.0;
secondPoint.y -= pin.bounds.size.height / 2.0;
secondPoint.x += pinCenterOffset.x;
secondPoint.y += pinCenterOffset.y;
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
//draw the pins on the image
[image drawAtPoint:CGPointMake(0, 0)];
[firstPointPinImage drawAtPoint:firstPoint];
[secondPointPinImage drawAtPoint:secondPoint];
//get the final image with the pins on top
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.mapImageView setImage:finalImage];
}];
}
-(void)prepareSnapshot
{
//get the coordinates to show
CLLocationCoordinate2D firstPoint = CLLocationCoordinate2DMake(37.425105, -122.126424);
CLLocationCoordinate2D secondPoint = CLLocationCoordinate2DMake(37.430285, -122.168309);
MKMapPoint points[] = {
MKMapPointForCoordinate(firstPoint),
MKMapPointForCoordinate(secondPoint)
};
//create the region with the helper method previously declared
MKMapRect rect = MapRectBoundingMapPoints(points, 2);
//create the region with padding
rect = MKMapRectInset(rect,
-rect.size.width * 0.05,
-rect.size.height * 0.05);
MKCoordinateRegion coordinateRegion = MKCoordinateRegionForMapRect(rect);
//create the options for the snapshotter
//a snapshot requires some options to be defined, more on that on the next method
MKMapSnapshotOptions *options = [self snapshotOptionsWithRegion:coordinateRegion];
//create snapshotter and execute the snapshot
[self createSnapshotWithOptions:options
fristCoords:firstPoint
secondCoords:secondPoint];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment