diff options
author | Osana Babayan <32496536+osana@users.noreply.github.com> | 2018-02-15 12:02:00 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-15 12:02:00 -0500 |
commit | e4a40fe7974462369533722a20d252b753a55347 (patch) | |
tree | 0a6273b53a9b822d0dcca6a0fe53ea06b298d20f /platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java | |
parent | 82de856c94bbc090ba30186011610da5e233e277 (diff) | |
download | qtlocation-mapboxgl-e4a40fe7974462369533722a20d252b753a55347.tar.gz |
[android] bounds can go over the antimeridian / date line. (#10892)
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java')
-rw-r--r-- | platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java index cf647224ae..fc8d2ec8f0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java @@ -29,6 +29,10 @@ public class LatLngBounds implements Parcelable { * Construct a new LatLngBounds based on its corners, given in NESW * order. * + * If eastern longitude is smaller than the western one, bounds will include antimeridian. + * For example, if the NE point is (10, -170) and the SW point is (-10, 170), then bounds will span over 20 degrees + * and cross the antimeridian. + * * @param northLatitude Northern Latitude * @param eastLongitude Eastern Longitude * @param southLatitude Southern Latitude @@ -48,10 +52,9 @@ public class LatLngBounds implements Parcelable { * @return the bounds representing the world */ public static LatLngBounds world() { - return new LatLngBounds.Builder() - .include(new LatLng(GeometryConstants.MAX_LATITUDE, GeometryConstants.MAX_LONGITUDE)) - .include(new LatLng(GeometryConstants.MIN_LATITUDE, GeometryConstants.MIN_LONGITUDE)) - .build(); + return LatLngBounds.from( + GeometryConstants.MAX_LATITUDE, GeometryConstants.MAX_LONGITUDE, + GeometryConstants.MIN_LATITUDE, GeometryConstants.MIN_LONGITUDE); } /** @@ -61,8 +64,21 @@ public class LatLngBounds implements Parcelable { * @return LatLng center of this LatLngBounds */ public LatLng getCenter() { - return new LatLng((this.latitudeNorth + this.latitudeSouth) / 2, - (this.longitudeEast + this.longitudeWest) / 2); + double latCenter = (this.latitudeNorth + this.latitudeSouth) / 2.0; + double longCenter; + + if (this.longitudeEast > this.longitudeWest) { + longCenter = (this.longitudeEast + this.longitudeWest) / 2; + } else { + double halfSpan = (GeometryConstants.LONGITUDE_SPAN + this.longitudeEast - this.longitudeWest) / 2.0; + longCenter = this.longitudeWest + halfSpan; + if (longCenter >= GeometryConstants.MAX_LONGITUDE) { + longCenter = this.longitudeEast - halfSpan; + } + return new LatLng(latCenter, longCenter); + } + + return new LatLng(latCenter, longCenter); } /** @@ -163,10 +179,26 @@ public class LatLngBounds implements Parcelable { * @return Span distance */ public double getLongitudeSpan() { - return Math.abs(this.longitudeEast - this.longitudeWest); + double longSpan = Math.abs(this.longitudeEast - this.longitudeWest); + if (this.longitudeEast > this.longitudeWest) { + return longSpan; + } + + // shortest span contains antimeridian + return GeometryConstants.LONGITUDE_SPAN - longSpan; } + static double getLongitudeSpan(final double longEast, final double longWest) { + double longSpan = Math.abs(longEast - longWest); + if (longEast > longWest) { + return longSpan; + } + + // shortest span contains antimeridian + return GeometryConstants.LONGITUDE_SPAN - longSpan; + } + /** * Validate if LatLngBounds is empty, determined if absolute distance is * @@ -196,21 +228,44 @@ public class LatLngBounds implements Parcelable { */ static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) { double minLat = GeometryConstants.MAX_LATITUDE; - double minLon = GeometryConstants.MAX_LONGITUDE; double maxLat = GeometryConstants.MIN_LATITUDE; - double maxLon = GeometryConstants.MIN_LONGITUDE; + + double eastLon = latLngs.get(0).getLongitude(); + double westLon = latLngs.get(1).getLongitude(); + double lonSpan = Math.abs(eastLon - westLon); + if (lonSpan < GeometryConstants.LONGITUDE_SPAN / 2) { + if (eastLon < westLon) { + double temp = eastLon; + eastLon = westLon; + westLon = temp; + } + } else { + lonSpan = GeometryConstants.LONGITUDE_SPAN - lonSpan; + if (westLon < eastLon) { + double temp = eastLon; + eastLon = westLon; + westLon = temp; + } + } for (final ILatLng gp : latLngs) { final double latitude = gp.getLatitude(); - final double longitude = gp.getLongitude(); - minLat = Math.min(minLat, latitude); - minLon = Math.min(minLon, longitude); maxLat = Math.max(maxLat, latitude); - maxLon = Math.max(maxLon, longitude); + + final double longitude = gp.getLongitude(); + if (!containsLongitude(eastLon, westLon, longitude)) { + final double eastSpan = getLongitudeSpan(longitude, westLon); + final double westSpan = getLongitudeSpan(eastLon, longitude); + if (eastSpan <= westSpan) { + eastLon = longitude; + } else { + westLon = longitude; + } + } } - return new LatLngBounds(maxLat, maxLon, minLat, minLon); + return new LatLngBounds(maxLat, eastLon, minLat, westLon); } /** @@ -322,6 +377,24 @@ public class LatLngBounds implements Parcelable { return false; } + + private boolean containsLatitude(final double latitude) { + return (latitude <= this.latitudeNorth) + && (latitude >= this.latitudeSouth); + } + + private boolean containsLongitude(final double longitude) { + return containsLongitude(this.longitudeEast, this.longitudeWest, longitude); + } + + static boolean containsLongitude(final double eastLon, final double westLon, final double longitude) { + if (eastLon > westLon) { + return (longitude <= eastLon) + && (longitude >= westLon); + } + return (longitude < eastLon) || (longitude > westLon); + } + /** * Determines whether this LatLngBounds contains a point. * @@ -329,12 +402,8 @@ public class LatLngBounds implements Parcelable { * @return true, if the point is contained within the bounds */ public boolean contains(final ILatLng latLng) { - final double latitude = latLng.getLatitude(); - final double longitude = latLng.getLongitude(); - return ((latitude <= this.latitudeNorth) - && (latitude >= this.latitudeSouth)) - && ((longitude <= this.longitudeEast) - && (longitude >= this.longitudeWest)); + return containsLatitude(latLng.getLatitude()) + && containsLongitude(latLng.getLongitude()); } /** @@ -344,7 +413,8 @@ public class LatLngBounds implements Parcelable { * @return true, if the bounds is contained within the bounds */ public boolean contains(final LatLngBounds other) { - return contains(other.getNorthEast()) && contains(other.getSouthWest()); + return contains(other.getNorthEast()) + && contains(other.getSouthWest()); } /** |