diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2018-09-27 10:50:43 -0700 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2018-10-01 18:12:03 -0700 |
commit | a9dc1b529487d2d7d4d8ca8a8ef4498e1de6aafb (patch) | |
tree | dba3c3677d8fd4cd601fa2188ad80fcd31fbc1fc | |
parent | 85a474e2757269313799dd11208da8a1540ab81e (diff) | |
download | qtlocation-mapboxgl-a9dc1b529487d2d7d4d8ca8a8ef4498e1de6aafb.tar.gz |
[ios, macos] Fixed camera initialization with eye coordinate
Rewrote the code that calculates the heading and pitch of the camera when given an eye coordinate.
-rw-r--r-- | platform/darwin/src/MGLMapCamera.mm | 22 | ||||
-rw-r--r-- | platform/darwin/test/MGLMapCameraTests.m | 39 |
2 files changed, 50 insertions, 11 deletions
diff --git a/platform/darwin/src/MGLMapCamera.mm b/platform/darwin/src/MGLMapCamera.mm index 968b64ad17..62f7931641 100644 --- a/platform/darwin/src/MGLMapCamera.mm +++ b/platform/darwin/src/MGLMapCamera.mm @@ -1,7 +1,9 @@ #import "MGLMapCamera.h" #import "MGLGeometry_Private.h" -#include <mbgl/util/projection.hpp> +#import <CoreLocation/CoreLocation.h> + +#include <mbgl/math/wrap.hpp> BOOL MGLEqualFloatWithAccuracy(CGFloat left, CGFloat right, CGFloat accuracy) { @@ -27,17 +29,15 @@ BOOL MGLEqualFloatWithAccuracy(CGFloat left, CGFloat right, CGFloat accuracy) CLLocationDirection heading = -1; CGFloat pitch = -1; if (CLLocationCoordinate2DIsValid(centerCoordinate) && CLLocationCoordinate2DIsValid(eyeCoordinate)) { - mbgl::LatLng centerLatLng = MGLLatLngFromLocationCoordinate2D(centerCoordinate); - mbgl::LatLng eyeLatLng = MGLLatLngFromLocationCoordinate2D(eyeCoordinate); - - mbgl::ProjectedMeters centerMeters = mbgl::Projection::projectedMetersForLatLng(centerLatLng); - mbgl::ProjectedMeters eyeMeters = mbgl::Projection::projectedMetersForLatLng(eyeLatLng); - heading = std::atan((centerMeters.northing() - eyeMeters.northing()) / - (centerMeters.easting() - eyeMeters.easting())); + heading = MGLDirectionBetweenCoordinates(eyeCoordinate, centerCoordinate); - double groundDistance = std::hypot(centerMeters.northing() - eyeMeters.northing(), - centerMeters.easting() - eyeMeters.easting()); - pitch = std::atan(eyeAltitude / groundDistance); + CLLocation *centerLocation = [[CLLocation alloc] initWithLatitude:centerCoordinate.latitude + longitude:centerCoordinate.longitude]; + CLLocation *eyeLocation = [[CLLocation alloc] initWithLatitude:eyeCoordinate.latitude + longitude:eyeCoordinate.longitude]; + CLLocationDistance groundDistance = [eyeLocation distanceFromLocation:centerLocation]; + CGFloat radianPitch = atan2(eyeAltitude, groundDistance); + pitch = mbgl::util::wrap(90 - MGLDegreesFromRadians(radianPitch), 0.0, 360.0); } return [[self alloc] initWithCenterCoordinate:centerCoordinate diff --git a/platform/darwin/test/MGLMapCameraTests.m b/platform/darwin/test/MGLMapCameraTests.m index 9c3a9a526c..9fbf6b9e45 100644 --- a/platform/darwin/test/MGLMapCameraTests.m +++ b/platform/darwin/test/MGLMapCameraTests.m @@ -9,6 +9,45 @@ @implementation MGLMapCameraTests +- (void)testEyeCoordinateInitialization { + CLLocationCoordinate2D fountainSquare = CLLocationCoordinate2DMake(39.10152215, -84.5124439696089); + CLLocationCoordinate2D unionTerminal = CLLocationCoordinate2DMake(39.10980955, -84.5352778794236); + + MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:fountainSquare + fromEyeCoordinate:fountainSquare + eyeAltitude:1000]; + MKMapCamera *mkCamera = [MKMapCamera cameraLookingAtCenterCoordinate:fountainSquare + fromEyeCoordinate:fountainSquare + eyeAltitude:1000]; + XCTAssertEqual(camera.centerCoordinate.latitude, fountainSquare.latitude); + XCTAssertEqual(camera.centerCoordinate.longitude, fountainSquare.longitude); + XCTAssertEqual(camera.centerCoordinate.latitude, mkCamera.centerCoordinate.latitude); + XCTAssertEqual(camera.centerCoordinate.longitude, mkCamera.centerCoordinate.longitude); + XCTAssertEqual(camera.altitude, 1000, @"Eye altitude should be equivalent to altitude in untilted camera."); + XCTAssertEqual(camera.altitude, mkCamera.altitude, @"Eye altitude in untilted camera should match MapKit."); + XCTAssertEqual(camera.pitch, 0, @"Camera directly over center coordinate should be untilted."); + XCTAssertEqual(camera.pitch, mkCamera.pitch, @"Camera directly over center coordinate should have same pitch as MapKit."); + XCTAssertEqual(camera.heading, 0, @"Camera directly over center coordinate should be unrotated."); + XCTAssertEqual(camera.heading, mkCamera.heading, @"Camera directly over center coordinate should have same heading as MapKit."); + + camera = [MGLMapCamera cameraLookingAtCenterCoordinate:fountainSquare + fromEyeCoordinate:unionTerminal + eyeAltitude:1000]; + mkCamera = [MKMapCamera cameraLookingAtCenterCoordinate:fountainSquare + fromEyeCoordinate:unionTerminal + eyeAltitude:1000]; + XCTAssertEqual(camera.centerCoordinate.latitude, fountainSquare.latitude); + XCTAssertEqual(camera.centerCoordinate.longitude, fountainSquare.longitude); + XCTAssertEqual(camera.centerCoordinate.latitude, mkCamera.centerCoordinate.latitude); + XCTAssertEqual(camera.centerCoordinate.longitude, mkCamera.centerCoordinate.longitude); + XCTAssertEqual(camera.altitude, 1000); + XCTAssertEqual(camera.altitude, mkCamera.altitude, @"Eye altitude in tilted camera should match MapKit."); + XCTAssertEqualWithAccuracy(camera.pitch, 65.3469146074, 0.01); + XCTAssertEqual(camera.pitch, mkCamera.pitch); + XCTAssertEqualWithAccuracy(camera.heading, 115.066396383, 0.01); + XCTAssertEqualWithAccuracy(camera.heading, mkCamera.heading, 0.01); +} + - (void)testViewingDistanceInitialization { CLLocationCoordinate2D fountainSquare = CLLocationCoordinate2DMake(39.10152215, -84.5124439696089); MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:fountainSquare |