From 6aea5b561ae702ad8e8dd184230e52e53c3c8375 Mon Sep 17 00:00:00 2001 From: Osana Babayan <32496536+osana@users.noreply.github.com> Date: Wed, 12 Dec 2018 09:06:12 -0500 Subject: [android] LatLng bounds cannot be wrapped (#13419) --- .../mapboxsdk/constants/GeometryConstants.java | 14 +- .../java/com/mapbox/mapboxsdk/geometry/LatLng.java | 3 +- .../mapbox/mapboxsdk/geometry/LatLngBounds.java | 318 +++++----------- .../com/mapbox/mapboxsdk/geometry/LatLngSpan.java | 18 - .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 7 +- .../java/com/mapbox/mapboxsdk/maps/Projection.java | 4 + .../mapboxsdk/geometry/LatLngBoundsTest.java | 421 +++++++++++---------- .../com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt | 5 +- .../testapp/geometry/LatLngBoundsTest.java | 1 - .../mapboxsdk/testapp/maps/VisibleRegionTest.kt | 49 ++- .../maplayout/LatLngBoundsForCameraActivity.java | 56 ++- .../src/main/res/menu/menu_bounds.xml | 12 + .../src/main/res/values/actions.xml | 2 + platform/android/src/geometry/lat_lng_bounds.cpp | 2 - 14 files changed, 430 insertions(+), 482 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_bounds.xml 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 67385fdba4..6f6e777922 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.MAX_VALUE; /** * 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.MAX_VALUE; /** * 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 dc1fbfe740..8ae388549e 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 class LatLng implements Parcelable { */ @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 ca39c99c4a..263780f473 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,13 @@ import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; 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_LONGITUDE; +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_LONGITUDE; +import static com.mapbox.mapboxsdk.constants.GeometryConstants.MIN_WRAP_LONGITUDE; + /** * A geographical area representing a latitude/longitude aligned rectangle. *

@@ -33,9 +40,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 @@ -43,8 +53,8 @@ public class LatLngBounds implements Parcelable { * @param westLongitude Western Longitude */ @Keep - LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude, - final double westLongitude) { + LatLngBounds(final double northLatitude, final double eastLongitude, + final double southLatitude, final double westLongitude) { this.latitudeNorth = northLatitude; this.longitudeEast = eastLongitude; this.latitudeSouth = southLatitude; @@ -58,8 +68,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 +81,7 @@ public class LatLngBounds implements Parcelable { @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,23 +189,7 @@ public class LatLngBounds implements Parcelable { * @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; - } - - 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; + return Math.abs(this.longitudeEast - this.longitudeWest); } /** @@ -226,7 +210,7 @@ public class LatLngBounds implements Parcelable { @Override public String toString() { return "N:" + this.latitudeNorth + "; E:" + this.longitudeEast + "; S:" + this.latitudeSouth - + "; W:" + this.longitudeWest; + + "; W:" + this.longitudeWest; } /** @@ -237,45 +221,21 @@ public class LatLngBounds implements Parcelable { * @return LatLngBounds */ static LatLngBounds fromLatLngs(final List latLngs) { - double minLat = GeometryConstants.MAX_LATITUDE; - double maxLat = GeometryConstants.MIN_LATITUDE; - - 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; - } - } + double minLat = MAX_LATITUDE; + double minLon = MAX_LONGITUDE; + double maxLat = MIN_LATITUDE; + double maxLon = MIN_LONGITUDE; for (final LatLng 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); - - 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; - } - } + maxLon = Math.max(maxLon, longitude); } - return new LatLngBounds(maxLat, eastLon, minLat, westLon); + return new LatLngBounds(maxLat, maxLon, minLat, minLon); } /** @@ -297,29 +257,27 @@ public class LatLngBounds implements Parcelable { * 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, - double lonEast, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, - double lonWest) { + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latNorth, + double lonEast, + @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, - double lonEast, - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) double latSouth, - double lonWest) { + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latNorth, + double lonEast, + @FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latSouth, + double lonWest) { if (Double.isNaN(latNorth) || Double.isNaN(latSouth)) { throw new IllegalArgumentException("latitude must not be NaN"); @@ -333,14 +291,18 @@ public class LatLngBounds implements Parcelable { 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) { @@ -349,7 +311,7 @@ public class LatLngBounds implements Parcelable { } private static double lon_(int z, int x) { - return x / Math.pow(2.0, z) * 360.0 - GeometryConstants.MAX_LONGITUDE; + return x / Math.pow(2.0, z) * 360.0 - GeometryConstants.MAX_WRAP_LONGITUDE; } /** @@ -376,10 +338,10 @@ public class LatLngBounds implements Parcelable { @NonNull public LatLngBounds include(@NonNull LatLng latLng) { return new LatLngBounds.Builder() - .include(getNorthEast()) - .include(getSouthWest()) - .include(latLng) - .build(); + .include(getNorthEast()) + .include(getSouthWest()) + .include(latLng) + .build(); } /** @@ -396,9 +358,9 @@ public class LatLngBounds implements Parcelable { if (o instanceof LatLngBounds) { LatLngBounds other = (LatLngBounds) o; return latitudeNorth == other.getLatNorth() - && latitudeSouth == other.getLatSouth() - && longitudeEast == other.getLonEast() - && longitudeWest == other.getLonWest(); + && latitudeSouth == other.getLatSouth() + && longitudeEast == other.getLonEast() + && longitudeWest == other.getLonWest(); } return false; } @@ -406,19 +368,12 @@ public class LatLngBounds implements Parcelable { private boolean containsLatitude(final double latitude) { return (latitude <= this.latitudeNorth) - && (latitude >= this.latitudeSouth); + && (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); + return (longitude <= this.longitudeEast) + && (longitude >= this.longitudeWest); } /** @@ -451,21 +406,21 @@ public class LatLngBounds implements Parcelable { */ @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 +429,23 @@ public class LatLngBounds implements Parcelable { * @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); - } + private LatLngBounds unionNoParamCheck(final double northLat, final double eastLon, + final double southLat, final double westLon) { - 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); - } - - 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 +455,18 @@ public class LatLngBounds implements Parcelable { 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 +474,30 @@ public class LatLngBounds implements Parcelable { * @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); - - // 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); - } + private LatLngBounds intersectNoParamCheck(final double northLat, final double eastLon, + final double southLat, final double westLon) { - 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); + 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); } - return null; } + + /** * Inner class responsible for recreating Parcels into objects. */ @@ -656,9 +522,9 @@ public class LatLngBounds implements Parcelable { @Override public int hashCode() { return (int) ((latitudeNorth + 90) - + ((latitudeSouth + 90) * 1000) - + ((longitudeEast + 180) * 1000000) - + ((longitudeWest + 180) * 1000000000)); + + ((latitudeSouth + 90) * 1000) + + ((longitudeEast + 180) * 1000000) + + ((longitudeWest + 180) * 1000000000)); } /** 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 f069d7807f..941e6652f9 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 @@ -4,8 +4,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; -import com.mapbox.mapboxsdk.constants.GeometryConstants; - /** * A geographical span defined by its latitude and longitude span. */ @@ -138,20 +136,4 @@ public class LatLngSpan implements Parcelable { 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/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index b0137615d0..33d8a4881a 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -264,8 +264,7 @@ final class NativeMapView { if (checkState("")) { return new LatLng(); } - // wrap longitude values coming from core - return nativeGetLatLng().wrap(); + return nativeGetLatLng(); } public CameraPosition getCameraForLatLngBounds(LatLngBounds bounds, int[] padding, double bearing, double tilt) { @@ -638,7 +637,7 @@ final class NativeMapView { return new LatLng(); } return nativeLatLngForProjectedMeters(projectedMeters.getNorthing(), - projectedMeters.getEasting()).wrap(); + projectedMeters.getEasting()); } @NonNull @@ -655,7 +654,7 @@ final class NativeMapView { if (checkState("latLngForPixel")) { return new LatLng(); } - return nativeLatLngForPixel(pixel.x / pixelRatio, pixel.y / pixelRatio).wrap(); + return nativeLatLngForPixel(pixel.x / pixelRatio, pixel.y / pixelRatio); } public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java index c455ae606f..cbf5426012 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -176,6 +176,10 @@ public class Projection { } } + if (east < west) { + return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, + LatLngBounds.from(north, east + GeometryConstants.LONGITUDE_SPAN, south, west)); + } return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, LatLngBounds.from(north, east, south, west)); } 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 a45728c494..6c44c29e3b 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 @@ -30,9 +30,9 @@ public class LatLngBoundsTest { @Before public void beforeTest() { latLngBounds = new LatLngBounds.Builder() - .include(LAT_LNG_NULL_ISLAND) - .include(LAT_LNG_NOT_NULL_ISLAND) - .build(); + .include(LAT_LNG_NULL_ISLAND) + .include(LAT_LNG_NOT_NULL_ISLAND) + .build(); } @Test @@ -71,41 +71,41 @@ public class LatLngBoundsTest { @Test public void dateLineSpanBuilder1() { latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, -170)) - .include(new LatLng(-10, 170)) - .build(); + .include(new LatLng(10, -170)) + .include(new LatLng(-10, 170)) + .build(); LatLngSpan latLngSpan = latLngBounds.getSpan(); - assertEquals("LatLngSpan should be shortest distance", new LatLngSpan(20, 20), - latLngSpan); + assertEquals("LatLngSpan should be the same", new LatLngSpan(20, 340), + latLngSpan); } @Test public void dateLineSpanBuilder2() { latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(-10, -170)) - .include(new LatLng(10, 170)) - .build(); + .include(new LatLng(-10, -170)) + .include(new LatLng(10, 170)) + .build(); LatLngSpan latLngSpan = latLngBounds.getSpan(); - assertEquals("LatLngSpan should be shortest distance", new LatLngSpan(20, 20), - latLngSpan); + assertEquals("LatLngSpan should be the same", new LatLngSpan(20, 340), + latLngSpan); } @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); + assertEquals("LatLngSpan should be the same", new LatLngSpan(20, 20), + latLngSpan); } @Test public void dateLineSpanFrom2() { latLngBounds = LatLngBounds.from(10, 170, -10, -170); LatLngSpan latLngSpan = latLngBounds.getSpan(); - assertEquals("LatLngSpan should be shortest distance", new LatLngSpan(20, 340), - latLngSpan); + assertEquals("LatLngSpan should be the same", new LatLngSpan(20, 340), + latLngSpan); } @Test @@ -113,33 +113,33 @@ public class LatLngBoundsTest { latLngBounds = LatLngBounds.from(10, 10, -10, 10); LatLngSpan latLngSpan = latLngBounds.getSpan(); assertEquals("LatLngSpan should be shortest distance", new LatLngSpan(20, 0), - latLngSpan); + latLngSpan); } @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); } @@ -174,20 +174,20 @@ public class LatLngBoundsTest { @Test public void notEmptySpan() { latLngBounds = new LatLngBounds.Builder() - .include(LAT_LNG_NOT_NULL_ISLAND) - .include(LAT_LNG_NULL_ISLAND) - .build(); + .include(LAT_LNG_NOT_NULL_ISLAND) + .include(LAT_LNG_NULL_ISLAND) + .build(); assertFalse("Should not be empty", latLngBounds.isEmptySpan()); } @Test public void includeSameLatLngs() { latLngBounds = new LatLngBounds.Builder() - .include(LAT_LNG_NOT_NULL_ISLAND) - .include(LAT_LNG_NOT_NULL_ISLAND) - .include(LAT_LNG_NULL_ISLAND) - .include(LAT_LNG_NULL_ISLAND) - .build(); + .include(LAT_LNG_NOT_NULL_ISLAND) + .include(LAT_LNG_NOT_NULL_ISLAND) + .include(LAT_LNG_NULL_ISLAND) + .include(LAT_LNG_NULL_ISLAND) + .build(); assertEquals(latLngBounds.getNorthEast(), LAT_LNG_NOT_NULL_ISLAND); assertEquals(latLngBounds.getSouthWest(), LAT_LNG_NULL_ISLAND); } @@ -195,13 +195,13 @@ public class LatLngBoundsTest { @Test public void toLatLngs() { latLngBounds = new LatLngBounds.Builder() - .include(LAT_LNG_NOT_NULL_ISLAND) - .include(LAT_LNG_NULL_ISLAND) - .build(); + .include(LAT_LNG_NOT_NULL_ISLAND) + .include(LAT_LNG_NULL_ISLAND) + .build(); assertArrayEquals("LatLngs should match", - new LatLng[] {LAT_LNG_NOT_NULL_ISLAND, LAT_LNG_NULL_ISLAND}, - latLngBounds.toLatLngs()); + new LatLng[] {LAT_LNG_NOT_NULL_ISLAND, LAT_LNG_NULL_ISLAND}, + latLngBounds.toLatLngs()); } @Test @@ -216,13 +216,13 @@ public class LatLngBoundsTest { points.add(LAT_LNG_NOT_NULL_ISLAND); LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .includes(points) - .build(); + .includes(points) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(LAT_LNG_NULL_ISLAND) - .include(LAT_LNG_NOT_NULL_ISLAND) - .build(); + .include(LAT_LNG_NULL_ISLAND) + .include(LAT_LNG_NOT_NULL_ISLAND) + .build(); assertEquals("LatLngBounds should match", latLngBounds1, latLngBounds2); } @@ -230,20 +230,20 @@ public class LatLngBoundsTest { @Test public void includesOrderDoesNotMatter() { LatLngBounds sameLongitudeFirst = new LatLngBounds.Builder() - .include(new LatLng(50, 10)) // southWest - .include(new LatLng(60, 10)) - .include(new LatLng(60, 20)) // northEast - .include(new LatLng(50, 20)) - .include(new LatLng(50, 10)) // southWest again - .build(); + .include(new LatLng(50, 10)) // southWest + .include(new LatLng(60, 10)) + .include(new LatLng(60, 20)) // northEast + .include(new LatLng(50, 20)) + .include(new LatLng(50, 10)) // southWest again + .build(); LatLngBounds sameLatitudeFirst = new LatLngBounds.Builder() - .include(new LatLng(50, 20)) - .include(new LatLng(50, 10)) // southWest - .include(new LatLng(60, 10)) - .include(new LatLng(60, 20)) // northEast - .include(new LatLng(50, 20)) - .build(); + .include(new LatLng(50, 20)) + .include(new LatLng(50, 10)) // southWest + .include(new LatLng(60, 10)) + .include(new LatLng(60, 20)) // northEast + .include(new LatLng(50, 20)) + .build(); assertEquals(sameLatitudeFirst, sameLongitudeFirst); } @@ -252,77 +252,81 @@ public class LatLngBoundsTest { public void includesOverDateline1() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, -170)) - .include(new LatLng(-10, -175)) - .include(new LatLng(0, 170)) - .build(); + .include(new LatLng(10, -170)) + .include(new LatLng(-10, -175)) + .include(new LatLng(0, -190)) + .build(); + LatLngSpan latLngSpan = latLngBounds.getSpan(); assertEquals("LatLngSpan should be the same", - new LatLngSpan(20, 20), latLngBounds.getSpan()); + new LatLngSpan(20, 20), latLngSpan); } @Test public void includesOverDateline2() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, 170)) - .include(new LatLng(-10, 175)) - .include(new LatLng(0, -170)) - .build(); + .include(new LatLng(10, 170)) + .include(new LatLng(-10, 175)) + .include(new LatLng(0, 190)) + .build(); assertEquals("LatLngSpan should be the same", - new LatLngSpan(20, 20), latLngBounds.getSpan()); + new LatLngSpan(20, 20), latLngBounds.getSpan()); } @Test public void includesOverDateline3() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, 170)) - .include(new LatLng(-10, -170)) - .include(new LatLng(0, -180)) - .include(new LatLng(5, 180)) - .build(); + .include(new LatLng(10, -190)) + .include(new LatLng(-10, -170)) + .include(new LatLng(0, -180)) + .include(new LatLng(5, -180)) + .build(); assertEquals("LatLngSpan should be the same", - new LatLngSpan(20, 20), latLngBounds.getSpan()); + new LatLngSpan(20, 20), latLngBounds.getSpan()); } @Test public void containsNot() { - assertFalse("LatLng should not be included", latLngBounds.contains(new LatLng(3, 1))); + assertFalse("LatLng should not be included", + latLngBounds.contains(new LatLng(3, 1))); } @Test public void containsBoundsInWorld() { - assertTrue("LatLngBounds should be contained in the world", LatLngBounds.world().contains(latLngBounds)); + assertTrue("LatLngBounds should be contained in the world", + LatLngBounds.world().contains(latLngBounds)); } @Test public void worldSpan() { assertEquals("LatLngBounds world span should be 180, 360", - GeometryConstants.LATITUDE_SPAN, LatLngBounds.world().getLatitudeSpan(), DELTA); + GeometryConstants.LATITUDE_SPAN, LatLngBounds.world().getLatitudeSpan(), DELTA); assertEquals("LatLngBounds world span should be 180, 360", - GeometryConstants.LONGITUDE_SPAN, LatLngBounds.world().getLongitudeSpan(), DELTA); + GeometryConstants.LONGITUDE_SPAN, LatLngBounds.world().getLongitudeSpan(), DELTA); } @Test public void emptySpan() { - LatLngBounds latLngBounds = LatLngBounds.from(GeometryConstants.MIN_LATITUDE, GeometryConstants.MAX_LONGITUDE, - GeometryConstants.MIN_LATITUDE, GeometryConstants.MAX_LONGITUDE); + LatLngBounds latLngBounds = LatLngBounds.from( + GeometryConstants.MIN_LATITUDE, GeometryConstants.MAX_LONGITUDE, + GeometryConstants.MIN_LATITUDE, GeometryConstants.MAX_LONGITUDE); assertTrue("LatLngBounds empty span", latLngBounds.isEmptySpan()); } @Test public void containsBounds() { LatLngBounds inner = new LatLngBounds.Builder() - .include(new LatLng(-5, -5)) - .include(new LatLng(5, 5)) - .build(); + .include(new LatLng(-5, -5)) + .include(new LatLng(5, 5)) + .build(); LatLngBounds outer = new LatLngBounds.Builder() - .include(new LatLng(-10, -10)) - .include(new LatLng(10, 10)) - .build(); + .include(new LatLng(-10, -10)) + .include(new LatLng(10, 10)) + .build(); assertTrue(outer.contains(inner)); assertFalse(inner.contains(outer)); } @@ -335,11 +339,12 @@ public class LatLngBoundsTest { @Test public void equality() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(LAT_LNG_NULL_ISLAND) - .include(LAT_LNG_NOT_NULL_ISLAND) - .build(); + .include(LAT_LNG_NULL_ISLAND) + .include(LAT_LNG_NOT_NULL_ISLAND) + .build(); assertEquals("equality should match", this.latLngBounds, latLngBounds); - assertEquals("not equal to a different object type", this.latLngBounds.equals(LAT_LNG_NOT_NULL_ISLAND), false); + assertEquals("not equal to a different object type", + this.latLngBounds.equals(LAT_LNG_NOT_NULL_ISLAND), false); } @Test @@ -350,19 +355,22 @@ public class LatLngBoundsTest { @Test public void intersect() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(1, 1)) - .include(LAT_LNG_NULL_ISLAND) - .build(); - assertEquals("intersect should match", latLngBounds, latLngBounds.intersect(this.latLngBounds.getLatNorth(), - this.latLngBounds.getLonEast(), this.latLngBounds.getLatSouth(), this.latLngBounds.getLonWest())); + .include(new LatLng(1, 1)) + .include(LAT_LNG_NULL_ISLAND) + .build(); + assertEquals("intersect should match", latLngBounds, + latLngBounds.intersect(this.latLngBounds.getLatNorth(), + this.latLngBounds.getLonEast(), + this.latLngBounds.getLatSouth(), + this.latLngBounds.getLonWest())); } @Test public void intersectNot() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, 10)) - .include(new LatLng(9, 8)) - .build(); + .include(new LatLng(10, 10)) + .include(new LatLng(9, 8)) + .build(); assertNull(latLngBounds.intersect(this.latLngBounds)); } @@ -371,8 +379,8 @@ public class LatLngBoundsTest { exception.expect(IllegalArgumentException.class); exception.expectMessage("latitude must be between -90 and 90"); LatLngBounds intersectLatLngBounds = - LatLngBounds.from(10, 10, 0, 0) - .intersect(200, 200, 0, 0); + LatLngBounds.from(10, 10, 0, 0) + .intersect(200, 200, 0, 0); } @Test @@ -380,39 +388,45 @@ public class LatLngBoundsTest { exception.expect(IllegalArgumentException.class); exception.expectMessage("latitude must be between -90 and 90"); LatLngBounds intersectLatLngBounds = - LatLngBounds.from(0, 0, -10, -10) - .intersect(0, 0, -200, -200); + LatLngBounds.from(0, 0, -10, -10) + .intersect(0, 0, -200, -200); } @Test public void intersectSouthLessThanNorthCheck() { exception.expect(IllegalArgumentException.class); exception.expectMessage("latNorth cannot be less than latSouth"); + LatLngBounds intersectLatLngBounds = + LatLngBounds.from(10, 10, 0, 0) + .intersect(0, 200, 20, 0); + } + @Test + public void intersectEastLessThanWestCheck() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("lonEast cannot be less than lonWest"); LatLngBounds intersectLatLngBounds = - LatLngBounds.from(10, 10, 0, 0) + LatLngBounds.from(10, -10, 0, 0) .intersect(0, 200, 20, 0); } + public void intersectEastDoesNotWrapCheck() { - @Test - public void intersectEastWrapCheck() { - - LatLngBounds latLngBounds1 = LatLngBounds.from(10, -150, 0, 0); + LatLngBounds latLngBounds1 = LatLngBounds.from(10, 210, 0, 0); LatLngBounds latLngBounds2 = LatLngBounds.from(90, 200, 0, 0); - LatLngBounds intersectLatLngBounds = LatLngBounds.from(10, -160, 0, 0); + LatLngBounds intersectLatLngBounds = LatLngBounds.from(10, 200, 0, 0); assertEquals(latLngBounds1.intersect(latLngBounds2), intersectLatLngBounds); assertEquals(latLngBounds2.intersect(latLngBounds1), intersectLatLngBounds); } @Test - public void intersectWestWrapCheck() { - LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, 150); + public void intersectDoesNotWestWrapCheck() { + 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); @@ -421,46 +435,46 @@ public class LatLngBoundsTest { @Test public void innerUnion() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(1, 1)) - .include(LAT_LNG_NULL_ISLAND) - .build(); + .include(new LatLng(1, 1)) + .include(LAT_LNG_NULL_ISLAND) + .build(); assertEquals("union should match", latLngBounds, latLngBounds.intersect(this.latLngBounds)); } @Test public void outerUnion() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, 10)) - .include(new LatLng(9, 8)) - .build(); + .include(new LatLng(10, 10)) + .include(new LatLng(9, 8)) + .build(); assertEquals("outer union should match", - latLngBounds.union(this.latLngBounds), - new LatLngBounds.Builder() - .include(new LatLng(10, 10)) - .include(LAT_LNG_NULL_ISLAND) - .build()); + latLngBounds.union(this.latLngBounds), + new LatLngBounds.Builder() + .include(new LatLng(10, 10)) + .include(LAT_LNG_NULL_ISLAND) + .build()); } @Test public void unionOverDateLine() { LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .include(new LatLng(10, 170)) - .include(new LatLng(0, 160)) - .build(); + .include(new LatLng(10, 170)) + .include(new LatLng(0, 160)) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(new LatLng(0, -170)) - .include(new LatLng(-10, -160)) - .build(); + .include(new LatLng(0, 190)) + .include(new LatLng(-10, 200)) + .build(); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, - new LatLngBounds.Builder() - .include(new LatLng(10, 160)) - .include(new LatLng(-10, -160)) - .build()); + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, 200)) + .build()); assertEquals(union1, union2); } @@ -468,23 +482,23 @@ public class LatLngBoundsTest { @Test public void unionOverDateLine2() { LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .include(new LatLng(10, 170)) - .include(new LatLng(0, 160)) - .build(); + .include(new LatLng(10, 170)) + .include(new LatLng(0, 160)) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(new LatLng(0, 165)) - .include(new LatLng(-10, -160)) - .build(); + .include(new LatLng(0, 165)) + .include(new LatLng(-10, 200)) + .build(); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, - new LatLngBounds.Builder() - .include(new LatLng(10, 160)) - .include(new LatLng(-10, -160)) - .build()); + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, 200)) + .build()); assertEquals(union1, union2); } @@ -492,23 +506,23 @@ public class LatLngBoundsTest { @Test public void unionOverDateLine3() { LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .include(new LatLng(10, -165)) - .include(new LatLng(0, 160)) - .build(); + .include(new LatLng(10, 195)) + .include(new LatLng(0, 160)) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(new LatLng(0, -170)) - .include(new LatLng(-10, -160)) - .build(); + .include(new LatLng(0, 190)) + .include(new LatLng(-10, 200)) + .build(); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, - new LatLngBounds.Builder() - .include(new LatLng(10, 160)) - .include(new LatLng(-10, -160)) - .build()); + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, 200)) + .build()); assertEquals(union1, union2); } @@ -516,23 +530,23 @@ public class LatLngBoundsTest { @Test public void unionOverDateLine4() { LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .include(new LatLng(10, -160)) - .include(new LatLng(0, 160)) - .build(); + .include(new LatLng(10, -160)) + .include(new LatLng(0, -200)) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(new LatLng(0, -170)) - .include(new LatLng(-10, -175)) - .build(); + .include(new LatLng(0, -170)) + .include(new LatLng(-10, -175)) + .build(); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, - new LatLngBounds.Builder() - .include(new LatLng(10, 160)) - .include(new LatLng(-10, -160)) - .build()); + new LatLngBounds.Builder() + .include(new LatLng(10, -200)) + .include(new LatLng(-10, -160)) + .build()); assertEquals(union1, union2); } @@ -540,37 +554,37 @@ public class LatLngBoundsTest { @Test public void unionOverDateLine5() { LatLngBounds latLngBounds1 = new LatLngBounds.Builder() - .include(new LatLng(10, -160)) - .include(new LatLng(0, 160)) - .build(); + .include(new LatLng(10, 200)) + .include(new LatLng(0, 160)) + .build(); LatLngBounds latLngBounds2 = new LatLngBounds.Builder() - .include(new LatLng(0, 170)) - .include(new LatLng(-10, 175)) - .build(); + .include(new LatLng(0, 170)) + .include(new LatLng(-10, 175)) + .build(); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, - new LatLngBounds.Builder() - .include(new LatLng(10, 160)) - .include(new LatLng(-10, -160)) - .build()); + new LatLngBounds.Builder() + .include(new LatLng(10, 160)) + .include(new LatLng(-10, 200)) + .build()); assertEquals(union1, union2); } @Test - public void unionOverDateLineReturnWorldLonSpan() { - LatLngBounds latLngBounds1 = LatLngBounds.from(10, -160, -10, -10); - LatLngBounds latLngBounds2 = LatLngBounds.from(10, 10, -10, 160); + public void unionOverDateLineReturnLongerThanWorldLonSpan() { + LatLngBounds latLngBounds1 = LatLngBounds.from(10, 200, -10, -10); + LatLngBounds latLngBounds2 = LatLngBounds.from(10, 10, -10, -200); LatLngBounds union1 = latLngBounds1.union(latLngBounds2); LatLngBounds union2 = latLngBounds2.union(latLngBounds1); assertEquals(union1, union2); - assertEquals(union1, LatLngBounds.from(10, 180, -10, -180)); + assertEquals(union1, LatLngBounds.from(10, 200, -10, -200)); } @Test @@ -578,8 +592,8 @@ public class LatLngBoundsTest { exception.expect(IllegalArgumentException.class); exception.expectMessage("latitude must be between -90 and 90"); LatLngBounds unionLatLngBounds = - LatLngBounds.from(10, 10, 0, 0) - .union(200, 200, 0, 0); + LatLngBounds.from(10, 10, 0, 0) + .union(200, 200, 0, 0); } @Test @@ -587,8 +601,8 @@ public class LatLngBoundsTest { exception.expect(IllegalArgumentException.class); exception.expectMessage("latitude must be between -90 and 90"); LatLngBounds unionLatLngBounds = - LatLngBounds.from(0, 0, -10, -10) - .union(0, 0, -200, -200); + LatLngBounds.from(0, 0, -10, -10) + .union(0, 0, -200, -200); } @Test @@ -597,28 +611,28 @@ public class LatLngBoundsTest { exception.expectMessage("latNorth cannot be less than latSouth"); LatLngBounds unionLatLngBounds = - LatLngBounds.from(10, 10, 0, 0) - .union(0, 200, 20, 0); + LatLngBounds.from(10, 10, 0, 0) + .union(0, 200, 20, 0); } @Test - public void unionEastWrapCheck() { + public void unionEastDoesNotWrapCheck() { LatLngBounds latLngBounds1 = LatLngBounds.from(10, 10, 0, 0); LatLngBounds latLngBounds2 = LatLngBounds.from(90, 200, 0, 0); - LatLngBounds unionLatLngBounds = LatLngBounds.from(90, -160, 0, 0); + LatLngBounds unionLatLngBounds = LatLngBounds.from(90, 200, 0, 0); assertEquals(latLngBounds1.union(latLngBounds2), unionLatLngBounds); assertEquals(latLngBounds2.union(latLngBounds1), unionLatLngBounds); } @Test - public void unionWestWrapCheck() { + public void unionWestDoesNotWrapCheck() { LatLngBounds latLngBounds1 = LatLngBounds.from(0, 0, -10, -10); LatLngBounds latLngBounds2 = LatLngBounds.from(0, 0, -90, -200); - LatLngBounds unionLatLngBounds = LatLngBounds.from(0, 0, -90, 160); + LatLngBounds unionLatLngBounds = LatLngBounds.from(0, 0, -90, -200); assertEquals(latLngBounds1.union(latLngBounds2), unionLatLngBounds); assertEquals(latLngBounds2.union(latLngBounds1), unionLatLngBounds); @@ -632,9 +646,9 @@ public class LatLngBoundsTest { double maxLon = 21; LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(minLat, minLon)) - .include(new LatLng(maxLat, maxLon)) - .build(); + .include(new LatLng(minLat, minLon)) + .include(new LatLng(maxLat, maxLon)) + .build(); assertEquals("NorthWest should match", latLngBounds.getNorthWest(), new LatLng(maxLat, minLon)); } @@ -647,9 +661,9 @@ public class LatLngBoundsTest { double maxLon = 21; LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(minLat, minLon)) - .include(new LatLng(maxLat, maxLon)) - .build(); + .include(new LatLng(minLat, minLon)) + .include(new LatLng(maxLat, maxLon)) + .build(); assertEquals("SouthWest should match", latLngBounds.getSouthWest(), new LatLng(minLat, minLon)); } @@ -662,9 +676,9 @@ public class LatLngBoundsTest { double maxLon = 21; LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(minLat, minLon)) - .include(new LatLng(maxLat, maxLon)) - .build(); + .include(new LatLng(minLat, minLon)) + .include(new LatLng(maxLat, maxLon)) + .build(); assertEquals("NorthEast should match", latLngBounds.getNorthEast(), new LatLng(maxLat, maxLon)); } @@ -677,9 +691,9 @@ public class LatLngBoundsTest { double maxLon = 21; LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(minLat, minLon)) - .include(new LatLng(maxLat, maxLon)) - .build(); + .include(new LatLng(minLat, minLon)) + .include(new LatLng(maxLat, maxLon)) + .build(); assertEquals("SouthEast should match", latLngBounds.getSouthEast(), new LatLng(minLat, maxLon)); } @@ -687,9 +701,9 @@ public class LatLngBoundsTest { @Test public void testParcelable() { LatLngBounds latLngBounds = new LatLngBounds.Builder() - .include(new LatLng(10, 10)) - .include(new LatLng(9, 8)) - .build(); + .include(new LatLng(10, 10)) + .include(new LatLng(9, 8)) + .build(); Parcelable parcel = MockParcel.obtain(latLngBounds); assertEquals("Parcel should match original object", parcel, latLngBounds); } @@ -697,9 +711,9 @@ public class LatLngBoundsTest { @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); @@ -789,4 +803,11 @@ public class LatLngBoundsTest { 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); + } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt index c48b99964f..1514c362f3 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt @@ -238,7 +238,8 @@ class NativeMapViewTest { fun testLatLngForProjectedMeters() { val expected = LatLng(0.01796630538796444, 0.02694945852363162) val actual = nativeMapView.latLngForProjectedMeters(ProjectedMeters(2000.0, 3000.0)) - assertEquals("Get LatLng for projected meters", expected, actual) + assertEquals("Lat for projected meters", expected.latitude, actual.latitude, DELTA) + assertEquals("Lng for projected meters", expected.longitude, actual.longitude, DELTA) } @Test @@ -306,7 +307,7 @@ class NativeMapViewTest { .bearing(0.0) .build() val actual = nativeMapView.getCameraForLatLngBounds( - LatLngBounds.from(30.0, 12.0, 16.0, 16.0), + LatLngBounds.from(30.0, 16.0, 16.0, 12.0), intArrayOf(0, 0, 0, 0), 0.0, 0.0 diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java index 7aaca370b2..0fdae6fcda 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/geometry/LatLngBoundsTest.java @@ -6,7 +6,6 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxHighlightActivity; - import com.mapbox.mapboxsdk.testapp.utils.TestConstants; import org.junit.Test; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/VisibleRegionTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/VisibleRegionTest.kt index e70005c6d7..72ff293c3e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/VisibleRegionTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/VisibleRegionTest.kt @@ -189,9 +189,12 @@ class VisibleRegionTest : BaseActivityTest() { val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(0f, 0f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), @@ -240,9 +243,12 @@ class VisibleRegionTest : BaseActivityTest() { val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(0f, 0f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), @@ -263,12 +269,16 @@ class VisibleRegionTest : BaseActivityTest() { validateTestSetup() invoke(mapboxMap) { _: UiController, mapboxMap: MapboxMap -> mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 180.0), 8.0)) + val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(0f, 0f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), @@ -292,9 +302,12 @@ class VisibleRegionTest : BaseActivityTest() { val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(0f, 0f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), @@ -318,9 +331,12 @@ class VisibleRegionTest : BaseActivityTest() { val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(0f, 0f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()), + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), 0f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height / 2f) + .also { it.longitude += 360 }, + mapboxMap.getLatLngFromScreenCoords(mapView.width.toFloat(), mapView.height.toFloat()) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height.toFloat()), mapboxMap.getLatLngFromScreenCoords(0f, mapView.height / 2f), @@ -368,7 +384,8 @@ class VisibleRegionTest : BaseActivityTest() { val latLngs = listOf( mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f - d / 2f, mapView.height / 2f), - mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f), + mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f + d / 2f, mapView.height / 2f) + .also { it.longitude += 360 }, mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f - d / 2f), mapboxMap.getLatLngFromScreenCoords(mapView.width / 2f, mapView.height / 2f + d / 2f) ) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java index 5e6e828856..1a9d3d300b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java @@ -5,9 +5,10 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.view.Gravity; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.FrameLayout; - import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -18,7 +19,7 @@ import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.mapboxsdk.testapp.R; /** - * Test activity showcasing restricting user gestures to a bounds around Iceland. + * Test activity showcasing restricting user gestures to a bounds around Iceland, almost worldview and IDL. */ public class LatLngBoundsForCameraActivity extends AppCompatActivity implements OnMapReadyCallback { @@ -27,6 +28,16 @@ public class LatLngBoundsForCameraActivity extends AppCompatActivity implements .include(new LatLng(62.985661, -12.626277)) .build(); + private static final LatLngBounds ALMOST_WORLD_BOUNDS = new LatLngBounds.Builder() + .include(new LatLng(20.0, 170.0)) + .include(new LatLng(-20, -170.0)) + .build(); + + private static final LatLngBounds CROSS_IDL_BOUNDS = new LatLngBounds.Builder() + .include(new LatLng(20.0, 170.0)) + .include(new LatLng(-20, 190.0)) + .build(); + private MapView mapView; private MapboxMap mapboxMap; @@ -35,7 +46,7 @@ public class LatLngBoundsForCameraActivity extends AppCompatActivity implements super.onCreate(savedInstanceState); setContentView(R.layout.activity_restricted_bounds); - mapView = (MapView) findViewById(R.id.mapView); + mapView = findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(this); } @@ -44,18 +55,43 @@ public class LatLngBoundsForCameraActivity extends AppCompatActivity implements public void onMapReady(@NonNull MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; mapboxMap.setStyle(Style.SATELLITE_STREETS); - mapboxMap.setLatLngBoundsForCameraTarget(ICELAND_BOUNDS); mapboxMap.setMinZoomPreference(2); - showBoundsArea(); + mapboxMap.getUiSettings().setFlingVelocityAnimationEnabled(false); showCrosshair(); + setupBounds(ICELAND_BOUNDS); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_bounds, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_action_allmost_world_bounds: + setupBounds(ALMOST_WORLD_BOUNDS); + return true; + case R.id.menu_action_cross_idl: + setupBounds(CROSS_IDL_BOUNDS); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void setupBounds(LatLngBounds bounds) { + mapboxMap.setLatLngBoundsForCameraTarget(bounds); + showBoundsArea(bounds); } - private void showBoundsArea() { + private void showBoundsArea(LatLngBounds bounds) { + mapboxMap.clear(); PolygonOptions boundsArea = new PolygonOptions() - .add(ICELAND_BOUNDS.getNorthWest()) - .add(ICELAND_BOUNDS.getNorthEast()) - .add(ICELAND_BOUNDS.getSouthEast()) - .add(ICELAND_BOUNDS.getSouthWest()); + .add(bounds.getNorthWest()) + .add(bounds.getNorthEast()) + .add(bounds.getSouthEast()) + .add(bounds.getSouthWest()); boundsArea.alpha(0.25f); boundsArea.fillColor(Color.RED); mapboxMap.addPolygon(boundsArea); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_bounds.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_bounds.xml new file mode 100644 index 0000000000..db7aad6d1f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_bounds.xml @@ -0,0 +1,12 @@ + +

+ + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/actions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/actions.xml index e3cdc06dc1..7513baaa36 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/actions.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/actions.xml @@ -88,4 +88,6 @@ Zoom by 2 Zoom to point Zoom to 4 + Restrict almost worldview + Restrict across IDL \ No newline at end of file diff --git a/platform/android/src/geometry/lat_lng_bounds.cpp b/platform/android/src/geometry/lat_lng_bounds.cpp index d76ff5b365..cf534a06e4 100644 --- a/platform/android/src/geometry/lat_lng_bounds.cpp +++ b/platform/android/src/geometry/lat_lng_bounds.cpp @@ -19,8 +19,6 @@ mbgl::LatLngBounds LatLngBounds::getLatLngBounds(jni::JNIEnv& env, const jni::Ob mbgl::LatLng sw = { bounds.Get(env, swLatField), bounds.Get(env, swLonField) }; mbgl::LatLng ne = { bounds.Get(env, neLatField), bounds.Get(env, neLonField) }; - sw.unwrapForShortestPath(ne); - return mbgl::LatLngBounds::hull(sw, ne); } -- cgit v1.2.1