summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-04-22 00:17:39 -0700
committerMinh Nguyễn <mxn@1ec5.org>2016-04-22 11:13:03 -0700
commit91023f02f85ad243f867a2fb920699c3e1659f94 (patch)
tree4f3e68615c6a6562e74a2a21d6069ce788993c90
parenta852ee24fbf6c883b7f64bad9883937eb7b8d80d (diff)
downloadqtlocation-mapboxgl-91023f02f85ad243f867a2fb920699c3e1659f94.tar.gz
[ios, osx] Coordinate formatter
Added a degree-minute-second coordinate formatter for general use. Use this formatter in iosapp and osxapp. Added unit tests for the coordinate formatter and for round-tripping geometry types through NSValue.
-rw-r--r--.jazzy.yaml2
-rw-r--r--platform/darwin/include/MGLCoordinateFormatter.h31
-rw-r--r--platform/darwin/src/MGLCoordinateFormatter.m60
-rw-r--r--platform/darwin/test/MGLCoordinateFormatterTests.m15
-rw-r--r--platform/darwin/test/MGLGeometryTests.mm25
-rw-r--r--platform/ios/CHANGELOG.md2
-rw-r--r--platform/ios/app/MBXViewController.m2
-rw-r--r--platform/ios/framework/Mapbox.h1
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj16
-rw-r--r--platform/osx/app/DroppedPinAnnotation.m17
-rw-r--r--platform/osx/app/LocationCoordinate2DTransformer.m33
-rw-r--r--platform/osx/app/MapDocument.m3
-rw-r--r--platform/osx/app/NSValue+Additions.h10
-rw-r--r--platform/osx/app/NSValue+Additions.m15
-rw-r--r--platform/osx/app/TimeIntervalTransformer.m2
-rw-r--r--platform/osx/osx.xcodeproj/project.pbxproj20
-rw-r--r--platform/osx/sdk/Mapbox.h1
17 files changed, 190 insertions, 65 deletions
diff --git a/.jazzy.yaml b/.jazzy.yaml
index 216fd82ae2..a6d47f25a2 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -63,6 +63,7 @@ custom_categories:
- MGLCoordinateBoundsIsEmpty
- MGLCoordinateBoundsMake
- MGLCoordinateBoundsOffset
+ - MGLCoordinateFormatter
- MGLCoordinateSpan
- MGLCoordinateSpanEqualToCoordinateSpan
- MGLCoordinateSpanMake
@@ -70,3 +71,4 @@ custom_categories:
- MGLDegreesFromRadians
- MGLRadiansFromDegrees
- MGLStringFromCoordinateBounds
+ - NSValue(MGLGeometryAdditions)
diff --git a/platform/darwin/include/MGLCoordinateFormatter.h b/platform/darwin/include/MGLCoordinateFormatter.h
new file mode 100644
index 0000000000..885471c36e
--- /dev/null
+++ b/platform/darwin/include/MGLCoordinateFormatter.h
@@ -0,0 +1,31 @@
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+#import "MGLTypes.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ The `MGLCoordinateFormatter` class provides properly formatted descriptions of
+ geographic coordinate pairs. Use this class to create localized coordinate
+ strings when displaying location information to users.
+ */
+@interface MGLCoordinateFormatter : NSFormatter
+
+/**
+ Returns a coordinate string for the provided value.
+
+ @param coordinate The coordinate’s value.
+ @return The coordinate string appropriately formatted for the formatter’s
+ locale.
+ */
+- (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate;
+
+/**
+ This method is not supported for the `MGLCoordinateFormatter` class.
+ */
+- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLCoordinateFormatter.m b/platform/darwin/src/MGLCoordinateFormatter.m
new file mode 100644
index 0000000000..847b5dfe76
--- /dev/null
+++ b/platform/darwin/src/MGLCoordinateFormatter.m
@@ -0,0 +1,60 @@
+#import "MGLCoordinateFormatter.h"
+
+#import "MGLGeometry.h"
+
+@implementation MGLCoordinateFormatter {
+ NSNumberFormatter *_numberFormatter;
+}
+
+- (instancetype)init {
+ if (self = [super init]) {
+ _numberFormatter = [[NSNumberFormatter alloc] init];
+ _numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
+ _numberFormatter.maximumFractionDigits = 0;
+ }
+ return self;
+}
+
+- (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate {
+ return [NSString stringWithFormat:NSLocalizedString(@"%@, %@", @"Latitude, longitude format"),
+ [self stringFromLocationDegrees:coordinate.latitude
+ positiveFormat:NSLocalizedString(@"%@N", @"North latitude format")
+ negativeFormat:NSLocalizedString(@"%@S", @"South latitude format")],
+ [self stringFromLocationDegrees:coordinate.longitude
+ positiveFormat:NSLocalizedString(@"%@E", @"East longitude format")
+ negativeFormat:NSLocalizedString(@"%@W", @"West longitude format")]];
+}
+
+- (NSString *)stringFromLocationDegrees:(CLLocationDegrees)degrees positiveFormat:(NSString *)positiveFormat negativeFormat:(NSString *)negativeFormat {
+ CLLocationDegrees minutes = (fabs(degrees) - floor(fabs(degrees))) * 60;
+ CLLocationDegrees seconds = (minutes - floor(minutes)) * 60;
+
+ NSMutableString *string = [NSMutableString stringWithFormat:NSLocalizedString(@"%@°", @"Degrees of arc format"),
+ [_numberFormatter stringFromNumber:@(floor(fabs(degrees)))]];
+ if (trunc(minutes) > 0 || trunc(seconds) > 0) {
+ [string appendFormat:NSLocalizedString(@"%@′", @"Arcminutes format"),
+ [_numberFormatter stringFromNumber:@(floor(minutes))]];
+ }
+ if (trunc(seconds) > 0) {
+ [string appendFormat:NSLocalizedString(@"%@″", @"Arcseconds format"),
+ [_numberFormatter stringFromNumber:@(seconds)]];
+ }
+ if (degrees == 0) {
+ return string;
+ }
+ return [NSString stringWithFormat:degrees > 0 ? positiveFormat : negativeFormat, string];
+}
+
+- (nullable NSString *)stringForObjectValue:(id)obj {
+ if (![obj isKindOfClass:[NSValue class]]) {
+ return nil;
+ }
+ return [self stringFromCoordinate:[obj MGLCoordinateValue]];
+}
+
+- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error {
+ NSAssert(NO, @"-getObjectValue:forString:errorDescription: has not been implemented");
+ return NO;
+}
+
+@end
diff --git a/platform/darwin/test/MGLCoordinateFormatterTests.m b/platform/darwin/test/MGLCoordinateFormatterTests.m
new file mode 100644
index 0000000000..84a17596b1
--- /dev/null
+++ b/platform/darwin/test/MGLCoordinateFormatterTests.m
@@ -0,0 +1,15 @@
+#import <Mapbox/Mapbox.h>
+#import <XCTest/XCTest.h>
+
+@interface MGLCoordinateFormatterTests : XCTestCase
+
+@end
+
+@implementation MGLCoordinateFormatterTests
+
+- (void)testStrings {
+ MGLCoordinateFormatter *formatter = [[MGLCoordinateFormatter alloc] init];
+ XCTAssertEqualObjects([formatter stringFromCoordinate:CLLocationCoordinate2DMake(38.9131982, -77.0325453144239)], @"38°54′48″N, 77°1′57″W");
+}
+
+@end
diff --git a/platform/darwin/test/MGLGeometryTests.mm b/platform/darwin/test/MGLGeometryTests.mm
index 73af0bb211..b9205e8d9d 100644
--- a/platform/darwin/test/MGLGeometryTests.mm
+++ b/platform/darwin/test/MGLGeometryTests.mm
@@ -52,4 +52,29 @@
XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 60, 40, midSize), 60, 40, midSize), 3);
}
+- (void)testGeometryBoxing {
+ CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(38.9131982, -77.0325453144239);
+ CLLocationCoordinate2D roundTrippedCoordinate = [NSValue valueWithMGLCoordinate:coordinate].MGLCoordinateValue;
+
+ XCTAssertEqual(coordinate.latitude, roundTrippedCoordinate.latitude, @"Latitude should round-trip.");
+ XCTAssertEqual(coordinate.longitude, roundTrippedCoordinate.longitude, @"Longitude should round-trip.");
+
+ MGLCoordinateSpan span = MGLCoordinateSpanMake(4.383333333333335, -4.299999999999997);
+ MGLCoordinateSpan roundTrippedSpan = [NSValue valueWithMGLCoordinateSpan:span].MGLCoordinateSpanValue;
+
+ XCTAssertEqual(span.latitudeDelta, roundTrippedSpan.latitudeDelta, @"Latitude delta should round-trip.");
+ XCTAssertEqual(span.longitudeDelta, roundTrippedSpan.longitudeDelta, @"Longitude delta should round-trip.");
+
+ MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(38.9131982, -77.0325453144239),
+ CLLocationCoordinate2DMake(37.7757368, -122.4135302));
+ MGLCoordinateBounds roundTrippedBounds = [NSValue valueWithMGLCoordinateBounds:bounds].MGLCoordinateBoundsValue;
+
+ XCTAssertEqualObjects([NSValue valueWithMGLCoordinate:bounds.sw],
+ [NSValue valueWithMGLCoordinate:roundTrippedBounds.sw],
+ @"Southwest should round-trip.");
+ XCTAssertEqualObjects([NSValue valueWithMGLCoordinate:bounds.ne],
+ [NSValue valueWithMGLCoordinate:roundTrippedBounds.ne],
+ @"Northeast should round-trip.");
+}
+
@end
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index e84590e7dc..875b0dd7a6 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -11,6 +11,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON
- Setting the `image` property of an MGLAnnotationImage to `nil` resets it to the default red pin image and reclaims resources that can be used to customize additional annotations. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835))
- Fixed an issue preventing KVO change notifications from being generated on MGLMapView’s `userTrackingMode` key path when `-setUserTrackingMode:animated:` is called. ([#4724](https://github.com/mapbox/mapbox-gl-native/pull/4724))
- Rendering now occurs on the main thread, fixing a hang when calling `-[MGLMapView styleURL]` before the map view has fully loaded or while the application is in the background. ([#2909](https://github.com/mapbox/mapbox-gl-native/pull/2909))
+- Added category methods on NSValue for converting to and from the structure types defined in MGLGeometry.h. ([#4802](https://github.com/mapbox/mapbox-gl-native/pull/4802))
+- Added MGLCoordinateFormatter for converting geographic coordinates into display strings. ([#4802](https://github.com/mapbox/mapbox-gl-native/pull/4802))
- Added a `-reloadStyle:` action to MGLMapView to force a reload of the current style. ([#4728](https://github.com/mapbox/mapbox-gl-native/pull/4728))
- A more specific user agent string is now sent with style and tile requests. ([#4012](https://github.com/mapbox/mapbox-gl-native/pull/4012))
- Mapbox Telemetry is automatically disabled while the host application is running in the iOS Simulator. ([#4726](https://github.com/mapbox/mapbox-gl-native/pull/4726))
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index d8bdc6d99e..f6e0cc0ae8 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -450,7 +450,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
point.coordinate = [self.mapView convertPoint:[longPress locationInView:longPress.view]
toCoordinateFromView:self.mapView];
point.title = @"Dropped Marker";
- point.subtitle = [NSString stringWithFormat:@"lat: %.3f, lon: %.3f", point.coordinate.latitude, point.coordinate.longitude];
+ point.subtitle = [[[MGLCoordinateFormatter alloc] init] stringFromCoordinate:point.coordinate];
[self.mapView addAnnotation:point];
[self.mapView selectAnnotation:point animated:YES];
}
diff --git a/platform/ios/framework/Mapbox.h b/platform/ios/framework/Mapbox.h
index 7b233ecac5..68579933b6 100644
--- a/platform/ios/framework/Mapbox.h
+++ b/platform/ios/framework/Mapbox.h
@@ -10,6 +10,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLAnnotation.h"
#import "MGLAnnotationImage.h"
#import "MGLCalloutView.h"
+#import "MGLCoordinateFormatter.h"
#import "MGLMapCamera.h"
#import "MGLGeometry.h"
#import "MGLMapView.h"
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 9215474947..50f2a79dea 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -28,6 +28,11 @@
DA2E88631CC0382C00F24E7B /* MGLOfflineRegionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */; };
DA2E88641CC0382C00F24E7B /* MGLOfflineStorageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2E885F1CC0382C00F24E7B /* MGLOfflineStorageTests.m */; };
DA2E88651CC0382C00F24E7B /* MGLStyleTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA2E88601CC0382C00F24E7B /* MGLStyleTests.mm */; };
+ DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA35A2A11CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */; };
+ DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */; };
+ DA35A2AA1CCA058D00E826B2 /* MGLCoordinateFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */; };
DA4A26941CB6E337000B7809 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC9561CB6C1C2006E619F /* Main.storyboard */; };
DA4A26951CB6E337000B7809 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC95B1CB6C1C2006E619F /* LaunchScreen.storyboard */; };
DA8847D91CBAF91600AB86E3 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA8847D21CBAF91600AB86E3 /* Mapbox.framework */; };
@@ -269,6 +274,9 @@
DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLOfflineRegionTests.m; path = ../../darwin/test/MGLOfflineRegionTests.m; sourceTree = "<group>"; };
DA2E885F1CC0382C00F24E7B /* MGLOfflineStorageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLOfflineStorageTests.m; path = ../../darwin/test/MGLOfflineStorageTests.m; sourceTree = "<group>"; };
DA2E88601CC0382C00F24E7B /* MGLStyleTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLStyleTests.mm; path = ../../darwin/test/MGLStyleTests.mm; sourceTree = "<group>"; };
+ DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLCoordinateFormatter.h; path = include/MGLCoordinateFormatter.h; sourceTree = "<group>"; };
+ DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLCoordinateFormatter.m; path = src/MGLCoordinateFormatter.m; sourceTree = "<group>"; };
+ DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLCoordinateFormatterTests.m; path = ../../darwin/test/MGLCoordinateFormatterTests.m; sourceTree = "<group>"; };
DA4A26961CB6E795000B7809 /* Mapbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mapbox.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DA8847D21CBAF91600AB86E3 /* Mapbox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Mapbox.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DA8847D61CBAF91600AB86E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -503,6 +511,7 @@
DA2E88521CC036F400F24E7B /* SDK Tests */ = {
isa = PBXGroup;
children = (
+ DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */,
DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */,
DA2E885D1CC0382C00F24E7B /* MGLOfflinePackTests.m */,
DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */,
@@ -534,6 +543,8 @@
DA8847FF1CBAFA6200AB86E3 /* MGLAccountManager_Private.h */,
DA8848001CBAFA6200AB86E3 /* MGLAccountManager.m */,
DA8847E01CBAFA5100AB86E3 /* MGLAnnotation.h */,
+ DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */,
+ DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */,
DA8847E11CBAFA5100AB86E3 /* MGLGeometry.h */,
DA8848011CBAFA6200AB86E3 /* MGLGeometry_Private.h */,
DA8848021CBAFA6200AB86E3 /* MGLGeometry.mm */,
@@ -741,6 +752,7 @@
DA88483D1CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h in Headers */,
DA17BE301CC4BAC300402C41 /* MGLMapView_Internal.h in Headers */,
DA88481E1CBAFA6200AB86E3 /* MGLMultiPoint_Private.h in Headers */,
+ DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DA8847F71CBAFA5100AB86E3 /* MGLOverlay.h in Headers */,
DA88488B1CBB037E00AB86E3 /* SMCalloutView.h in Headers */,
DA8847FE1CBAFA5100AB86E3 /* MGLTypes.h in Headers */,
@@ -771,6 +783,7 @@
files = (
DABFB85E1CBE99E500D62B32 /* MGLAnnotation.h in Headers */,
DABFB8641CBE99E500D62B32 /* MGLOfflineStorage.h in Headers */,
+ DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */,
DABFB86D1CBE9A0F00D62B32 /* MGLAnnotationImage.h in Headers */,
@@ -1019,6 +1032,7 @@
DA2E88611CC0382C00F24E7B /* MGLGeometryTests.mm in Sources */,
DA2E88641CC0382C00F24E7B /* MGLOfflineStorageTests.m in Sources */,
DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */,
+ DA35A2AA1CCA058D00E826B2 /* MGLCoordinateFormatterTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1038,6 +1052,7 @@
DA8848501CBAFB9800AB86E3 /* MGLAnnotationImage.m in Sources */,
DA8848281CBAFA6200AB86E3 /* MGLShape.m in Sources */,
DA8848321CBAFA6200AB86E3 /* NSString+MGLAdditions.m in Sources */,
+ DA35A2A11CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */,
DA88481C1CBAFA6200AB86E3 /* MGLGeometry.mm in Sources */,
DA88481F1CBAFA6200AB86E3 /* MGLMultiPoint.mm in Sources */,
@@ -1071,6 +1086,7 @@
DAA4E41D1CBB730400178DFB /* MGLGeometry.mm in Sources */,
DAA4E41F1CBB730400178DFB /* MGLMultiPoint.mm in Sources */,
DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */,
+ DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
DAA4E42D1CBB730400178DFB /* MGLAnnotationImage.m in Sources */,
DAA4E4301CBB730400178DFB /* MGLLocationManager.m in Sources */,
DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */,
diff --git a/platform/osx/app/DroppedPinAnnotation.m b/platform/osx/app/DroppedPinAnnotation.m
index a103ec923c..5b19fd7401 100644
--- a/platform/osx/app/DroppedPinAnnotation.m
+++ b/platform/osx/app/DroppedPinAnnotation.m
@@ -2,21 +2,27 @@
#import "LocationCoordinate2DTransformer.h"
#import "TimeIntervalTransformer.h"
-#import "NSValue+Additions.h"
+
+#import <Mapbox/Mapbox.h>
+
+static MGLCoordinateFormatter *DroppedPinCoordinateFormatter;
@implementation DroppedPinAnnotation {
NSTimer *_timer;
NSTimeInterval _priorShownTimeInterval;
NSDate *_dateShown;
- NSValueTransformer *_coordinateTransformer;
NSValueTransformer *_timeIntervalTransformer;
}
++ (void)initialize {
+ if (self == [DroppedPinAnnotation class]) {
+ DroppedPinCoordinateFormatter = [[MGLCoordinateFormatter alloc] init];
+ }
+}
+
- (instancetype)init {
if (self = [super init]) {
- _coordinateTransformer = [NSValueTransformer valueTransformerForName:
- NSStringFromClass([LocationCoordinate2DTransformer class])];
_timeIntervalTransformer = [NSValueTransformer valueTransformerForName:
NSStringFromClass([TimeIntervalTransformer class])];
[self update:nil];
@@ -54,8 +60,7 @@
}
- (void)update:(NSTimer *)timer {
- NSString *coordinate = [_coordinateTransformer transformedValue:
- [NSValue valueWithCLLocationCoordinate2D:self.coordinate]];
+ NSString *coordinate = [DroppedPinCoordinateFormatter stringFromCoordinate:self.coordinate];
NSString *elapsedTime = [_timeIntervalTransformer transformedValue:@(self.elapsedShownTime)];
self.subtitle = [NSString stringWithFormat:@"%@\nSelected for %@", coordinate, elapsedTime];
}
diff --git a/platform/osx/app/LocationCoordinate2DTransformer.m b/platform/osx/app/LocationCoordinate2DTransformer.m
index d9c35b2a1f..aeede23497 100644
--- a/platform/osx/app/LocationCoordinate2DTransformer.m
+++ b/platform/osx/app/LocationCoordinate2DTransformer.m
@@ -1,26 +1,11 @@
#import "LocationCoordinate2DTransformer.h"
-#import "NSValue+Additions.h"
+#import <Mapbox/Mapbox.h>
-NSString *StringFromDegrees(CLLocationDegrees degrees, char positiveDirection, char negativeDirection) {
- double minutes = (degrees - floor(degrees)) * 60;
- double seconds = (minutes - floor(minutes)) * 60;
-
- NSMutableString *string = [NSMutableString stringWithFormat:@"%.0f°", fabs(degrees)];
- if (floor(minutes) || floor(seconds)) {
- [string appendFormat:@"%.0f′", minutes];
- }
- if (floor(seconds)) {
- [string appendFormat:@"%.0f″", seconds];
- }
- if (degrees) {
- [string appendFormat:@"%c", degrees > 0 ? positiveDirection : negativeDirection];
- }
- return string;
+@implementation LocationCoordinate2DTransformer {
+ MGLCoordinateFormatter *_coordinateFormatter;
}
-@implementation LocationCoordinate2DTransformer
-
+ (Class)transformedValueClass {
return [NSString class];
}
@@ -29,14 +14,18 @@ NSString *StringFromDegrees(CLLocationDegrees degrees, char positiveDirection, c
return NO;
}
+- (instancetype)init {
+ if (self = [super init]) {
+ _coordinateFormatter = [[MGLCoordinateFormatter alloc] init];
+ }
+ return self;
+}
+
- (id)transformedValue:(id)value {
if (![value isKindOfClass:[NSValue class]]) {
return nil;
}
- CLLocationCoordinate2D coordinate = [value CLLocationCoordinate2DValue];
- return [NSString stringWithFormat:@"%@, %@",
- StringFromDegrees(coordinate.latitude, 'N', 'S'),
- StringFromDegrees(coordinate.longitude, 'E', 'W')];
+ return [_coordinateFormatter stringForObjectValue:value];
}
@end
diff --git a/platform/osx/app/MapDocument.m b/platform/osx/app/MapDocument.m
index aaa04e9914..2a537772b5 100644
--- a/platform/osx/app/MapDocument.m
+++ b/platform/osx/app/MapDocument.m
@@ -2,7 +2,6 @@
#import "AppDelegate.h"
#import "DroppedPinAnnotation.h"
-#import "NSValue+Additions.h"
#import <Mapbox/Mapbox.h>
@@ -222,7 +221,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
// Temporarily set the display name to the default center coordinate instead
// of “Untitled” until the binding kicks in.
- NSValue *coordinateValue = [NSValue valueWithCLLocationCoordinate2D:self.mapView.centerCoordinate];
+ NSValue *coordinateValue = [NSValue valueWithMGLCoordinate:self.mapView.centerCoordinate];
self.displayName = [[NSValueTransformer valueTransformerForName:@"LocationCoordinate2DTransformer"]
transformedValue:coordinateValue];
}
diff --git a/platform/osx/app/NSValue+Additions.h b/platform/osx/app/NSValue+Additions.h
deleted file mode 100644
index 050dbc8132..0000000000
--- a/platform/osx/app/NSValue+Additions.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#import <Foundation/Foundation.h>
-#import <CoreLocation/CoreLocation.h>
-
-@interface NSValue (Additions)
-
-+ (instancetype)valueWithCLLocationCoordinate2D:(CLLocationCoordinate2D)coordinate;
-
-@property (readonly) CLLocationCoordinate2D CLLocationCoordinate2DValue;
-
-@end
diff --git a/platform/osx/app/NSValue+Additions.m b/platform/osx/app/NSValue+Additions.m
deleted file mode 100644
index c060602f43..0000000000
--- a/platform/osx/app/NSValue+Additions.m
+++ /dev/null
@@ -1,15 +0,0 @@
-#import "NSValue+Additions.h"
-
-@implementation NSValue (Additions)
-
-+ (instancetype)valueWithCLLocationCoordinate2D:(CLLocationCoordinate2D)coordinate {
- return [self valueWithBytes:&coordinate objCType:@encode(CLLocationCoordinate2D)];
-}
-
-- (CLLocationCoordinate2D)CLLocationCoordinate2DValue {
- CLLocationCoordinate2D coordinate;
- [self getValue:&coordinate];
- return coordinate;
-}
-
-@end
diff --git a/platform/osx/app/TimeIntervalTransformer.m b/platform/osx/app/TimeIntervalTransformer.m
index e6d7333d25..39177dc5bc 100644
--- a/platform/osx/app/TimeIntervalTransformer.m
+++ b/platform/osx/app/TimeIntervalTransformer.m
@@ -1,7 +1,5 @@
#import "TimeIntervalTransformer.h"
-#import "NSValue+Additions.h"
-
@implementation TimeIntervalTransformer
+ (Class)transformedValueClass {
diff --git a/platform/osx/osx.xcodeproj/project.pbxproj b/platform/osx/osx.xcodeproj/project.pbxproj
index 4854858df8..dc7030a949 100644
--- a/platform/osx/osx.xcodeproj/project.pbxproj
+++ b/platform/osx/osx.xcodeproj/project.pbxproj
@@ -8,6 +8,9 @@
/* Begin PBXBuildFile section */
52BECB0A1CC5A26F009CD791 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */; };
+ DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */; };
+ DA35A2A81CC9F41600E826B2 /* MGLCoordinateFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A71CC9F41600E826B2 /* MGLCoordinateFormatterTests.m */; };
DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E961CC2E3400062CAFB /* AppDelegate.m */; };
DA839E9A1CC2E3400062CAFB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E991CC2E3400062CAFB /* main.m */; };
DA839E9D1CC2E3400062CAFB /* MapDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E9C1CC2E3400062CAFB /* MapDocument.m */; };
@@ -18,7 +21,6 @@
DAE6C2E21CC304F900DB3429 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = DAE6C2E11CC304F900DB3429 /* Credits.rtf */; };
DAE6C2ED1CC3050F00DB3429 /* DroppedPinAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */; };
DAE6C2EE1CC3050F00DB3429 /* LocationCoordinate2DTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2E61CC3050F00DB3429 /* LocationCoordinate2DTransformer.m */; };
- DAE6C2EF1CC3050F00DB3429 /* NSValue+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2E81CC3050F00DB3429 /* NSValue+Additions.m */; };
DAE6C2F01CC3050F00DB3429 /* OfflinePackNameValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2EA1CC3050F00DB3429 /* OfflinePackNameValueTransformer.m */; };
DAE6C2F11CC3050F00DB3429 /* TimeIntervalTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2EC1CC3050F00DB3429 /* TimeIntervalTransformer.m */; };
DAE6C3321CC30DB200DB3429 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAE6C3281CC30DB200DB3429 /* Mapbox.framework */; };
@@ -134,6 +136,9 @@
/* Begin PBXFileReference section */
52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+ DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLCoordinateFormatter.h; path = include/MGLCoordinateFormatter.h; sourceTree = "<group>"; };
+ DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLCoordinateFormatter.m; path = src/MGLCoordinateFormatter.m; sourceTree = "<group>"; };
+ DA35A2A71CC9F41600E826B2 /* MGLCoordinateFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLCoordinateFormatterTests.m; path = ../../darwin/test/MGLCoordinateFormatterTests.m; sourceTree = "<group>"; };
DA839E921CC2E3400062CAFB /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DA839E951CC2E3400062CAFB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
DA839E961CC2E3400062CAFB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -150,8 +155,6 @@
DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DroppedPinAnnotation.m; sourceTree = "<group>"; };
DAE6C2E51CC3050F00DB3429 /* LocationCoordinate2DTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocationCoordinate2DTransformer.h; sourceTree = "<group>"; };
DAE6C2E61CC3050F00DB3429 /* LocationCoordinate2DTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocationCoordinate2DTransformer.m; sourceTree = "<group>"; };
- DAE6C2E71CC3050F00DB3429 /* NSValue+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+Additions.h"; sourceTree = "<group>"; };
- DAE6C2E81CC3050F00DB3429 /* NSValue+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+Additions.m"; sourceTree = "<group>"; };
DAE6C2E91CC3050F00DB3429 /* OfflinePackNameValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OfflinePackNameValueTransformer.h; sourceTree = "<group>"; };
DAE6C2EA1CC3050F00DB3429 /* OfflinePackNameValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OfflinePackNameValueTransformer.m; sourceTree = "<group>"; };
DAE6C2EB1CC3050F00DB3429 /* TimeIntervalTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeIntervalTransformer.h; sourceTree = "<group>"; };
@@ -222,7 +225,7 @@
DAE6C3BC1CC31F2E00DB3429 /* mapbox.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = mapbox.pdf; path = src/resources/mapbox.pdf; sourceTree = SOURCE_ROOT; };
DAE6C3BD1CC31F2E00DB3429 /* MGLAnnotationCallout.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = MGLAnnotationCallout.xib; path = src/resources/MGLAnnotationCallout.xib; sourceTree = SOURCE_ROOT; };
DAE6C3C11CC31F4500DB3429 /* Mapbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mapbox.h; sourceTree = "<group>"; };
- DAE6C3C51CC31F9100DB3429 /* mbgl.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = mbgl.xcconfig; path = "../../build/osx/mbgl.xcconfig"; sourceTree = "<group>"; };
+ DAE6C3C51CC31F9100DB3429 /* mbgl.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = mbgl.xcconfig; path = ../../build/osx/mbgl.xcconfig; sourceTree = "<group>"; };
DAE6C3C61CC3499100DB3429 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
DAE6C3C81CC34BD800DB3429 /* MGLGeometryTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLGeometryTests.mm; path = ../../darwin/test/MGLGeometryTests.mm; sourceTree = "<group>"; };
DAE6C3C91CC34BD800DB3429 /* MGLOfflinePackTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLOfflinePackTests.m; path = ../../darwin/test/MGLOfflinePackTests.m; sourceTree = "<group>"; };
@@ -297,8 +300,6 @@
DA839E9B1CC2E3400062CAFB /* MapDocument.h */,
DA839E9C1CC2E3400062CAFB /* MapDocument.m */,
DA839E9E1CC2E3400062CAFB /* MapDocument.xib */,
- DAE6C2E71CC3050F00DB3429 /* NSValue+Additions.h */,
- DAE6C2E81CC3050F00DB3429 /* NSValue+Additions.m */,
DAE6C2E91CC3050F00DB3429 /* OfflinePackNameValueTransformer.h */,
DAE6C2EA1CC3050F00DB3429 /* OfflinePackNameValueTransformer.m */,
DAE6C2EB1CC3050F00DB3429 /* TimeIntervalTransformer.h */,
@@ -350,6 +351,7 @@
DAE6C3371CC30DB200DB3429 /* SDK Tests */ = {
isa = PBXGroup;
children = (
+ DA35A2A71CC9F41600E826B2 /* MGLCoordinateFormatterTests.m */,
DAE6C3C81CC34BD800DB3429 /* MGLGeometryTests.mm */,
DAE6C3C91CC34BD800DB3429 /* MGLOfflinePackTests.m */,
DAE6C3CA1CC34BD800DB3429 /* MGLOfflineRegionTests.m */,
@@ -368,6 +370,8 @@
DAE6C36A1CC31E2A00DB3429 /* MGLAccountManager_Private.h */,
DAE6C36B1CC31E2A00DB3429 /* MGLAccountManager.m */,
DAE6C34B1CC31E0400DB3429 /* MGLAnnotation.h */,
+ DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */,
+ DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */,
DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,
DAE6C36C1CC31E2A00DB3429 /* MGLGeometry_Private.h */,
DAE6C36D1CC31E2A00DB3429 /* MGLGeometry.mm */,
@@ -475,6 +479,7 @@
DAE6C3661CC31E0400DB3429 /* MGLShape.h in Headers */,
DAE6C3C21CC31F4500DB3429 /* Mapbox.h in Headers */,
DAE6C3641CC31E0400DB3429 /* MGLPolygon.h in Headers */,
+ DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DAE6C3621CC31E0400DB3429 /* MGLOverlay.h in Headers */,
DAE6C3651CC31E0400DB3429 /* MGLPolyline.h in Headers */,
DAE6C39A1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h in Headers */,
@@ -635,7 +640,6 @@
DAE6C2EE1CC3050F00DB3429 /* LocationCoordinate2DTransformer.m in Sources */,
DAE6C2F11CC3050F00DB3429 /* TimeIntervalTransformer.m in Sources */,
DA839E9A1CC2E3400062CAFB /* main.m in Sources */,
- DAE6C2EF1CC3050F00DB3429 /* NSValue+Additions.m in Sources */,
DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */,
DAE6C2F01CC3050F00DB3429 /* OfflinePackNameValueTransformer.m in Sources */,
);
@@ -659,6 +663,7 @@
DAE6C3BA1CC31EF300DB3429 /* MGLOpenGLLayer.mm in Sources */,
DAE6C38A1CC31E2A00DB3429 /* MGLMultiPoint.mm in Sources */,
DAE6C3961CC31E2A00DB3429 /* MGLTypes.m in Sources */,
+ DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */,
DAE6C3881CC31E2A00DB3429 /* MGLMapCamera.mm in Sources */,
DAE6C3911CC31E2A00DB3429 /* MGLPolygon.mm in Sources */,
DAE6C39B1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m in Sources */,
@@ -679,6 +684,7 @@
DAE6C3D21CC34C9900DB3429 /* MGLGeometryTests.mm in Sources */,
DAE6C3D51CC34C9900DB3429 /* MGLOfflineStorageTests.m in Sources */,
DAE6C3D31CC34C9900DB3429 /* MGLOfflinePackTests.m in Sources */,
+ DA35A2A81CC9F41600E826B2 /* MGLCoordinateFormatterTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/platform/osx/sdk/Mapbox.h b/platform/osx/sdk/Mapbox.h
index 4a2cd32504..49d5cab728 100644
--- a/platform/osx/sdk/Mapbox.h
+++ b/platform/osx/sdk/Mapbox.h
@@ -9,6 +9,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import <Mapbox/MGLAccountManager.h>
#import <Mapbox/MGLAnnotation.h>
#import <Mapbox/MGLAnnotationImage.h>
+#import <Mapbox/MGLCoordinateFormatter.h>
#import <Mapbox/MGLGeometry.h>
#import <Mapbox/MGLMapCamera.h>
#import <Mapbox/MGLMapView.h>