Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios] Fix visible coordinates when boundaries cross international dat…
Browse files Browse the repository at this point in the history
…eline.
  • Loading branch information
fabian-guerra committed Aug 18, 2017
1 parent 5d641f4 commit a01bddc
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
45 changes: 45 additions & 0 deletions platform/darwin/src/MGLGeometry_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,48 @@ NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinateAtDistanceFacingDirection(MGL
cos(distance) - sin(coordinate.latitude) * sin(otherLatitude));
return MGLRadianCoordinate2DMake(otherLatitude, otherLongitude);
}

/** Returns the coordinate at a given fraction between two coordinates.
@param origin Origin `CLLocationCoordinate2D`.
@param destination Destination `CLLocationCoordinate2D`.
@param fraction Fraction between coordinates (0 = origin, 0.5 = middle, 1 = destination).
@return A coordinate at given fraction. */
// Ported from http://www.movable-type.co.uk/scripts/latlong.html
NS_INLINE CLLocationCoordinate2D MGLCLCoordinateAtFraction(CLLocationCoordinate2D origin, CLLocationCoordinate2D destination, double fraction) {
double φ1 = MGLRadiansFromDegrees(origin.latitude);
double λ1 = MGLRadiansFromDegrees(origin.longitude);

double φ2 = MGLRadiansFromDegrees(destination.latitude);
double λ2 = MGLRadiansFromDegrees(destination.longitude);
double sinφ1 = sin1);
double cosφ1 = cos1);
double sinλ1 = sin1);
double cosλ1 = cos1);
double sinφ2 = sin2);
double cosφ2 = cos2);
double sinλ2 = sin2);
double cosλ2 = cos2);

// distance between points
double Δφ = φ2 - φ1;
double Δλ = λ2 - λ1;
double a = sin(Δφ/2) * sin(Δφ/2) + cos1) * cos2) * sin(Δλ/2) * sin(Δλ/2);
double δ = 2 * atan2(sqrt(a), sqrt(1-a));

double A = sin((1-fraction)*δ) / sin(δ);
double B = sin(fraction*δ) / sin(δ);

double x = A * cosφ1 * cosλ1 + B * cosφ2 * cosλ2;
double y = A * cosφ1 * sinλ1 + B * cosφ2 * sinλ2;
double z = A * sinφ1 + B * sinφ2;

double φ3 = atan2(z, sqrt(x*x + y*y));
double λ3 = atan2(y, x);

CLLocationDegrees latitude = MGLDegreesFromRadians3);
CLLocationDegrees longitude = fmod(MGLDegreesFromRadians3), 360 - 180);

return CLLocationCoordinate2DMake(latitude, longitude);
}
25 changes: 25 additions & 0 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2667,8 +2667,21 @@ - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count
{
latLngs.push_back({coordinates[i].latitude, coordinates[i].longitude});
}

BOOL boundariesCrossDateTime = NO;
if (count == 4 && coordinates[1].longitude > 0 && coordinates[3].longitude < 0) {
boundariesCrossDateTime = YES;
latLngs = [self normalizeCoordinatesForDateTimeChangeSW:coordinates[1] ne:coordinates[3]];

}

mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(latLngs, padding);

if (boundariesCrossDateTime) {
CLLocationCoordinate2D centerCoordinate = MGLCLCoordinateAtFraction(coordinates[1], coordinates[3], 0.5);
cameraOptions.center = MGLLatLngFromLocationCoordinate2D(centerCoordinate);
}

if (direction >= 0)
{
cameraOptions.angle = MGLRadiansFromDegrees(-direction);
Expand Down Expand Up @@ -2707,6 +2720,18 @@ - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count
[self didChangeValueForKey:@"visibleCoordinateBounds"];
}

- (std::vector<mbgl::LatLng>)normalizeCoordinatesForDateTimeChangeSW:(CLLocationCoordinate2D)sw ne:(CLLocationCoordinate2D)ne
{
CLLocationDegrees delta = (180 - fabs(sw.longitude)) + (180 - fabs(ne.longitude));
CLLocationCoordinate2D swap = sw;
sw = CLLocationCoordinate2DMake(ne.latitude, sw.longitude - delta);
ne = swap;

std::vector<mbgl::LatLng> latLngs = { {ne.latitude, sw.longitude}, {sw.latitude, sw.longitude}, {sw.latitude, ne.longitude}, {ne.latitude, ne.longitude} };

return latLngs;
}

+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingDirection
{
return [NSSet setWithObject:@"camera"];
Expand Down

0 comments on commit a01bddc

Please sign in to comment.