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

Commit

Permalink
[ios, macos] Unwrap coordinate bounds
Browse files Browse the repository at this point in the history
Updated coordinate bounds conversion methods to use the beyond-±180 method to indicate that the bounds extends beyond the antimeridian. Also copyedited conversion documentation.
  • Loading branch information
1ec5 committed Feb 21, 2018
1 parent 25629c8 commit 0525fd1
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 76 deletions.
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT

### Other changes

* The `-[MGLMapView convertRect:toCoordinateBoundsFromView:]` method and the `MGLMapView.visibleCoordinateBounds` property’s getter now indicate that the coordinate bounds straddles the antimeridian by extending one side beyond ±180 degrees longitude. ([#11265](https://github.com/mapbox/mapbox-gl-native/pull/11265))
* Feature querying results now account for the `MGLSymbolStyleLayer.circleStrokeWidth` property. ([#10897](https://github.com/mapbox/mapbox-gl-native/pull/10897))
* Fixed an issue preventing labels from being transliterated when VoiceOver was enabled on iOS 10._x_ and below. ([#10881](https://github.com/mapbox/mapbox-gl-native/pull/10881))
* Labels are now transliterated from more languages when VoiceOver is enabled. ([#10881](https://github.com/mapbox/mapbox-gl-native/pull/10881))
Expand Down
36 changes: 26 additions & 10 deletions platform/ios/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,23 +659,21 @@ MGL_EXPORT IB_DESIGNABLE
want to animate the change, call `-setVisibleCoordinateBounds:animated:`
instead.
If a longitude is less than −180 degrees or greater than 180 degrees, the visible
bounds straddles the antimeridian or international date line.
For example, a visible bounds that stretches from Tokyo to San Francisco would have
coordinates of (35.68476, -220.24257) and (37.78428, -122.41310).
If a longitude is less than −180 degrees or greater than 180 degrees, the
visible bounds straddles the antimeridian or international date line. For
example, if both Tokyo and San Francisco are visible, the visible bounds might
extend from (35.68476, −220.24257) to (37.78428, −122.41310).
*/
@property (nonatomic) MGLCoordinateBounds visibleCoordinateBounds;

/**
Changes the receiver’s viewport to fit the given coordinate bounds,
optionally animating the change.
To make the visible bounds go across the antimeridian or international date line,
specify some longitudes less than −180 degrees or greater than 180 degrees.
For example, a visible bounds that stretches from Tokyo to San Francisco would have
coordinates of (35.68476, -220.24257) and (37.78428, -122.41310).
To bring both sides of the antimeridian or international date line into view,
specify some longitudes less than −180 degrees or greater than 180 degrees. For
example, to show both Tokyo and San Francisco simultaneously, you could set the
visible bounds to extend from (35.68476, −220.24257) to (37.78428, −122.41310).
@param bounds The bounds that the viewport will show in its entirety.
@param animated Specify `YES` to animate the change by smoothly scrolling
Expand All @@ -686,6 +684,11 @@ MGL_EXPORT IB_DESIGNABLE
/**
Changes the receiver’s viewport to fit the given coordinate bounds and
optionally some additional padding on each side.
To bring both sides of the antimeridian or international date line into view,
specify some longitudes less than −180 degrees or greater than 180 degrees. For
example, to show both Tokyo and San Francisco simultaneously, you could set the
visible bounds to extend from (35.68476, −220.24257) to (37.78428, −122.41310).
@param bounds The bounds that the viewport will show in its entirety.
@param insets The minimum padding (in screen points) that will be visible
Expand All @@ -698,6 +701,11 @@ MGL_EXPORT IB_DESIGNABLE
/**
Changes the receiver’s viewport to fit all of the given coordinates and
optionally some additional padding on each side.
To bring both sides of the antimeridian or international date line into view,
specify some longitudes less than −180 degrees or greater than 180 degrees. For
example, to show both Tokyo and San Francisco simultaneously, you could set the
visible coordinates to (35.68476, −220.24257) and (37.78428, −122.41310).
@param coordinates The coordinates that the viewport will show.
@param count The number of coordinates. This number must not be greater than
Expand All @@ -712,6 +720,11 @@ MGL_EXPORT IB_DESIGNABLE
/**
Changes the receiver’s viewport to fit all of the given coordinates and
optionally some additional padding on each side.
To bring both sides of the antimeridian or international date line into view,
specify some longitudes less than −180 degrees or greater than 180 degrees. For
example, to show both Tokyo and San Francisco simultaneously, you could set the
visible coordinates to (35.68476, −220.24257) and (37.78428, −122.41310).
@param coordinates The coordinates that the viewport will show.
@param count The number of coordinates. This number must not be greater than
Expand Down Expand Up @@ -994,6 +1007,9 @@ MGL_EXPORT IB_DESIGNABLE
/**
Converts a rectangle in the given view’s coordinate system to a geographic
bounding box.
If a longitude is less than −180 degrees or greater than 180 degrees, the
bounding box straddles the antimeridian or international date line.
@param rect The rectangle to convert.
@param view The view in whose coordinate system the rectangle is expressed.
Expand Down
48 changes: 18 additions & 30 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3423,36 +3423,24 @@ - (CGRect)convertLatLngBounds:(mbgl::LatLngBounds)bounds toRectToView:(nullable
/// bounding box.
- (mbgl::LatLngBounds)convertRect:(CGRect)rect toLatLngBoundsFromView:(nullable UIView *)view
{
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
bounds.extend([self convertPoint:rect.origin toLatLngFromView:view]);
bounds.extend([self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMinY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ CGRectGetMinX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view]);

// The world is wrapping if a point just outside the bounds is also within
// the rect.
mbgl::LatLng outsideLatLng;
if (bounds.west() > -180)
{
outsideLatLng = {
(bounds.south() + bounds.north()) / 2,
bounds.west() - 1,
};
}
else if (bounds.east() < 180)
{
outsideLatLng = {
(bounds.south() + bounds.north()) / 2,
bounds.east() + 1,
};
}

// If the world is wrapping, extend the bounds to cover all longitudes.
if (CGRectContainsPoint(rect, [self convertLatLng:outsideLatLng toPointToView:view]))
{
bounds.extend(mbgl::LatLng(bounds.south(), -180));
bounds.extend(mbgl::LatLng(bounds.south(), 180));
}
auto bounds = mbgl::LatLngBounds::empty();
auto topLeft = [self convertPoint:{ CGRectGetMinX(rect), CGRectGetMinY(rect) } toLatLngFromView:view];
auto topRight = [self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMinY(rect) } toLatLngFromView:view];
auto bottomRight = [self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view];
auto bottomLeft = [self convertPoint:{ CGRectGetMinX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view];

// If the bounds straddles the antimeridian, unwrap it so that one side
// extends beyond ±180° longitude.
auto center = [self convertPoint:{ CGRectGetMidX(rect), CGRectGetMidY(rect) } toLatLngFromView:view];
topLeft.unwrapForShortestPath(center);
topRight.unwrapForShortestPath(center);
bottomRight.unwrapForShortestPath(center);
bottomLeft.unwrapForShortestPath(center);

bounds.extend(topLeft);
bounds.extend(topRight);
bounds.extend(bottomRight);
bounds.extend(bottomLeft);

return bounds;
}
Expand Down
1 change: 1 addition & 0 deletions platform/macos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
### Other changes

* Added Danish and Hebrew localizations. ([#10967](https://github.com/mapbox/mapbox-gl-native/pull/10967), [#11136](https://github.com/mapbox/mapbox-gl-native/pull/11134))
* The `-[MGLMapView convertRect:toCoordinateBoundsFromView:]` method and the `MGLMapView.visibleCoordinateBounds` property’s getter now indicate that the coordinate bounds straddles the antimeridian by extending one side beyond ±180 degrees longitude. ([#11265](https://github.com/mapbox/mapbox-gl-native/pull/11265))
* Feature querying results now account for the `MGLSymbolStyleLayer.circleStrokeWidth` property. ([#10897](https://github.com/mapbox/mapbox-gl-native/pull/10897))
* Removed methods, properties, and constants that had been deprecated as of v0.6.1. ([#11205](https://github.com/mapbox/mapbox-gl-native/pull/11205))

Expand Down
21 changes: 11 additions & 10 deletions platform/macos/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,23 +397,21 @@ MGL_EXPORT IB_DESIGNABLE
want to animate the change, use the `-setVisibleCoordinateBounds:animated:`
method instead.
If a longitude is less than −180 degrees or greater than 180 degrees, the visible
bounds straddles the antimeridian or international date line.
For example, a visible bounds that stretches from Tokyo to San Francisco would have
coordinates of (35.68476, -220.24257) and (37.78428, -122.41310).
If a longitude is less than −180 degrees or greater than 180 degrees, the
visible bounds straddles the antimeridian or international date line. For
example, if both Tokyo and San Francisco are visible, the visible bounds might
extend from (35.68476, −220.24257) to (37.78428, −122.41310).
*/
@property (nonatomic) MGLCoordinateBounds visibleCoordinateBounds;

/**
Changes the receiver’s viewport to fit the given coordinate bounds, optionally
animating the change.
To make the visible bounds go across the antimeridian or international date line,
specify some longitudes less than −180 degrees or greater than 180 degrees.
For example, a visible bounds that stretches from Tokyo to San Francisco would have
coordinates of (35.68476, -220.24257) and (37.78428, -122.41310).
To bring both sides of the antimeridian or international date line into view,
specify some longitudes less than −180 degrees or greater than 180 degrees. For
example, to show both Tokyo and San Francisco simultaneously, you could set the
visible bounds to extend from (35.68476, −220.24257) to (37.78428, −122.41310).
@param bounds The bounds that the viewport will show in its entirety.
@param animated Specify `YES` to animate the change by smoothly scrolling and
Expand Down Expand Up @@ -1060,6 +1058,9 @@ MGL_EXPORT IB_DESIGNABLE
/**
Converts a rectangle in the given view’s coordinate system to a geographic
bounding box.
If a longitude is less than −180 degrees or greater than 180 degrees, the
bounding box straddles the antimeridian or international date line.
@param rect The rectangle to convert.
@param view The view in whose coordinate system the rectangle is expressed.
Expand Down
44 changes: 18 additions & 26 deletions platform/macos/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2717,32 +2717,24 @@ - (MGLCoordinateBounds)convertRect:(NSRect)rect toCoordinateBoundsFromView:(null
/// Converts a rectangle in the given view’s coordinate system to a geographic
/// bounding box.
- (mbgl::LatLngBounds)convertRect:(NSRect)rect toLatLngBoundsFromView:(nullable NSView *)view {
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
bounds.extend([self convertPoint:rect.origin toLatLngFromView:view]);
bounds.extend([self convertPoint:{ NSMaxX(rect), NSMinY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ NSMaxX(rect), NSMaxY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ NSMinX(rect), NSMaxY(rect) } toLatLngFromView:view]);

// The world is wrapping if a point just outside the bounds is also within
// the rect.
mbgl::LatLng outsideLatLng;
if (bounds.west() > -180) {
outsideLatLng = {
(bounds.south() + bounds.north()) / 2,
bounds.west() - 1,
};
} else if (bounds.northeast().longitude() < 180) {
outsideLatLng = {
(bounds.south() + bounds.north()) / 2,
bounds.east() + 1,
};
}

// If the world is wrapping, extend the bounds to cover all longitudes.
if (NSPointInRect([self convertLatLng:outsideLatLng toPointToView:view], rect)) {
bounds.extend(mbgl::LatLng(bounds.south(), -180));
bounds.extend(mbgl::LatLng(bounds.south(), 180));
}
auto bounds = mbgl::LatLngBounds::empty();
auto bottomLeft = [self convertPoint:{ NSMinX(rect), NSMinY(rect) } toLatLngFromView:view];
auto bottomRight = [self convertPoint:{ NSMaxX(rect), NSMinY(rect) } toLatLngFromView:view];
auto topRight = [self convertPoint:{ NSMaxX(rect), NSMaxY(rect) } toLatLngFromView:view];
auto topLeft = [self convertPoint:{ NSMinX(rect), NSMaxY(rect) } toLatLngFromView:view];

// If the bounds straddles the antimeridian, unwrap it so that one side
// extends beyond ±180° longitude.
auto center = [self convertPoint:{ NSMidX(rect), NSMidY(rect) } toLatLngFromView:view];
bottomLeft.unwrapForShortestPath(center);
bottomRight.unwrapForShortestPath(center);
topRight.unwrapForShortestPath(center);
topLeft.unwrapForShortestPath(center);

bounds.extend(bottomLeft);
bounds.extend(bottomRight);
bounds.extend(topRight);
bounds.extend(topLeft);

return bounds;
}
Expand Down

0 comments on commit 0525fd1

Please sign in to comment.