diff --git a/UTMConversion/CLLocation+UTMCoordinate.swift b/UTMConversion/CLLocation+UTMCoordinate.swift index d0862b5..458cf0c 100644 --- a/UTMConversion/CLLocation+UTMCoordinate.swift +++ b/UTMConversion/CLLocation+UTMCoordinate.swift @@ -6,11 +6,13 @@ public extension CLLocation { /** Calculates the UTM coordinate of the receiver - - Parameter datum: The datum to use, defaults to WGS84 which should be fine for most applications + - Parameter datum: The datum to use, defaults to WGS84 which should be fine for most applications. + Throws a ``UTMConversionError.invalidCoordinate`` if the locations coordinate is invalid. */ - func utmCoordinate(datum: UTMDatum = UTMDatum.wgs84) -> UTMCoordinate { + func utmCoordinate(datum: UTMDatum = UTMDatum.wgs84) throws -> UTMCoordinate { let coordinate = self.coordinate + guard CLLocationCoordinate2DIsValid(coordinate) else { throw UTMConversionError.invalidCoordinate } let zone = coordinate.zone return TMCoordinate(coordinate: coordinate, centralMeridian: zone.centralMeridian, datum: datum).utmCoordinate(zone: zone, hemisphere: coordinate.hemisphere) } diff --git a/UTMConversion/CLLocationCoordinate2D+UTMCoordinate.swift b/UTMConversion/CLLocationCoordinate2D+UTMCoordinate.swift index d79dffd..6501f98 100644 --- a/UTMConversion/CLLocationCoordinate2D+UTMCoordinate.swift +++ b/UTMConversion/CLLocationCoordinate2D+UTMCoordinate.swift @@ -7,10 +7,12 @@ public extension CLLocationCoordinate2D { /** Calculates the UTM coordinate of the receiver - - Parameter datum: The datum to use, defaults to WGS84 which should be fine for most applications + - Parameter datum: The datum to use, defaults to WGS84 which should be fine for most applications. + Throws a ``UTMConversionError.invalidCoordinate`` if the coordinate is invalid. */ - func utmCoordinate(datum: UTMDatum = UTMDatum.wgs84) -> UTMCoordinate { + func utmCoordinate(datum: UTMDatum = UTMDatum.wgs84) throws -> UTMCoordinate { + guard CLLocationCoordinate2DIsValid(self) else { throw UTMConversionError.invalidCoordinate } let zone = self.zone return TMCoordinate(coordinate: self, centralMeridian: zone.centralMeridian, datum: datum).utmCoordinate(zone: zone, hemisphere: hemisphere) } diff --git a/UTMConversion/UTMConversionError.swift b/UTMConversion/UTMConversionError.swift new file mode 100644 index 0000000..3228ec1 --- /dev/null +++ b/UTMConversion/UTMConversionError.swift @@ -0,0 +1,3 @@ +public enum UTMConversionError: Error { + case invalidCoordinate +} diff --git a/UTMConversionTests/UTMConversionTests.swift b/UTMConversionTests/UTMConversionTests.swift index dc18846..1acf09d 100644 --- a/UTMConversionTests/UTMConversionTests.swift +++ b/UTMConversionTests/UTMConversionTests.swift @@ -4,52 +4,52 @@ import XCTest class UTMConversionTests: XCTestCase { - func testCLLocationCoordinate2D_utmCoordinate() { - let osloUTM = oslo.utmCoordinate() + func testCLLocationCoordinate2D_utmCoordinate() throws { + let osloUTM = try oslo.utmCoordinate() XCTAssertEqual(osloUTM.northing, 6643010.0, accuracy: 0.00001); XCTAssertEqual(osloUTM.easting, 598430.0, accuracy: 0.00001); XCTAssertEqual(osloUTM.zone, 32) XCTAssertEqual(osloUTM.hemisphere, .northern) - let trondheimUTM = trondheim.utmCoordinate() + let trondheimUTM = try trondheim.utmCoordinate() XCTAssertEqual(trondheimUTM.northing, 7034313, accuracy: 0.00001) XCTAssertEqual(trondheimUTM.easting, 569612, accuracy: 0.00001) XCTAssertEqual(trondheimUTM.zone, 32) XCTAssertEqual(trondheimUTM.hemisphere, .northern) - let johannesburgUTM = johannesburg.utmCoordinate() + let johannesburgUTM = try johannesburg.utmCoordinate() XCTAssertEqual(johannesburgUTM.northing, 7100115, accuracy: 0.00001) XCTAssertEqual(johannesburgUTM.easting, 603914, accuracy: 0.00001) XCTAssertEqual(johannesburgUTM.zone, 35) XCTAssertEqual(johannesburgUTM.hemisphere, .southern) - let buninyongUTM = buninyong.utmCoordinate() + let buninyongUTM = try buninyong.utmCoordinate() XCTAssertEqual(buninyongUTM.northing, 5828674.33994, accuracy: 0.00001) XCTAssertEqual(buninyongUTM.easting, 758173.79835, accuracy: 0.00001) XCTAssertEqual(buninyongUTM.zone, 54) XCTAssertEqual(buninyongUTM.hemisphere, .southern) } - func testCLLocation_utmCoordinate() { - let osloUTM = osloLocation.utmCoordinate() + func testCLLocation_utmCoordinate() throws { + let osloUTM = try osloLocation.utmCoordinate() XCTAssertEqual(osloUTM.northing, 6643010.0, accuracy: 0.00001); XCTAssertEqual(osloUTM.easting, 598430.0, accuracy: 0.00001); XCTAssertEqual(osloUTM.zone, 32) XCTAssertEqual(osloUTM.hemisphere, .northern) - let trondheimUTM = trondheimLocation.utmCoordinate() + let trondheimUTM = try trondheimLocation.utmCoordinate() XCTAssertEqual(trondheimUTM.northing, 7034313, accuracy: 0.00001) XCTAssertEqual(trondheimUTM.easting, 569612, accuracy: 0.00001) XCTAssertEqual(trondheimUTM.zone, 32) XCTAssertEqual(trondheimUTM.hemisphere, .northern) - let johannesburgUTM = johannesburgLocation.utmCoordinate() + let johannesburgUTM = try johannesburgLocation.utmCoordinate() XCTAssertEqual(johannesburgUTM.northing, 7100115, accuracy: 0.00001) XCTAssertEqual(johannesburgUTM.easting, 603914, accuracy: 0.00001) XCTAssertEqual(johannesburgUTM.zone, 35) XCTAssertEqual(johannesburgUTM.hemisphere, .southern) - let buninyongUTM = buninyongLocation.utmCoordinate() + let buninyongUTM = try buninyongLocation.utmCoordinate() XCTAssertEqual(buninyongUTM.northing, 5828674.33994, accuracy: 0.00001) XCTAssertEqual(buninyongUTM.easting, 758173.79835, accuracy: 0.00001) XCTAssertEqual(buninyongUTM.zone, 54) @@ -98,6 +98,34 @@ class UTMConversionTests: XCTestCase { XCTAssertEqual(oslo.coordinate.latitude, 59.912814611065265) XCTAssertEqual(oslo.coordinate.longitude, 10.760192985178369) } + + func testInvalidCoordinateLatitude() { + let coordinate = CLLocationCoordinate2D(latitude: 90.1, longitude: -180) + XCTAssertThrowsError(try coordinate.utmCoordinate()) { error in + XCTAssertEqual(error as? UTMConversionError, UTMConversionError.invalidCoordinate) + } + } + + func testInvalidCoordinateLongitude() { + let coordinate = CLLocationCoordinate2D(latitude: 90, longitude: -180.1) + XCTAssertThrowsError(try coordinate.utmCoordinate()) { error in + XCTAssertEqual(error as? UTMConversionError, UTMConversionError.invalidCoordinate) + } + } + + func testInvalidLocationLatitude() { + let location = CLLocation(latitude: -90.1, longitude: 180) + XCTAssertThrowsError(try location.utmCoordinate()) { error in + XCTAssertEqual(error as? UTMConversionError, UTMConversionError.invalidCoordinate) + } + } + + func testInvalidLocationLongitude() { + let location = CLLocation(latitude: -90, longitude: 180.1) + XCTAssertThrowsError(try location.utmCoordinate()) { error in + XCTAssertEqual(error as? UTMConversionError, UTMConversionError.invalidCoordinate) + } + } }