summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-12-11 12:39:43 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-16 14:52:29 -0800
commit13d5b18ebaeb330f05c4abfc04e0247222e038ba (patch)
tree90e24f1fb745581767b6979d1c562e60859cbcf6 /platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry
parent0db9f229f2bb14e2c6ccd3a8c0d0a30eb25ea5c5 (diff)
downloadqtlocation-mapboxgl-13d5b18ebaeb330f05c4abfc04e0247222e038ba.tar.gz
[android] Move into platform subdirectory
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java304
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java58
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java30
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java43
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java187
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java93
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java95
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/package-info.java5
10 files changed, 834 insertions, 0 deletions
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
new file mode 100644
index 0000000000..e778e30aad
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java
@@ -0,0 +1,304 @@
+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, Serializable {
+
+ 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();
+ }
+
+ /**
+ * Create a new BoundingBox with no size centered at 0, 0, also known as null island
+ */
+ public BoundingBox() {
+ this(0, 0, 0, 0);
+ }
+
+ /**
+ * 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/CoordinateBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
new file mode 100644
index 0000000000..1ad584f8c8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateBounds.java
@@ -0,0 +1,58 @@
+package com.mapbox.mapboxsdk.geometry;
+
+/**
+ * Implementation of iOS MGLCoordinateBounds
+ */
+public class CoordinateBounds {
+
+ private LatLng southWest;
+ private LatLng northEast;
+
+ public CoordinateBounds(LatLng southWest, LatLng northEast) {
+ this.southWest = southWest;
+ this.northEast = northEast;
+ }
+
+ public LatLng getSouthWest() {
+ return southWest;
+ }
+
+ public void setSouthWest(LatLng southWest) {
+ this.southWest = southWest;
+ }
+
+ public LatLng getNorthEast() {
+ return northEast;
+ }
+
+ public void setNorthEast(LatLng northEast) {
+ this.northEast = northEast;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = southWest.hashCode();
+ result = (int) (temp ^ (temp >>> 32));
+ temp = northEast.hashCode();
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o instanceof CoordinateBounds) {
+ CoordinateBounds other = (CoordinateBounds) o;
+ return getNorthEast().equals(other.getNorthEast())
+ && getSouthWest().equals(other.getSouthWest());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "CoordinateBounds [northEast[" + getNorthEast() + "], southWest[]" + getSouthWest() + "]";
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
new file mode 100644
index 0000000000..a70bb05a41
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateRegion.java
@@ -0,0 +1,30 @@
+package com.mapbox.mapboxsdk.geometry;
+
+/**
+ * Implementation of iOS MKCoordinateRegion
+ */
+public class CoordinateRegion {
+ private LatLng center;
+ private CoordinateSpan span;
+
+ public CoordinateRegion(final LatLng center, final CoordinateSpan span) {
+ this.center = center;
+ this.span = span;
+ }
+
+ public LatLng getCenter() {
+ return center;
+ }
+
+ public void setCenter(final LatLng center) {
+ this.center = center;
+ }
+
+ public CoordinateSpan getSpan() {
+ return span;
+ }
+
+ public void setSpan(final CoordinateSpan span) {
+ this.span = span;
+ }
+}
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/CoordinateSpan.java
new file mode 100644
index 0000000000..79361f725a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/CoordinateSpan.java
@@ -0,0 +1,43 @@
+package com.mapbox.mapboxsdk.geometry;
+
+/**
+ * Implementation of iOS MKCoordinateSpan
+ */
+public class CoordinateSpan {
+
+ private double latitudeSpan;
+ private double longitudeSpan;
+
+ public CoordinateSpan(final double latitudeSpan, final double longitudeSpan) {
+ this.latitudeSpan = latitudeSpan;
+ this.longitudeSpan = longitudeSpan;
+ }
+
+ public double getLatitudeSpan() {
+ return latitudeSpan;
+ }
+
+ public void setLatitudeSpan(final double latitudeSpan) {
+ this.latitudeSpan = latitudeSpan;
+ }
+
+ public double getLongitudeSpan() {
+ return longitudeSpan;
+ }
+
+ public void setLongitudeSpan(final double longitudeSpan) {
+ this.longitudeSpan = longitudeSpan;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o instanceof CoordinateSpan) {
+ CoordinateSpan other = (CoordinateSpan) o;
+ return longitudeSpan == other.getLongitudeSpan()
+ && latitudeSpan == other.getLatitudeSpan();
+ }
+ return false;
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
new file mode 100644
index 0000000000..892d0ad4ae
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
@@ -0,0 +1,12 @@
+package com.mapbox.mapboxsdk.geometry;
+
+/**
+ * A Latitude, Longitude point.
+ */
+public interface ILatLng {
+ double getLatitude();
+
+ double getLongitude();
+
+ double getAltitude();
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
new file mode 100644
index 0000000000..5aa5f607eb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
@@ -0,0 +1,7 @@
+package com.mapbox.mapboxsdk.geometry;
+
+public interface IProjectedMeters {
+ double getNorthing();
+
+ double getEasting();
+}
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
new file mode 100644
index 0000000000..c340b09e05
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -0,0 +1,187 @@
+package com.mapbox.mapboxsdk.geometry;
+
+import android.location.Location;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.mapbox.mapboxsdk.constants.GeoConstants;
+import com.mapbox.mapboxsdk.constants.MathConstants;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * This class is container for a single latitude, longitude pair, with
+ * optional altitude. Latitude and longitude are expressed as decimal degrees
+ * in the WGS84 datum. By default, altitude is 0.0, or sea level.
+ * </p>
+ * <p>
+ * Mapbox GL displays maps in the Mercator Projection and projects geographical
+ * data automatically, so all data enters in the WGS84 datum.
+ * </p>
+ */
+public class LatLng implements ILatLng, Parcelable, Serializable {
+
+ public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
+ public LatLng createFromParcel(Parcel in) {
+ return new LatLng(in);
+ }
+
+ public LatLng[] newArray(int size) {
+ return new LatLng[size];
+ }
+ };
+
+ private double latitude;
+ private double longitude;
+ private double altitude = 0.0;
+
+ /**
+ * Construct a new latitude, longitude point at (0, 0)
+ */
+ public LatLng() {
+ this.latitude = 0.0;
+ this.longitude = 0.0;
+ }
+
+ /**
+ * Construct a new latitude, longitude point given float arguments
+ * @param latitude Latitude in degrees
+ * @param longitude Longitude in degrees
+ */
+ public LatLng(double latitude, double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+
+ /**
+ * Construct a new latitude, longitude, altitude point given float arguments
+ * @param latitude Latitude in degrees
+ * @param longitude Longitude in degress
+ * @param altitude Altitude in meters
+ */
+ public LatLng(double latitude, double longitude, double altitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.altitude = altitude;
+ }
+
+ /**
+ * Transform a Location into a LatLng point
+ * @param location Android Location
+ */
+ public LatLng(Location location) {
+ this(location.getLatitude(), location.getLongitude(), location.getAltitude());
+ }
+
+ /**
+ * Clone an existing latitude longitude point
+ * @param aLatLng LatLng
+ */
+ public LatLng(LatLng aLatLng) {
+ this.latitude = aLatLng.latitude;
+ this.longitude = aLatLng.longitude;
+ this.altitude = aLatLng.altitude;
+ }
+
+ protected LatLng(Parcel in) {
+ latitude = in.readDouble();
+ longitude = in.readDouble();
+ altitude = in.readDouble();
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ @Override
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ @Override
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setAltitude(double altitude) {
+ this.altitude = altitude;
+ }
+
+ @Override
+ public double getAltitude() {
+ return altitude;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ LatLng latLng = (LatLng) o;
+
+ return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0 && Double.compare(latLng.longitude, longitude) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(latitude);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(longitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(altitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "LatLng [longitude=" + longitude + ", latitude=" + latitude + ", altitude=" + altitude + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeDouble(latitude);
+ out.writeDouble(longitude);
+ out.writeDouble(altitude);
+ }
+
+ /**
+ * Calculate distance between two points
+ * @param other Other LatLng to compare to
+ * @return distance in meters
+ */
+ public double distanceTo(LatLng other) {
+
+ final double a1 = MathConstants.DEG2RAD * this.latitude;
+ final double a2 = MathConstants.DEG2RAD * this.longitude;
+ final double b1 = MathConstants.DEG2RAD * other.getLatitude();
+ final double b2 = MathConstants.DEG2RAD * other.getLongitude();
+
+ final double cosa1 = Math.cos(a1);
+ final double cosb1 = Math.cos(b1);
+
+ final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
+ final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
+ final double t3 = Math.sin(a1) * Math.sin(b1);
+ final double tt = Math.acos(t1 + t2 + t3);
+
+ return GeoConstants.RADIUS_EARTH_METERS * tt;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
new file mode 100644
index 0000000000..9e453a391c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java
@@ -0,0 +1,93 @@
+package com.mapbox.mapboxsdk.geometry;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.Serializable;
+
+public class LatLngZoom extends LatLng implements Parcelable, Serializable {
+
+ public static final Parcelable.Creator<LatLngZoom> CREATOR = new Parcelable.Creator<LatLngZoom>() {
+ public LatLngZoom createFromParcel(Parcel in) {
+ return new LatLngZoom(in);
+ }
+
+ public LatLngZoom[] newArray(int size) {
+ return new LatLngZoom[size];
+ }
+ };
+
+ private double zoom;
+
+ public LatLngZoom() {
+ super();
+ this.zoom = 0.0;
+ }
+
+ public LatLngZoom(double latitude, double longitude, double zoom) {
+ super(latitude, longitude);
+ this.zoom = zoom;
+ }
+
+ public LatLngZoom(LatLng latLng, double zoom) {
+ super(latLng.getLatitude(), latLng.getLongitude());
+ this.zoom = zoom;
+ }
+
+ private LatLngZoom(Parcel in) {
+ super(in);
+ zoom = in.readDouble();
+ }
+
+ public double getZoom() {
+ return zoom;
+ }
+
+ public void setZoom(double zoom) {
+ this.zoom = zoom;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ LatLngZoom that = (LatLngZoom) o;
+
+ return Double.compare(that.zoom, zoom) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(zoom);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "LatLngZoom [latitude=" + super.getLatitude() + ", longitude=" + super.getLongitude() + ", altitude=" + super.getAltitude() + ", zoom=" + zoom + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeDouble(zoom);
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
new file mode 100644
index 0000000000..fc821e887c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
@@ -0,0 +1,95 @@
+package com.mapbox.mapboxsdk.geometry;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.Serializable;
+
+/**
+ * ProjectedMeters is an internal representation of longitude, latitude points that
+ * have been projected into Mapbox GL's Mercator projection. Instead of decimal
+ * degrees, it uses Mercator meters (which are notably not equivalent to SI meters)
+ * except at the equator.
+ */
+public class ProjectedMeters implements IProjectedMeters, Parcelable, Serializable {
+
+ public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
+ public ProjectedMeters createFromParcel(Parcel in) {
+ return new ProjectedMeters(in);
+ }
+
+ public ProjectedMeters[] newArray(int size) {
+ return new ProjectedMeters[size];
+ }
+ };
+
+ private double northing;
+ private double easting;
+
+ public ProjectedMeters(double northing, double easting) {
+ this.northing = northing;
+ this.easting = easting;
+ }
+
+ public ProjectedMeters(ProjectedMeters aProjectedMeters) {
+ this.northing = aProjectedMeters.northing;
+ this.easting = aProjectedMeters.easting;
+ }
+
+ protected ProjectedMeters(Parcel in) {
+ northing = in.readDouble();
+ easting = in.readDouble();
+ }
+
+ @Override
+ public double getNorthing() {
+ return northing;
+ }
+
+ @Override
+ public double getEasting() {
+ return easting;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ProjectedMeters projectedMeters = (ProjectedMeters) o;
+
+ return Double.compare(projectedMeters.easting, easting) == 0 && Double.compare(projectedMeters.northing, northing) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(easting);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(northing);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeDouble(northing);
+ out.writeDouble(easting);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/package-info.java
new file mode 100644
index 0000000000..bf7dae12a8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains classes that deal with geometry and map coordinates. Many SDK functions
+ * accept or return these classes.
+ */
+package com.mapbox.mapboxsdk.geometry;