diff options
author | Tobrun <tobrun@mapbox.com> | 2016-02-03 17:26:09 +0100 |
---|---|---|
committer | Tobrun <tobrun@mapbox.com> | 2016-02-04 12:08:39 +0100 |
commit | aa05cba0df0645b7e65a3cff8724d8adb3b922ce (patch) | |
tree | c2a1daf64efac46e09e4efa5d849bbe01964616a /platform/android/MapboxGLAndroidSDK/src/main/java | |
parent | bc1f4b1fc0d96ecd544047db54d4abbffc45ee19 (diff) | |
download | qtlocation-mapboxgl-aa05cba0df0645b7e65a3cff8724d8adb3b922ce.tar.gz |
[android] #3758 - Projection / Visible Region implementation.
[android] #3758 - add VisibleRegion + unit tests, removed boundingbox, cleanup jni, cleanup test app, renamed CoordinateSpan to LatLng.
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java')
10 files changed, 235 insertions, 375 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java index e936b7bd23..9c79ffcbd9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java @@ -99,7 +99,7 @@ public class InfoWindow { // Calculate default Android x,y coordinate - mCoordinates = mapboxMap.toScreenLocation(position); + mCoordinates = mapboxMap.getProjection().toScreenLocation(position); float x = mCoordinates.x - (view.getMeasuredWidth() / 2) + offsetX; float y = mCoordinates.y - view.getMeasuredHeight() + offsetY; @@ -231,7 +231,7 @@ public class InfoWindow { Marker marker = mBoundMarker.get(); View view = mView.get(); if (mapboxMap != null && marker != null && view != null) { - mCoordinates = mapboxMap.toScreenLocation(marker.getPosition()); + mCoordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); view.setX(mCoordinates.x + mViewWidthOffset); view.setY(mCoordinates.y + mMarkerHeightOffset); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java deleted file mode 100644 index 72a851e1af..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java +++ /dev/null @@ -1,297 +0,0 @@ -package com.mapbox.mapboxsdk.geometry; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.io.Serializable; -import java.util.List; - -/** - * A rectangular geographical area defined in latitude and longitude units. - */ -public final class BoundingBox implements Parcelable { - - private final double mLatNorth; - private final double mLatSouth; - private final double mLonEast; - private final double mLonWest; - - private final boolean mIsValid; - - /** - * Construct a new bounding box based on its corners, given in NESW - * order. - * - * @param northLatitude Northern Latitude - * @param eastLongitude Eastern Longitude - * @param southLatitude Southern Latitude - * @param westLongitude Western Longitude - */ - public BoundingBox(final double northLatitude, final double eastLongitude, final double southLatitude, final double westLongitude) { - this.mLatNorth = northLatitude; - this.mLonEast = eastLongitude; - this.mLatSouth = southLatitude; - this.mLonWest = westLongitude; - this.mIsValid = ((this.mLonWest < this.mLonEast) && (this.mLatNorth > this.mLatSouth)); - } - - /** - * Construct a new bounding box based on its corners, given in NESW order. - * - * @param northEast Coordinate - * @param southWest Coordinate - */ - public BoundingBox(final LatLng northEast, final LatLng southWest) { - this(northEast.getLatitude(), northEast.getLongitude(), southWest.getLatitude(), southWest.getLongitude()); - } - - /** - * Create a bounding box from another bounding box - * - * @param other the other bounding box - */ - public BoundingBox(final BoundingBox other) { - this.mLatNorth = other.getLatNorth(); - this.mLonEast = other.getLonEast(); - this.mLatSouth = other.getLatSouth(); - this.mLonWest = other.getLonWest(); - this.mIsValid = other.isValid(); - } - - /** - * Calculates the centerpoint of this bounding box by simple interpolation and returns - * it as a point. This is a non-geodesic calculation which is not the geographic center. - * - * @return LatLng center of this BoundingBox - */ - public LatLng getCenter() { - return new LatLng((this.mLatNorth + this.mLatSouth) / 2, - (this.mLonEast + this.mLonWest) / 2); - } - - public double getLatNorth() { - return this.mLatNorth; - } - - public double getLatSouth() { - return this.mLatSouth; - } - - public double getLonEast() { - return this.mLonEast; - } - - public double getLonWest() { - return this.mLonWest; - } - - public boolean isValid() { - return this.mIsValid; - } - - /** - * Get the area spanned by this bounding box - * - * @return CoordinateSpan area - */ - public CoordinateSpan getSpan() { - return new CoordinateSpan(getLatitudeSpan(), getLongitudeSpan()); - } - - /** - * Get the absolute distance, in degrees, between the north and - * south boundaries of this bounding box - * - * @return Span distance - */ - public double getLatitudeSpan() { - return Math.abs(this.mLatNorth - this.mLatSouth); - } - - /** - * Get the absolute distance, in degrees, between the west and - * east boundaries of this bounding box - * - * @return Span distance - */ - public double getLongitudeSpan() { - return Math.abs(this.mLonEast - this.mLonWest); - } - - - /** - * Validate if bounding box is empty, determined if absolute distance is - * - * @return boolean indicating if span is empty - */ - public boolean isEmpty() { - return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0; - } - - @Override - public String toString() { - return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest; - } - - /** - * Constructs a bounding box that contains all of a list of LatLng - * objects. Empty lists will yield invalid bounding boxes. - * - * @param latLngs List of LatLng objects - * @return BoundingBox - */ - public static BoundingBox fromLatLngs(final List<? extends ILatLng> latLngs) { - double minLat = 90, - minLon = 180, - maxLat = -90, - maxLon = -180; - - for (final ILatLng gp : latLngs) { - final double latitude = gp.getLatitude(); - final double longitude = gp.getLongitude(); - - minLat = Math.min(minLat, latitude); - minLon = Math.min(minLon, longitude); - maxLat = Math.max(maxLat, latitude); - maxLon = Math.max(maxLon, longitude); - } - - return new BoundingBox(maxLat, maxLon, minLat, minLon); - } - - /** - * Determines whether this bounding box matches another one via coordinates. - * - * @param o another object - * @return a boolean indicating whether the bounding boxes are equal - */ - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o instanceof BoundingBox) { - BoundingBox other = (BoundingBox) o; - return mLatNorth == other.getLatNorth() - && mLatSouth == other.getLatSouth() - && mLonEast == other.getLonEast() - && mLonWest == other.getLonWest(); - } - return false; - } - - /** - * Determines whether this bounding box contains a point and the point - * does not touch its boundary. - * - * @param pGeoPoint the point which may be contained - * @return true, if the point is contained within the box. - */ - public boolean contains(final ILatLng pGeoPoint) { - final double latitude = pGeoPoint.getLatitude(); - final double longitude = pGeoPoint.getLongitude(); - return ((latitude < this.mLatNorth) - && (latitude > this.mLatSouth)) - && ((longitude < this.mLonEast) - && (longitude > this.mLonWest)); - } - - /** - * Returns a new BoundingBox that stretches to contain both this and another BoundingBox. - * - * @param box BoundingBox to add - * @return BoundingBox - */ - public BoundingBox union(BoundingBox box) { - return union(box.getLatNorth(), box.getLonEast(), box.getLatSouth(), box.getLonWest()); - } - - /** - * Returns a new BoundingBox that stretches to include another bounding box, - * given by corner points. - * - * @param lonNorth Northern Longitude - * @param latEast Eastern Latitude - * @param lonSouth Southern Longitude - * @param latWest Western Longitude - * @return BoundingBox - */ - public BoundingBox union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) { - return new BoundingBox((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth, - (this.mLonEast < latEast) ? latEast : this.mLonEast, - (this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth, - (this.mLonWest > latWest) ? latWest : this.mLonWest); - } - - /** - * Returns a new BoundingBox that is the intersection of this with another box - * - * @param box BoundingBox to intersect with - * @return BoundingBox - */ - public BoundingBox intersect(BoundingBox 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 BoundingBox(maxLonNorth, maxLatEast, minLonSouth, minLatWest); - } - } - return null; - } - - /** - * Returns a new BoundingBox that is the intersection of this with another box - * - * @param northLongitude Northern Longitude - * @param eastLatitude Eastern Latitude - * @param southLongitude Southern Longitude - * @param westLatitude Western Latitude - * @return BoundingBox - */ - public BoundingBox intersect(double northLongitude, double eastLatitude, double southLongitude, double westLatitude) { - return intersect(new BoundingBox(northLongitude, eastLatitude, southLongitude, westLatitude)); - } - - public static final Parcelable.Creator<BoundingBox> CREATOR = - new Parcelable.Creator<BoundingBox>() { - @Override - public BoundingBox createFromParcel(final Parcel in) { - return readFromParcel(in); - } - - @Override - public BoundingBox[] newArray(final int size) { - return new BoundingBox[size]; - } - }; - - @Override - public int hashCode() { - return (int) ((mLatNorth + 90) - + ((mLatSouth + 90) * 1000) - + ((mLonEast + 180) * 1000000) - + ((mLonEast + 180) * 1000000000)); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(final Parcel out, final int arg1) { - out.writeDouble(this.mLatNorth); - out.writeDouble(this.mLonEast); - out.writeDouble(this.mLatSouth); - out.writeDouble(this.mLonWest); - } - - private static BoundingBox readFromParcel(final Parcel in) { - final double lonNorth = in.readDouble(); - final double latEast = in.readDouble(); - final double lonSouth = in.readDouble(); - final double latWest = in.readDouble(); - return new BoundingBox(lonNorth, latEast, lonSouth, latWest); - } -} 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 17816a0776..82258e5b1d 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 @@ -3,10 +3,7 @@ package com.mapbox.mapboxsdk.geometry; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import com.mapbox.mapboxsdk.annotations.Icon; -import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import java.util.ArrayList; @@ -68,10 +65,10 @@ public class LatLngBounds implements Parcelable { /** * Get the area spanned by this LatLngBounds * - * @return CoordinateSpan area + * @return LatLngSpan area */ - public CoordinateSpan getSpan() { - return new CoordinateSpan(getLatitudeSpan(), getLongitudeSpan()); + public LatLngSpan getSpan() { + return new LatLngSpan(getLatitudeSpan(), getLongitudeSpan()); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java index a43757713d..9d4fb163fa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java @@ -7,17 +7,17 @@ import android.support.annotation.NonNull; /** * A geographical span defined by its latitude and longitude span. */ -public class CoordinateSpan implements Parcelable { +public class LatLngSpan implements Parcelable { private double mLatitudeSpan; private double mLongitudeSpan; - public CoordinateSpan(@NonNull Parcel in){ + public LatLngSpan(@NonNull Parcel in){ mLatitudeSpan = in.readDouble(); mLongitudeSpan = in.readDouble(); } - public CoordinateSpan(double latitudeSpan, double longitudeSpan) { + public LatLngSpan(double latitudeSpan, double longitudeSpan) { mLatitudeSpan = latitudeSpan; mLongitudeSpan = longitudeSpan; } @@ -41,24 +41,24 @@ public class CoordinateSpan implements Parcelable { @Override public boolean equals(Object o) { if (this == o) return true; - if (o instanceof CoordinateSpan) { - CoordinateSpan other = (CoordinateSpan) o; + if (o instanceof LatLngSpan) { + LatLngSpan other = (LatLngSpan) o; return mLongitudeSpan == other.getLongitudeSpan() && mLatitudeSpan == other.getLatitudeSpan(); } return false; } - public static final Parcelable.Creator<CoordinateSpan> CREATOR = - new Parcelable.Creator<CoordinateSpan>() { + public static final Parcelable.Creator<LatLngSpan> CREATOR = + new Parcelable.Creator<LatLngSpan>() { @Override - public CoordinateSpan createFromParcel(Parcel in) { - return new CoordinateSpan(in); + public LatLngSpan createFromParcel(Parcel in) { + return new LatLngSpan(in); } @Override - public CoordinateSpan[] newArray(int size) { - return new CoordinateSpan[size]; + public LatLngSpan[] newArray(int size) { + return new LatLngSpan[size]; } }; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java new file mode 100644 index 0000000000..349120d1f3 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java @@ -0,0 +1,120 @@ +package com.mapbox.mapboxsdk.geometry; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Contains the four points defining the four-sided polygon that is visible in a map's camera. + * This polygon can be a trapezoid instead of a rectangle, because a camera can have tilt. + * If the camera is directly over the center of the camera, the shape is rectangular, + * but if the camera is tilted, the shape will appear to be a trapezoid whose + * smallest side is closest to the point of view. + */ +public class VisibleRegion implements Parcelable { + + /** + * LatLng object that defines the far left corner of the camera. + */ + public final LatLng farLeft; + + /** + * LatLng object that defines the far right corner of the camera. + */ + public final LatLng farRight; + + /** + * LatLng object that defines the bottom left corner of the camera. + */ + public final LatLng nearLeft; + + /** + * LatLng object that defines the bottom right corner of the camera. + */ + public final LatLng nearRight; + + /** + * The smallest bounding box that includes the visible region defined in this class. + */ + public final LatLngBounds latLngBounds; + + private VisibleRegion(Parcel in) { + this.farLeft = in.readParcelable(LatLng.class.getClassLoader()); + this.farRight = in.readParcelable(LatLng.class.getClassLoader()); + this.nearLeft = in.readParcelable(LatLng.class.getClassLoader()); + this.nearRight = in.readParcelable(LatLng.class.getClassLoader()); + this.latLngBounds = in.readParcelable(LatLngBounds.class.getClassLoader()); + } + + /** + * Creates a new VisibleRegion given the four corners of the camera. + * + * @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region. + * @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region. + * @param nearLeft A LatLng object containing the latitude and longitude of the near left corner of the region. + * @param nearRight A LatLng object containing the latitude and longitude of the near left corner of the region. + * @param latLngBounds The smallest bounding box that includes the visible region defined in this class. + */ + public VisibleRegion(LatLng farLeft, LatLng farRight, LatLng nearLeft, LatLng nearRight, LatLngBounds latLngBounds) { + this.farLeft = farLeft; + this.farRight = farRight; + this.nearLeft = nearLeft; + this.nearRight = nearRight; + this.latLngBounds = latLngBounds; + } + + /** + * Compares this VisibleRegion to another object. + * If the other object is actually a pointer to this object, + * or if all four corners and the bounds of the two objects are the same, + * this method returns true. Otherwise, this method returns false. + * @param o The Object to compare with. + * @return true if both objects are the same object. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof VisibleRegion)) { + return false; + } + if (o == this) { + return true; + } + + VisibleRegion visibleRegion = (VisibleRegion) o; + return farLeft.equals(visibleRegion.farLeft) + && farRight.equals(visibleRegion.farRight) + && nearLeft.equals(visibleRegion.nearLeft) + && nearRight.equals(visibleRegion.nearRight) + && latLngBounds.equals(visibleRegion.latLngBounds); + } + + @Override + public String toString() { + return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds ["+latLngBounds+"]]"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeParcelable(farLeft, flags); + out.writeParcelable(farRight, flags); + out.writeParcelable(nearLeft, flags); + out.writeParcelable(nearRight, flags); + out.writeParcelable(latLngBounds, flags); + } + + public static final Parcelable.Creator<VisibleRegion> CREATOR + = new Parcelable.Creator<VisibleRegion>() { + public VisibleRegion createFromParcel(Parcel in) { + return new VisibleRegion(in); + } + + public VisibleRegion[] newArray(int size) { + return new VisibleRegion[size]; + } + }; + +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java index 81b4556076..fed6d9dd76 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java @@ -240,7 +240,7 @@ public class CameraUpdateFactory { centerPixel.y = viewportHeight - centerPixel.y; - LatLng center = mapboxMap.fromScreenLocation(centerPixel); + LatLng center = mapboxMap.getProjection().fromScreenLocation(centerPixel); return new CameraPosition.Builder() .target(center) @@ -370,7 +370,7 @@ public class CameraUpdateFactory { } else { return new CameraPosition.Builder(cameraPosition) .zoom(transformZoom(cameraPosition.zoom)) - .target(mapboxMap.fromScreenLocation(new PointF(getX(), getY()))) + .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY()))) .build(); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 38db55ea53..bd0a010900 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -73,8 +73,8 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException; import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; -import com.mapbox.mapboxsdk.geometry.BoundingBox; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.layers.CustomLayer; import com.mapbox.mapboxsdk.utils.ApiAccess; @@ -1254,7 +1254,7 @@ public class MapView extends FrameLayout { return new ArrayList<>(mAnnotations); } - private List<Marker> getMarkersInBounds(@NonNull BoundingBox bbox) { + private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) { if (bbox == null) { Log.w(TAG, "bbox was null, so just returning null"); return null; @@ -1699,15 +1699,13 @@ public class MapView extends FrameLayout { RectF tapRect = new RectF(tapPoint.x - toleranceSides, tapPoint.y + toleranceTop, tapPoint.x + toleranceSides, tapPoint.y - toleranceBottom); - List<LatLng> corners = Arrays.asList( - fromScreenLocation(new PointF(tapRect.left, tapRect.bottom)), - fromScreenLocation(new PointF(tapRect.left, tapRect.top)), - fromScreenLocation(new PointF(tapRect.right, tapRect.top)), - fromScreenLocation(new PointF(tapRect.right, tapRect.bottom)) - ); + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + builder.include(fromScreenLocation(new PointF(tapRect.left, tapRect.bottom))); + builder.include(fromScreenLocation(new PointF(tapRect.left, tapRect.top))); + builder.include(fromScreenLocation(new PointF(tapRect.right, tapRect.top))); + builder.include(fromScreenLocation(new PointF(tapRect.right, tapRect.bottom))); - BoundingBox tapBounds = BoundingBox.fromLatLngs(corners); - List<Marker> nearbyMarkers = getMarkersInBounds(tapBounds); + List<Marker> nearbyMarkers = getMarkersInBounds(builder.build()); long newSelectedMarkerId = -1; if (nearbyMarkers != null && nearbyMarkers.size() > 0) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index deebfbac63..757a9bc3d9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.maps; import android.Manifest; import android.content.Context; -import android.graphics.PointF; + import android.location.Location; import android.os.Bundle; import android.support.annotation.FloatRange; @@ -39,6 +39,7 @@ public class MapboxMap { private MapView mMapView; private UiSettings mUiSettings; + private Projection mProjection; private CameraPosition mCameraPosition; private boolean mInvalidCameraPosition; private String mStyleUrl; @@ -63,6 +64,7 @@ public class MapboxMap { mMapView = mapView; mMapView.addOnMapChangedListener(new MapChangeCameraPositionListener()); mUiSettings = new UiSettings(mapView); + mProjection = new Projection(mapView); mSelectedMarkers = new ArrayList<>(); mInfoWindows = new ArrayList<>(); } @@ -81,6 +83,17 @@ public class MapboxMap { } // + // Projection + // + + /** + * Get the Projection object that you can use to convert between screen coordinates and latitude/longitude coordinates. + */ + public Projection getProjection() { + return mProjection; + } + + // // Camera API // @@ -439,49 +452,6 @@ public class MapboxMap { } // - // Projection - // - - /** - * Converts a point in this view's coordinate system to a map coordinate. - * - * @param point A point in this view's coordinate system. - * @return The converted map coordinate. - */ - @UiThread - @NonNull - public LatLng fromScreenLocation(@NonNull PointF point) { - return mMapView.fromScreenLocation(point); - } - - /** - * Converts a map coordinate to a point in this view's coordinate system. - * - * @param location A map coordinate. - * @return The converted point in this view's coordinate system. - */ - @UiThread - @NonNull - public PointF toScreenLocation(@NonNull LatLng location) { - return mMapView.toScreenLocation(location); - } - - /** - * <p> - * Returns the distance spanned by one pixel at the specified latitude and current zoom level. - * </p> - * The distance between pixels decreases as the latitude approaches the poles. - * This relationship parallels the relationship between longitudinal coordinates at different latitudes. - * - * @param latitude The latitude for which to return the value. - * @return The distance measured in meters. - */ - @UiThread - public double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) double latitude) { - return mMapView.getMetersPerPixelAtLatitude(latitude); - } - - // // Annotations // 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 1c44e62627..6c388d9d8a 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 @@ -10,8 +10,8 @@ import android.view.Surface; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.Polyline; -import com.mapbox.mapboxsdk.geometry.BoundingBox; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.geometry.ProjectedMeters; import com.mapbox.mapboxsdk.layers.CustomLayer; @@ -403,7 +403,7 @@ final class NativeMapView { nativeRemoveAnnotations(mNativeMapViewPtr, ids); } - public long[] getAnnotationsInBounds(BoundingBox bbox) { + public long[] getAnnotationsInBounds(LatLngBounds bbox) { return nativeGetAnnotationsInBounds(mNativeMapViewPtr, bbox); } @@ -633,7 +633,7 @@ final class NativeMapView { private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id); - private native long[] nativeGetAnnotationsInBounds(long mNativeMapViewPtr, BoundingBox bbox); + private native long[] nativeGetAnnotationsInBounds(long mNativeMapViewPtr, LatLngBounds bbox); private native void nativeAddAnnotationIcon(long nativeMapViewPtr, String symbol, int width, int height, float scale, byte[] pixels); 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 new file mode 100644 index 0000000000..e53d430b69 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -0,0 +1,72 @@ +package com.mapbox.mapboxsdk.maps; + +import android.graphics.PointF; +import android.support.annotation.NonNull; + +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.geometry.VisibleRegion; + +/** + * A projection is used to translate between on screen location and geographic coordinates on + * the surface of the Earth (LatLng). Screen location is in screen pixels (not display pixels) + * with respect to the top left corner of the map (and not necessarily of the whole screen). + */ +public class Projection { + + private MapView mMapView; + + Projection(@NonNull MapView mapView) { + this.mMapView = mapView; + } + + /** + * Returns the geographic location that corresponds to a screen location. + * The screen location is specified in screen pixels (not display pixels) relative to the + * top left of the map (not the top left of the whole screen). + * + * @param point A Point on the screen in screen pixels. + * @return The LatLng corresponding to the point on the screen, or null if the ray through + * the given screen point does not intersect the ground plane. + */ + public LatLng fromScreenLocation(PointF point) { + return mMapView.fromScreenLocation(point); + } + + /** + * Gets a projection of the viewing frustum for converting between screen coordinates and + * geo-latitude/longitude coordinates. + * + * @return The projection of the viewing frustum in its current state. + */ + public VisibleRegion getVisibleRegion() { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + int viewportWidth = mMapView.getWidth(); + int viewportHeight = mMapView.getHeight(); + + LatLng topLeft = fromScreenLocation(new PointF(0, 0)); + LatLng topRight = fromScreenLocation(new PointF(viewportWidth, 0)); + LatLng bottomRight = fromScreenLocation(new PointF(viewportWidth, viewportHeight)); + LatLng bottomLeft = fromScreenLocation(new PointF(0, viewportHeight)); + + builder.include(topLeft) + .include(topRight) + .include(bottomRight) + .include(bottomLeft); + + return new VisibleRegion(topLeft,topRight,bottomLeft,bottomRight,builder.build()); + } + + /** + * Returns a screen location that corresponds to a geographical coordinate (LatLng). + * The screen location is in screen pixels (not display pixels) relative to the top left + * of the map (not of the whole screen). + * + * @param location A LatLng on the map to convert to a screen location. + * @return A Point representing the screen location in screen pixels. + */ + public PointF toScreenLocation(LatLng location) { + return mMapView.toScreenLocation(location); + } +} |