diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeometryConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeometryConstants.java index 67385fdba49..1ac08b12e1c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeometryConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeometryConstants.java @@ -11,15 +11,25 @@ public class GeometryConstants { */ public static final int RADIUS_EARTH_METERS = 6378137; + /** + * This constant represents the lowest longitude value available to represent a wrapped geolocation. + */ + public static final double MIN_WRAP_LONGITUDE = -180; + + /** + * This constant represents the highest longitude value available to represent a wrapped geolocation. + */ + public static final double MAX_WRAP_LONGITUDE = 180; + /** * This constant represents the lowest longitude value available to represent a geolocation. */ - public static final double MIN_LONGITUDE = -180; + public static final double MIN_LONGITUDE = Double.NEGATIVE_INFINITY; /** * This constant represents the highest longitude value available to represent a geolocation. */ - public static final double MAX_LONGITUDE = 180; + public static final double MAX_LONGITUDE = Double.POSITIVE_INFINITY; /** * This constant represents the lowest latitude value available to represent a geolocation. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java index dc1fbfe7404..8ae388549ef 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java @@ -208,7 +208,8 @@ public double getAltitude() { */ @NonNull public LatLng wrap() { - return new LatLng(latitude, wrap(longitude, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE)); + return new LatLng(latitude, wrap(longitude, + GeometryConstants.MIN_WRAP_LONGITUDE, GeometryConstants.MAX_WRAP_LONGITUDE)); } 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 ca39c99c4a3..c8507af1c2b 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 @@ -12,6 +12,11 @@ import java.util.ArrayList; import java.util.List; +import static com.mapbox.mapboxsdk.constants.GeometryConstants.MAX_LATITUDE; +import static com.mapbox.mapboxsdk.constants.GeometryConstants.MAX_WRAP_LONGITUDE; +import static com.mapbox.mapboxsdk.constants.GeometryConstants.MIN_LATITUDE; +import static com.mapbox.mapboxsdk.constants.GeometryConstants.MIN_WRAP_LONGITUDE; + /** * A geographical area representing a latitude/longitude aligned rectangle. *

@@ -33,9 +38,12 @@ 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. + * @since 7.0.0 LatLngBounds cannot be wrapped any more, i.e longitudeWest has to be + * less or equal to longitudeEast. + * + * For example, to represent bounds spanning 20 degrees crossing antimeridian with + * the NE point as (10, -170) and the SW point as (-10, 170), + * use (10, -190) and (-10, -170), or (10, -170) and (-10, -150). * * @param northLatitude Northern Latitude * @param eastLongitude Eastern Longitude @@ -58,8 +66,8 @@ public class LatLngBounds implements Parcelable { */ public static LatLngBounds world() { return LatLngBounds.from( - GeometryConstants.MAX_LATITUDE, GeometryConstants.MAX_LONGITUDE, - GeometryConstants.MIN_LATITUDE, GeometryConstants.MIN_LONGITUDE); + MAX_LATITUDE, MAX_WRAP_LONGITUDE, + MIN_LATITUDE, MIN_WRAP_LONGITUDE); } /** @@ -71,17 +79,7 @@ public static LatLngBounds world() { @NonNull public LatLng getCenter() { 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; - } - } + double longCenter = (this.longitudeEast + this.longitudeWest) / 2.0; return new LatLng(latCenter, longCenter); } @@ -189,18 +187,13 @@ public double getLatitudeSpan() { * @return Span distance */ public double getLongitudeSpan() { - double longSpan = Math.abs(this.longitudeEast - this.longitudeWest); - if (this.longitudeEast >= this.longitudeWest) { - return longSpan; - } - - // shortest span contains antimeridian - return GeometryConstants.LONGITUDE_SPAN - longSpan; + return Math.abs(this.longitudeEast - this.longitudeWest); } - static double getLongitudeSpan(final double longEast, final double longWest) { - double longSpan = Math.abs(longEast - longWest); - if (longEast >= longWest) { + private static double getWrappedLongitudeSpan(final double wrappedLongEast, + final double wrappedLongWest) { + double longSpan = Math.abs(wrappedLongEast - wrappedLongWest); + if (wrappedLongEast >= wrappedLongWest) { return longSpan; } @@ -237,8 +230,8 @@ public String toString() { * @return LatLngBounds */ static LatLngBounds fromLatLngs(final List latLngs) { - double minLat = GeometryConstants.MAX_LATITUDE; - double maxLat = GeometryConstants.MIN_LATITUDE; + double minLat = MAX_LATITUDE; + double maxLat = MIN_LATITUDE; double eastLon = latLngs.get(0).getLongitude(); double westLon = latLngs.get(1).getLongitude(); @@ -265,8 +258,8 @@ static LatLngBounds fromLatLngs(final List latLngs) { final double longitude = gp.getLongitude(); if (!containsLongitude(eastLon, westLon, longitude)) { - final double eastSpan = getLongitudeSpan(longitude, westLon); - final double westSpan = getLongitudeSpan(eastLon, longitude); + final double eastSpan = getWrappedLongitudeSpan(longitude, westLon); + final double westSpan = getWrappedLongitudeSpan(eastLon, longitude); if (eastSpan <= westSpan) { eastLon = longitude; } else { @@ -296,29 +289,26 @@ public LatLng[] toLatLngs() { * otherwise IllegalArgumentException will be thrown. * latNorth should be greater or equal latSouth, otherwise IllegalArgumentException will be thrown. *

- * This method doesn't recalculate most east or most west boundaries. - * Note that lonEast and lonWest will be wrapped to be in the range of [-180, 180], + * Note @since 7.0.0 lonEast and lonWest will NOT be wrapped to be in the range of [-180, 180], * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} + * lonEast should be greater or equal lonWest, otherwise IllegalArgumentException will be thrown. *

*/ public static LatLngBounds from( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latNorth, + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latNorth, double lonEast, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latSouth, double lonWest) { checkParams(latNorth, lonEast, latSouth, lonWest); - lonEast = LatLng.wrap(lonEast, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - lonWest = LatLng.wrap(lonWest, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - return new LatLngBounds(latNorth, lonEast, latSouth, lonWest); } private static void checkParams( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latNorth, + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latNorth, double lonEast, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latSouth, double lonWest) { if (Double.isNaN(latNorth) || Double.isNaN(latSouth)) { @@ -329,18 +319,18 @@ private static void checkParams( throw new IllegalArgumentException("longitude must not be NaN"); } - if (Double.isInfinite(lonEast) || Double.isInfinite(lonWest)) { - throw new IllegalArgumentException("longitude must not be infinite"); - } - - if (latNorth > GeometryConstants.MAX_LATITUDE || latNorth < GeometryConstants.MIN_LATITUDE - || latSouth > GeometryConstants.MAX_LATITUDE || latSouth < GeometryConstants.MIN_LATITUDE) { + if (latNorth > MAX_LATITUDE || latNorth < MIN_LATITUDE + || latSouth > MAX_LATITUDE || latSouth < MIN_LATITUDE) { throw new IllegalArgumentException("latitude must be between -90 and 90"); } if (latNorth < latSouth) { throw new IllegalArgumentException("latNorth cannot be less than latSouth"); } + + if (lonEast < lonWest) { + throw new IllegalArgumentException("lonEast cannot be less than lonWest"); + } } private static double lat_(int z, int y) { @@ -410,14 +400,13 @@ private boolean containsLatitude(final double latitude) { } private boolean containsLongitude(final double longitude) { - return containsLongitude(this.longitudeEast, this.longitudeWest, longitude); + return (longitude <= this.longitudeEast) + || (longitude >= this.longitudeWest); } - static boolean containsLongitude(final double eastLon, final double westLon, final double longitude) { - if (eastLon >= westLon) { - return (longitude <= eastLon) - && (longitude >= westLon); - } + private static boolean containsLongitude(final double eastLon, final double westLon, + final double longitude) { + return (longitude <= eastLon) || (longitude >= westLon); } @@ -451,21 +440,21 @@ public boolean contains(@NonNull final LatLngBounds other) { */ @NonNull public LatLngBounds union(@NonNull LatLngBounds bounds) { - return unionNoParamCheck(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest()); + return unionNoParamCheck(bounds.getLatNorth(), bounds.getLonEast(), + bounds.getLatSouth(), bounds.getLonWest()); } /** - * Returns a new LatLngBounds that stretches to include another LatLngBounds, - * given by corner points. + * Returns a new LatLngBounds that stretches to contain both this and another LatLngBounds. + * *

* This values of northLat and southLat should be in the range of [-90, 90], * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, * otherwise IllegalArgumentException will be thrown. * northLat should be greater or equal southLat, otherwise IllegalArgumentException will be thrown. + * *

- * This method doesn't recalculate most east or most west boundaries. - * Note that eastLon and westLon will be wrapped to be in the range of [-180, 180], - * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} + * eastLon should be greater or equal westLon, otherwise IllegalArgumentException will be thrown. * * @param northLat Northern Latitude corner point * @param eastLon Eastern Longitude corner point @@ -474,72 +463,23 @@ public LatLngBounds union(@NonNull LatLngBounds bounds) { * @return LatLngBounds */ @NonNull - public LatLngBounds union( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double northLat, - double eastLon, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, - double westLon) { + public LatLngBounds union(final double northLat, final double eastLon, + final double southLat, final double westLon) { checkParams(northLat, eastLon, southLat, westLon); return unionNoParamCheck(northLat, eastLon, southLat, westLon); } - @NonNull - private LatLngBounds unionNoParamCheck( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double northLat, - double eastLon, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, - double westLon) { - northLat = (this.latitudeNorth < northLat) ? northLat : this.latitudeNorth; - southLat = (this.latitudeSouth > southLat) ? southLat : this.latitudeSouth; - eastLon = LatLng.wrap(eastLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - westLon = LatLng.wrap(westLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - - // longitudes match - if (this.longitudeEast == eastLon && this.longitudeWest == westLon) { - return new LatLngBounds(northLat, eastLon, southLat, westLon); - } - - boolean eastInThis = containsLongitude(this.longitudeEast, this.longitudeWest, eastLon); - boolean westInThis = containsLongitude(this.longitudeEast, this.longitudeWest, westLon); - boolean thisEastInside = containsLongitude(eastLon, westLon, this.longitudeEast); - boolean thisWestInside = containsLongitude(eastLon, westLon, this.longitudeWest); - - // two intersections on each end - covers entire longitude - if (eastInThis && westInThis && thisEastInside && thisWestInside) { - return new LatLngBounds(northLat, GeometryConstants.MAX_LONGITUDE, southLat, GeometryConstants.MIN_LONGITUDE); - } - - if (eastInThis) { - if (westInThis) { - return new LatLngBounds(northLat, this.longitudeEast, southLat, this.longitudeWest); - } - return new LatLngBounds(northLat, this.longitudeEast, southLat, westLon); - } - - if (thisEastInside) { - if (thisWestInside) { - return new LatLngBounds(northLat, eastLon, southLat, westLon); - } - return new LatLngBounds(northLat, eastLon, southLat, this.longitudeWest); - } - - // bounds do not intersect, find where they will form shortest union - if (LatLngSpan.getLongitudeSpan(eastLon, this.longitudeWest) - < LatLngSpan.getLongitudeSpan(this.longitudeEast, westLon)) { - return new LatLngBounds(northLat, - eastLon, - southLat, - this.longitudeWest); - } + private LatLngBounds unionNoParamCheck(final double northLat, final double eastLon, + final double southLat, final double westLon) { - return new LatLngBounds(northLat, - this.longitudeEast, - southLat, - westLon); + return new LatLngBounds((this.latitudeNorth < northLat) ? northLat : this.latitudeNorth, + (this.longitudeEast < eastLon) ? eastLon : this.longitudeEast, + (this.latitudeSouth > southLat) ? southLat : this.latitudeSouth, + (this.longitudeWest > westLon) ? westLon : this.longitudeWest); } /** - * Returns a new LatLngBounds that is the intersection of this with another box + * Returns a new LatLngBounds that is the intersection of this with another LatLngBounds, * * @param box LatLngBounds to intersect with * @return LatLngBounds @@ -549,17 +489,18 @@ public LatLngBounds intersect(@NonNull LatLngBounds box) { return intersectNoParamCheck(box.getLatNorth(), box.getLonEast(), box.getLatSouth(), box.getLonWest()); } + /** - * Returns a new LatLngBounds that is the intersection of this with another LatLngBounds + * Returns a new LatLngBounds that is the intersection of this with another box. + * *

* This values of northLat and southLat should be in the range of [-90, 90], * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, * otherwise IllegalArgumentException will be thrown. * northLat should be greater or equal southLat, otherwise IllegalArgumentException will be thrown. + * *

- * This method doesn't recalculate most east or most west boundaries. - * Note that eastLon and westLon will be wrapped to be in the range of [-180, 180], - * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} + * eastLon should be greater or equal westLon, otherwise IllegalArgumentException will be thrown. * * @param northLat Northern Latitude corner point * @param eastLon Eastern Longitude corner point @@ -567,71 +508,30 @@ public LatLngBounds intersect(@NonNull LatLngBounds box) { * @param westLon Western Longitude corner point * @return LatLngBounds */ - @Nullable - public LatLngBounds intersect( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double northLat, - double eastLon, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, - double westLon) { - + @NonNull + public LatLngBounds intersect(final double northLat, final double eastLon, + final double southLat, final double westLon) { checkParams(northLat, eastLon, southLat, westLon); - return intersectNoParamCheck(northLat, eastLon, southLat, westLon); } - @Nullable - private LatLngBounds intersectNoParamCheck( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double northLat, - double eastLon, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double southLat, - double westLon) { - - double maxsouthLat = Math.max(getLatSouth(), Math.min(GeometryConstants.MAX_LATITUDE, southLat)); - double minnorthLat = Math.min(getLatNorth(), Math.max(GeometryConstants.MIN_LATITUDE, northLat)); - if (minnorthLat < maxsouthLat) { - return null; - } - - eastLon = LatLng.wrap(eastLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - westLon = LatLng.wrap(westLon, GeometryConstants.MIN_LONGITUDE, GeometryConstants.MAX_LONGITUDE); - - // longitudes match - if (this.longitudeEast == eastLon && this.longitudeWest == westLon) { - return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, westLon); - } - - boolean eastInThis = containsLongitude(this.longitudeEast, this.longitudeWest, eastLon); - boolean westInThis = containsLongitude(this.longitudeEast, this.longitudeWest, westLon); - boolean thisEastInside = containsLongitude(eastLon, westLon, this.longitudeEast); - boolean thisWestInside = containsLongitude(eastLon, westLon, this.longitudeWest); + private LatLngBounds intersectNoParamCheck(final double northLat, final double eastLon, + final double southLat, final double westLon) { - // two intersections : find the one that has longest span - if (eastInThis && westInThis && thisEastInside && thisWestInside) { - - if (getLongitudeSpan(eastLon, this.longitudeWest) > getLongitudeSpan(this.longitudeEast, westLon)) { - return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, this.longitudeWest); + double minLonWest = Math.max(this.longitudeWest, westLon); + double maxLonEast = Math.min(this.longitudeEast, eastLon); + if (maxLonEast >= minLonWest) { + double minLatSouth = Math.max(this.latitudeSouth, southLat); + double maxLatNorth = Math.min(this.latitudeNorth, northLat); + if (maxLatNorth >= minLatSouth) { + return new LatLngBounds(maxLatNorth, maxLonEast, minLatSouth, minLonWest); } - - return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, westLon); } - - if (eastInThis) { - if (westInThis) { - return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, westLon); - } - return new LatLngBounds(minnorthLat, eastLon, maxsouthLat, this.longitudeWest); - } - - if (thisEastInside) { - if (thisWestInside) { - return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, this.longitudeWest); - } - return new LatLngBounds(minnorthLat, this.longitudeEast, maxsouthLat, westLon); - } - return null; } + + /** * Inner class responsible for recreating Parcels into objects. */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java index f069d7807fc..bb802a80320 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java @@ -138,20 +138,4 @@ public int hashCode() { result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } - - /** - * Get the absolute distance, in degrees, between the west and - * east boundaries of this LatLngBounds - * - * @return Span distance - */ - static double getLongitudeSpan(double east, double west) { - double longSpan = Math.abs(east - west); - if (east > west) { - return longSpan; - } - - // shortest span contains antimeridian - return GeometryConstants.LONGITUDE_SPAN - longSpan; - } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java index a45728c4949..af000e88b57 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java @@ -94,7 +94,7 @@ public void dateLineSpanBuilder2() { @Test public void dateLineSpanFrom1() { - latLngBounds = LatLngBounds.from(10, -170, -10, 170); + latLngBounds = LatLngBounds.from(10, -170, -10, -190); LatLngSpan latLngSpan = latLngBounds.getSpan(); assertEquals("LatLngSpan should be shortest distance", new LatLngSpan(20, 20), latLngSpan); @@ -118,28 +118,28 @@ public void zeroLongitudeSpan() { @Test public void nearDateLineCenter1() { - latLngBounds = LatLngBounds.from(10, -175, -10, 165); + latLngBounds = LatLngBounds.from(10, -175, -10, -195); LatLng center = latLngBounds.getCenter(); - assertEquals("Center should match", new LatLng(0, 175), center); + assertEquals("Center should match", new LatLng(0, -185), center); } @Test public void nearDateLineCenter2() { - latLngBounds = LatLngBounds.from(10, -165, -10, 175); + latLngBounds = LatLngBounds.from(10, 195, -10, 175); LatLng center = latLngBounds.getCenter(); - assertEquals("Center should match", new LatLng(0, -175), center); + assertEquals("Center should match", new LatLng(0, 185), center); } @Test public void nearDateLineCenter3() { - latLngBounds = LatLngBounds.from(10, -170, -10, 170); + latLngBounds = LatLngBounds.from(10, -170, -10, -190); LatLng center = latLngBounds.getCenter(); assertEquals("Center should match", new LatLng(0, -180), center); } @Test public void nearDateLineCenter4() { - latLngBounds = LatLngBounds.from(10, -180, -10, 0); + latLngBounds = LatLngBounds.from(10, 180, -10, 0); LatLng center = latLngBounds.getCenter(); assertEquals("Center should match", new LatLng(0, 90), center); } @@ -409,10 +409,10 @@ public void intersectEastWrapCheck() { @Test public void intersectWestWrapCheck() { - LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, 150); + LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, -210); LatLngBounds latLngBounds2 = LatLngBounds.from(0, 0, -90, -200); - LatLngBounds intersectLatLngBounds = LatLngBounds.from(0, 0, -10, 160); + LatLngBounds intersectLatLngBounds = LatLngBounds.from(0, 0, -10, -200); assertEquals(latLngBounds1.intersect(latLngBounds2), intersectLatLngBounds); assertEquals(latLngBounds2.intersect(latLngBounds1), intersectLatLngBounds); @@ -697,9 +697,9 @@ public void testParcelable() { @Test public void fromTileID() { LatLngBounds bounds = LatLngBounds.from(0, 0, 0); - assertEquals(GeometryConstants.MIN_LONGITUDE, bounds.getLonWest(), DELTA); + assertEquals(GeometryConstants.MIN_WRAP_LONGITUDE, bounds.getLonWest(), DELTA); assertEquals(GeometryConstants.MIN_MERCATOR_LATITUDE, bounds.getLatSouth(), DELTA); - assertEquals(GeometryConstants.MAX_LONGITUDE, bounds.getLonEast(), DELTA); + assertEquals(GeometryConstants.MAX_WRAP_LONGITUDE, bounds.getLonEast(), DELTA); assertEquals(GeometryConstants.MAX_MERCATOR_LATITUDE, bounds.getLatNorth(), DELTA); bounds = LatLngBounds.from(10, 288, 385); @@ -742,10 +742,10 @@ public void testConstructorChecksNorthLatitudeLessThanThanNegative90() { } @Test - public void testConstructorChecksEastLongitudeInfinity() { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("longitude must not be infinite"); - LatLngBounds.from(0, Double.POSITIVE_INFINITY, -20, -20); + public void testConstructorEastLongitudeInfinityAllowed() { + LatLngBounds latLngBounds = + LatLngBounds.from(0, Double.POSITIVE_INFINITY, -20, -20); + assertEquals(Double.POSITIVE_INFINITY, latLngBounds.getLonEast(), DELTA); } @Test @@ -777,10 +777,10 @@ public void testConstructorChecksSouthLatitudeLessThanThanNegative90() { } @Test - public void testConstructorChecksWestLongitudeInfinity() { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("longitude must not be infinite"); - LatLngBounds.from(20, 20, 0, Double.POSITIVE_INFINITY); + public void testConstructorWestLongitudeInfinityAllowed() { + LatLngBounds latLngBounds = + LatLngBounds.from(20, 20, 0, Double.NEGATIVE_INFINITY); + assertEquals(Double.NEGATIVE_INFINITY, latLngBounds.getLonWest(), DELTA); } @Test @@ -789,4 +789,11 @@ public void testConstructorCheckLatSouthGreaterLatNorth() { exception.expectMessage("latNorth cannot be less than latSouth"); LatLngBounds.from(0, 20, 20, 0); } + + @Test + public void testConstructorCheckLonWestGreaterLonEast() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("lonEast cannot be less than lonWest"); + LatLngBounds.from(20, 0, 0, 20); + } }