Skip to content

Instantly share code, notes, and snippets.

@phildow
Last active December 2, 2019 02:37
Show Gist options
  • Save phildow/6043486 to your computer and use it in GitHub Desktop.
Save phildow/6043486 to your computer and use it in GitHub Desktop.
Category to create GPS metadata dictionary from CLLocation and CLHeading for writing to EXIF data in images.
#import <CoreLocation/CoreLocation.h>
#import <ImageIO/ImageIO.h>
@interface CLLocation (EXIFGPS)
- (NSDictionary*) EXIFMetadataWithHeading:(CLHeading*)heading;
@end
@interface NSDate (EXIFGPS)
- (NSString*) ISODate;
- (NSString*) ISOTime;
@end
#import "CLLocation+EXIFGPS.h"
NSString * const ISODateFormat = @"yyyy-MM-dd";
NSString * const ISOTimeFormat = @"HH:mm:ss.SSSSSS";
@implementation CLLocation (EXIFGPS)
- (NSDictionary*) EXIFMetadataWithHeading:(CLHeading*)heading
{
NSMutableDictionary *GPSMetadata = [NSMutableDictionary dictionary];
NSNumber *altitudeRef = [NSNumber numberWithInteger: self.altitude < 0.0 ? 1 : 0];
NSString *latitudeRef = self.coordinate.latitude < 0.0 ? @"S" : @"N";
NSString *longitudeRef = self.coordinate.longitude < 0.0 ? @"W" : @"E";
NSString *headingRef = @"T"; // T: true direction, M: magnetic
// GPS metadata
[GPSMetadata setValue:[NSNumber numberWithDouble:ABS(self.coordinate.latitude)] forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSMetadata setValue:[NSNumber numberWithDouble:ABS(self.coordinate.longitude)] forKey:(NSString*)kCGImagePropertyGPSLongitude];
[GPSMetadata setValue:latitudeRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
[GPSMetadata setValue:longitudeRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
[GPSMetadata setValue:[NSNumber numberWithDouble:ABS(self.altitude)] forKey:(NSString*)kCGImagePropertyGPSAltitude];
[GPSMetadata setValue:altitudeRef forKey:(NSString*)kCGImagePropertyGPSAltitudeRef];
[GPSMetadata setValue:[self.timestamp ISOTime] forKey:(NSString*)kCGImagePropertyGPSTimeStamp];
[GPSMetadata setValue:[self.timestamp ISODate] forKey:(NSString*)kCGImagePropertyGPSDateStamp];
if (heading) {
[GPSMetadata setValue:[NSNumber numberWithDouble:heading.trueHeading] forKey:(NSString*)kCGImagePropertyGPSImgDirection];
[GPSMetadata setValue:headingRef forKey:(NSString*)kCGImagePropertyGPSImgDirectionRef];
}
return [GPSMetadata copy];
}
@end
#pragma mark -
@implementation NSDate (EXIFGPS)
- (NSString*) ISODate
{
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[f setDateFormat:ISODateFormat];
return [f stringFromDate:self];
}
- (NSString*) ISOTime
{
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[f setDateFormat:ISOTimeFormat];
return [f stringFromDate:self];
}
@end
@nitrag
Copy link

nitrag commented Nov 21, 2016

This was helpful thanks. I have updated the code and ported to Swift 3 to help the next guy.

https://gist.github.com/nitrag/343fe13f01bb0ef3692f2ae2dfe33e86

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment