summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-09-27 10:50:43 -0700
committerMinh Nguyễn <mxn@1ec5.org>2018-10-01 17:07:14 -0700
commit44aa4f4be2bd504da982ffdcc0ffa5e84b2c6f31 (patch)
treedba3c3677d8fd4cd601fa2188ad80fcd31fbc1fc
parentfe5ad2346901242a52cf1144bc633f5364c61888 (diff)
downloadqtlocation-mapboxgl-upstream/1ec5-camera-distance-12943.tar.gz
[ios, macos] Fixed camera initialization with eye coordinateupstream/1ec5-camera-distance-12943
Rewrote the code that calculates the heading and pitch of the camera when given an eye coordinate.
-rw-r--r--platform/darwin/src/MGLMapCamera.mm22
-rw-r--r--platform/darwin/test/MGLMapCameraTests.m39
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