diff options
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 | 104 |
1 files changed, 80 insertions, 24 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 4fcb91033c..cf647224ae 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 @@ -2,11 +2,12 @@ package com.mapbox.mapboxsdk.geometry; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.FloatRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.mapbox.mapboxsdk.constants.GeometryConstants; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; -import com.mapbox.services.android.telemetry.constants.GeoConstants; import java.util.ArrayList; import java.util.List; @@ -48,8 +49,8 @@ public class LatLngBounds implements Parcelable { */ public static LatLngBounds world() { return new LatLngBounds.Builder() - .include(new LatLng(GeoConstants.MAX_LATITUDE, GeoConstants.MAX_LONGITUDE)) - .include(new LatLng(GeoConstants.MIN_LATITUDE, GeoConstants.MIN_LONGITUDE)) + .include(new LatLng(GeometryConstants.MAX_LATITUDE, GeometryConstants.MAX_LONGITUDE)) + .include(new LatLng(GeometryConstants.MIN_LATITUDE, GeometryConstants.MIN_LONGITUDE)) .build(); } @@ -194,10 +195,10 @@ public class LatLngBounds implements Parcelable { * @return LatLngBounds */ static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) { - double minLat = 90; - double minLon = 180; - double maxLat = -90; - double maxLon = -180; + double minLat = GeometryConstants.MAX_LATITUDE; + double minLon = GeometryConstants.MAX_LONGITUDE; + double maxLat = GeometryConstants.MIN_LATITUDE; + double maxLon = GeometryConstants.MIN_LONGITUDE; for (final ILatLng gp : latLngs) { final double latitude = gp.getLatitude(); @@ -223,14 +224,69 @@ public class LatLngBounds implements Parcelable { /** * Constructs a LatLngBounds from doubles representing a LatLng pair. + * + * This values of latNorth and latSouth should be in the range of [-90, 90], + * see {@link GeometryConstants#MIN_LATITUDE} and {@link GeometryConstants#MAX_LATITUDE}, + * otherwise IllegalArgumentException will be thrown. * <p> * 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], + * see {@link GeometryConstants#MIN_LONGITUDE} and {@link GeometryConstants#MAX_LONGITUDE} * </p> */ - public static LatLngBounds from(double latNorth, double lonEast, double latSouth, double lonWest) { + 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) { + + if (Double.isNaN(latNorth) || Double.isNaN(latSouth)) { + throw new IllegalArgumentException("latitude must not be NaN"); + } + + if (Double.isNaN(lonEast) || Double.isNaN(lonWest)) { + 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) { + throw new IllegalArgumentException("latitude must be between -90 and 90"); + } + + 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 double lat_(int z, int y) { + double n = Math.PI - 2.0 * Math.PI * y / Math.pow(2.0, z); + return Math.toDegrees(Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); + } + + private static double lon_(int z, int x) { + return x / Math.pow(2.0, z) * 360.0 - GeometryConstants.MAX_LONGITUDE; + } + + /** + * Constructs a LatLngBounds from a Tile identifier. + * + * Returned bounds will have latitude in the range of Mercator projection. + * @see GeometryConstants#MIN_MERCATOR_LATITUDE + * @see GeometryConstants#MAX_MERCATOR_LATITUDE + * + * @param z Tile zoom level. + * @param x Tile X coordinate. + * @param y Tile Y coordinate. + */ + public static LatLngBounds from(int z, int x, int y) { + return new LatLngBounds(lat_(z, y), lon_(z, x + 1), lat_(z, y + 1), lon_(z, x)); + } + /** * Constructs a LatLngBounds from current bounds with an additional latitude-longitude pair. * @@ -305,17 +361,17 @@ public class LatLngBounds implements Parcelable { * Returns a new LatLngBounds that stretches to include another LatLngBounds, * given by corner points. * - * @param lonNorth Northern Longitude - * @param latEast Eastern Latitude - * @param lonSouth Southern Longitude - * @param latWest Western Longitude + * @param latNorth Northern Latitude + * @param lonEast Eastern Longitude + * @param latSouth Southern Latitude + * @param lonWest Western Longitude * @return BoundingBox */ - public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) { - return new LatLngBounds((this.latitudeNorth < lonNorth) ? lonNorth : this.latitudeNorth, - (this.longitudeEast < latEast) ? latEast : this.longitudeEast, - (this.latitudeSouth > lonSouth) ? lonSouth : this.latitudeSouth, - (this.longitudeWest > latWest) ? latWest : this.longitudeWest); + public LatLngBounds union(final double latNorth, final double lonEast, final double latSouth, final double lonWest) { + return new LatLngBounds((this.latitudeNorth < latNorth) ? latNorth : this.latitudeNorth, + (this.longitudeEast < lonEast) ? lonEast : this.longitudeEast, + (this.latitudeSouth > latSouth) ? latSouth : this.latitudeSouth, + (this.longitudeWest > lonWest) ? lonWest : this.longitudeWest); } /** @@ -326,13 +382,13 @@ public class LatLngBounds implements Parcelable { */ @Nullable public LatLngBounds intersect(LatLngBounds box) { - double minLatWest = Math.max(getLonWest(), box.getLonWest()); - double maxLatEast = Math.min(getLonEast(), box.getLonEast()); - if (maxLatEast > minLatWest) { - double minLonSouth = Math.max(getLatSouth(), box.getLatSouth()); - double maxLonNorth = Math.min(getLatNorth(), box.getLatNorth()); - if (maxLonNorth > minLonSouth) { - return new LatLngBounds(maxLonNorth, maxLatEast, minLonSouth, minLatWest); + double minLonWest = Math.max(getLonWest(), box.getLonWest()); + double maxLonEast = Math.min(getLonEast(), box.getLonEast()); + if (maxLonEast > minLonWest) { + double minLatSouth = Math.max(getLatSouth(), box.getLatSouth()); + double maxLatNorth = Math.min(getLatNorth(), box.getLatNorth()); + if (maxLatNorth > minLatSouth) { + return new LatLngBounds(maxLatNorth, maxLonEast, minLatSouth, minLonWest); } } return null; |