Methods Summary |
---|
public float | bearingTo(android.location.Location dest)Returns the approximate initial bearing in degrees East of true
North when traveling along the shortest path between this
location and the given location. The shortest path is defined
using the WGS84 ellipsoid. Locations that are (nearly)
antipodal may produce meaningless results.
synchronized (mResults) {
// See if we already have the result
if (mLatitude != mLat1 || mLongitude != mLon1 ||
dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
computeDistanceAndBearing(mLatitude, mLongitude,
dest.mLatitude, dest.mLongitude, mResults);
mLat1 = mLatitude;
mLon1 = mLongitude;
mLat2 = dest.mLatitude;
mLon2 = dest.mLongitude;
mDistance = mResults[0];
mInitialBearing = mResults[1];
}
return mInitialBearing;
}
|
private static void | computeDistanceAndBearing(double lat1, double lon1, double lat2, double lon2, float[] results)
// Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
// using the "Inverse Formula" (section 4)
int MAXITERS = 20;
// Convert lat/long to radians
lat1 *= Math.PI / 180.0;
lat2 *= Math.PI / 180.0;
lon1 *= Math.PI / 180.0;
lon2 *= Math.PI / 180.0;
double a = 6378137.0; // WGS84 major axis
double b = 6356752.3142; // WGS84 semi-major axis
double f = (a - b) / a;
double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);
double L = lon2 - lon1;
double A = 0.0;
double U1 = Math.atan((1.0 - f) * Math.tan(lat1));
double U2 = Math.atan((1.0 - f) * Math.tan(lat2));
double cosU1 = Math.cos(U1);
double cosU2 = Math.cos(U2);
double sinU1 = Math.sin(U1);
double sinU2 = Math.sin(U2);
double cosU1cosU2 = cosU1 * cosU2;
double sinU1sinU2 = sinU1 * sinU2;
double sigma = 0.0;
double deltaSigma = 0.0;
double cosSqAlpha = 0.0;
double cos2SM = 0.0;
double cosSigma = 0.0;
double sinSigma = 0.0;
double cosLambda = 0.0;
double sinLambda = 0.0;
double lambda = L; // initial guess
for (int iter = 0; iter < MAXITERS; iter++) {
double lambdaOrig = lambda;
cosLambda = Math.cos(lambda);
sinLambda = Math.sin(lambda);
double t1 = cosU2 * sinLambda;
double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
double sinSqSigma = t1 * t1 + t2 * t2; // (14)
sinSigma = Math.sqrt(sinSqSigma);
cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)
sigma = Math.atan2(sinSigma, cosSigma); // (16)
double sinAlpha = (sinSigma == 0) ? 0.0 :
cosU1cosU2 * sinLambda / sinSigma; // (17)
cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
cos2SM = (cosSqAlpha == 0) ? 0.0 :
cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)
double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn
A = 1 + (uSquared / 16384.0) * // (3)
(4096.0 + uSquared *
(-768 + uSquared * (320.0 - 175.0 * uSquared)));
double B = (uSquared / 1024.0) * // (4)
(256.0 + uSquared *
(-128.0 + uSquared * (74.0 - 47.0 * uSquared)));
double C = (f / 16.0) *
cosSqAlpha *
(4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)
double cos2SMSq = cos2SM * cos2SM;
deltaSigma = B * sinSigma * // (6)
(cos2SM + (B / 4.0) *
(cosSigma * (-1.0 + 2.0 * cos2SMSq) -
(B / 6.0) * cos2SM *
(-3.0 + 4.0 * sinSigma * sinSigma) *
(-3.0 + 4.0 * cos2SMSq)));
lambda = L +
(1.0 - C) * f * sinAlpha *
(sigma + C * sinSigma *
(cos2SM + C * cosSigma *
(-1.0 + 2.0 * cos2SM * cos2SM))); // (11)
double delta = (lambda - lambdaOrig) / lambda;
if (Math.abs(delta) < 1.0e-12) {
break;
}
}
float distance = (float) (b * A * (sigma - deltaSigma));
results[0] = distance;
if (results.length > 1) {
float initialBearing = (float) Math.atan2(cosU2 * sinLambda,
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
initialBearing *= 180.0 / Math.PI;
results[1] = initialBearing;
if (results.length > 2) {
float finalBearing = (float) Math.atan2(cosU1 * sinLambda,
-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
finalBearing *= 180.0 / Math.PI;
results[2] = finalBearing;
}
}
|
public static java.lang.String | convert(double coordinate, int outputType)Converts a coordinate to a String representation. The outputType
may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
The coordinate must be a valid double between -180.0 and 180.0.
if (coordinate < -180.0 || coordinate > 180.0 ||
Double.isNaN(coordinate)) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
if ((outputType != FORMAT_DEGREES) &&
(outputType != FORMAT_MINUTES) &&
(outputType != FORMAT_SECONDS)) {
throw new IllegalArgumentException("outputType=" + outputType);
}
StringBuilder sb = new StringBuilder();
// Handle negative values
if (coordinate < 0) {
sb.append('-");
coordinate = -coordinate;
}
DecimalFormat df = new DecimalFormat("###.#####");
if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
int degrees = (int) Math.floor(coordinate);
sb.append(degrees);
sb.append(':");
coordinate -= degrees;
coordinate *= 60.0;
if (outputType == FORMAT_SECONDS) {
int minutes = (int) Math.floor(coordinate);
sb.append(minutes);
sb.append(':");
coordinate -= minutes;
coordinate *= 60.0;
}
}
sb.append(df.format(coordinate));
return sb.toString();
|
public static double | convert(java.lang.String coordinate)Converts a String in one of the formats described by
FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a
double.
// IllegalArgumentException if bad syntax
if (coordinate == null) {
throw new NullPointerException("coordinate");
}
boolean negative = false;
if (coordinate.charAt(0) == '-") {
coordinate = coordinate.substring(1);
negative = true;
}
StringTokenizer st = new StringTokenizer(coordinate, ":");
int tokens = st.countTokens();
if (tokens < 1) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
try {
String degrees = st.nextToken();
double val;
if (tokens == 1) {
val = Double.parseDouble(degrees);
return negative ? -val : val;
}
String minutes = st.nextToken();
int deg = Integer.parseInt(degrees);
double min;
double sec = 0.0;
if (st.hasMoreTokens()) {
min = Integer.parseInt(minutes);
String seconds = st.nextToken();
sec = Double.parseDouble(seconds);
} else {
min = Double.parseDouble(minutes);
}
boolean isNegative180 = negative && (deg == 180) &&
(min == 0) && (sec == 0);
// deg must be in [0, 179] except for the case of -180 degrees
if ((deg < 0.0) || (deg > 179 && !isNegative180)) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
if (min < 0 || min > 59) {
throw new IllegalArgumentException("coordinate=" +
coordinate);
}
if (sec < 0 || sec > 59) {
throw new IllegalArgumentException("coordinate=" +
coordinate);
}
val = deg*3600.0 + min*60.0 + sec;
val /= 3600.0;
return negative ? -val : val;
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
|
public int | describeContents()
return 0;
|
public static void | distanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)Computes the approximate distance in meters between two
locations, and optionally the initial and final bearings of the
shortest path between them. Distance and bearing are defined using the
WGS84 ellipsoid.
The computed distance is stored in results[0]. If results has length
2 or greater, the initial bearing is stored in results[1]. If results has
length 3 or greater, the final bearing is stored in results[2].
if (results == null || results.length < 1) {
throw new IllegalArgumentException("results is null or has length < 1");
}
computeDistanceAndBearing(startLatitude, startLongitude,
endLatitude, endLongitude, results);
|
public float | distanceTo(android.location.Location dest)Returns the approximate distance in meters between this
location and the given location. Distance is defined using
the WGS84 ellipsoid.
// See if we already have the result
synchronized (mResults) {
if (mLatitude != mLat1 || mLongitude != mLon1 ||
dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
computeDistanceAndBearing(mLatitude, mLongitude,
dest.mLatitude, dest.mLongitude, mResults);
mLat1 = mLatitude;
mLon1 = mLongitude;
mLat2 = dest.mLatitude;
mLon2 = dest.mLongitude;
mDistance = mResults[0];
mInitialBearing = mResults[1];
}
return mDistance;
}
|
public void | dump(android.util.Printer pw, java.lang.String prefix)
pw.println(prefix + toString());
|
public float | getAccuracy()Get the estimated accuracy of this location, in meters.
We define accuracy as the radius of 68% confidence. In other
words, if you draw a circle centered at this location's
latitude and longitude, and with a radius equal to the accuracy,
then there is a 68% probability that the true location is inside
the circle.
In statistical terms, it is assumed that location errors
are random with a normal distribution, so the 68% confidence circle
represents one standard deviation. Note that in practice, location
errors do not always follow such a simple distribution.
This accuracy estimation is only concerned with horizontal
accuracy, and does not indicate the accuracy of bearing,
velocity or altitude if those are included in this Location.
If this location does not have an accuracy, then 0.0 is returned.
All locations generated by the {@link LocationManager} include
an accuracy.
return mAccuracy;
|
public double | getAltitude()Get the altitude if available, in meters above the WGS 84 reference
ellipsoid.
If this location does not have an altitude then 0.0 is returned.
return mAltitude;
|
public float | getBearing()Get the bearing, in degrees.
Bearing is the horizontal direction of travel of this device,
and is not related to the device orientation. It is guaranteed to
be in the range (0.0, 360.0] if the device has a bearing.
If this location does not have a bearing then 0.0 is returned.
return mBearing;
|
public long | getElapsedRealtimeNanos()Return the time of this fix, in elapsed real-time since system boot.
This value can be reliably compared to
{@link android.os.SystemClock#elapsedRealtimeNanos},
to calculate the age of a fix and to compare Location fixes. This
is reliable because elapsed real-time is guaranteed monotonic for
each system boot and continues to increment even when the system
is in deep sleep (unlike {@link #getTime}.
All locations generated by the {@link LocationManager}
are guaranteed to have a valid elapsed real-time.
return mElapsedRealtimeNanos;
|
public android.location.Location | getExtraLocation(java.lang.String key)Returns one of the optional extra {@link Location}s that can be attached
to this Location.
if (mExtras != null) {
Parcelable value = mExtras.getParcelable(key);
if (value instanceof Location) {
return (Location) value;
}
}
return null;
|
public android.os.Bundle | getExtras()Returns additional provider-specific information about the
location fix as a Bundle. The keys and values are determined
by the provider. If no additional information is available,
null is returned.
A number of common key/value pairs are listed
below. Providers that use any of the keys on this list must
provide the corresponding value as described below.
- satellites - the number of satellites used to derive the fix
return mExtras;
|
public double | getLatitude()Get the latitude, in degrees.
All locations generated by the {@link LocationManager}
will have a valid latitude.
return mLatitude;
|
public double | getLongitude()Get the longitude, in degrees.
All locations generated by the {@link LocationManager}
will have a valid longitude.
return mLongitude;
|
public java.lang.String | getProvider()Returns the name of the provider that generated this fix.
return mProvider;
|
public float | getSpeed()Get the speed if it is available, in meters/second over ground.
If this location does not have a speed then 0.0 is returned.
return mSpeed;
|
public long | getTime()Return the UTC time of this fix, in milliseconds since January 1, 1970.
Note that the UTC time on a device is not monotonic: it
can jump forwards or backwards unpredictably. So always use
{@link #getElapsedRealtimeNanos} when calculating time deltas.
On the other hand, {@link #getTime} is useful for presenting
a human readable time to the user, or for carefully comparing
location fixes across reboot or across devices.
All locations generated by the {@link LocationManager}
are guaranteed to have a valid UTC time, however remember that
the system time may have changed since the location was generated.
return mTime;
|
public boolean | hasAccuracy()True if this location has an accuracy.
All locations generated by the {@link LocationManager} have an
accuracy.
return mHasAccuracy;
|
public boolean | hasAltitude()True if this location has an altitude.
return mHasAltitude;
|
public boolean | hasBearing()True if this location has a bearing.
return mHasBearing;
|
public boolean | hasSpeed()True if this location has a speed.
return mHasSpeed;
|
public boolean | isComplete()Return true if this Location object is complete.
A location object is currently considered complete if it has
a valid provider, accuracy, wall-clock time and elapsed real-time.
All locations supplied by the {@link LocationManager} to
applications must be complete.
if (mProvider == null) return false;
if (!mHasAccuracy) return false;
if (mTime == 0) return false;
if (mElapsedRealtimeNanos == 0) return false;
return true;
|
public boolean | isFromMockProvider()Returns true if the Location came from a mock provider.
return mIsFromMockProvider;
|
public void | makeComplete()Helper to fill incomplete fields.
Used to assist in backwards compatibility with
Location objects received from applications.
if (mProvider == null) mProvider = "?";
if (!mHasAccuracy) {
mHasAccuracy = true;
mAccuracy = 100.0f;
}
if (mTime == 0) mTime = System.currentTimeMillis();
if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
|
public void | removeAccuracy()Remove the accuracy from this location.
Following this call {@link #hasAccuracy} will return false, and
{@link #getAccuracy} will return 0.0.
mAccuracy = 0.0f;
mHasAccuracy = false;
|
public void | removeAltitude()Remove the altitude from this location.
Following this call {@link #hasAltitude} will return false,
and {@link #getAltitude} will return 0.0.
mAltitude = 0.0f;
mHasAltitude = false;
|
public void | removeBearing()Remove the bearing from this location.
Following this call {@link #hasBearing} will return false,
and {@link #getBearing} will return 0.0.
mBearing = 0.0f;
mHasBearing = false;
|
public void | removeSpeed()Remove the speed from this location.
Following this call {@link #hasSpeed} will return false,
and {@link #getSpeed} will return 0.0.
mSpeed = 0.0f;
mHasSpeed = false;
|
public void | reset()Clears the contents of the location.
mProvider = null;
mTime = 0;
mElapsedRealtimeNanos = 0;
mLatitude = 0;
mLongitude = 0;
mHasAltitude = false;
mAltitude = 0;
mHasSpeed = false;
mSpeed = 0;
mHasBearing = false;
mBearing = 0;
mHasAccuracy = false;
mAccuracy = 0;
mExtras = null;
mIsFromMockProvider = false;
|
public void | set(android.location.Location l)Sets the contents of the location to the values from the given location.
mProvider = l.mProvider;
mTime = l.mTime;
mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
mLatitude = l.mLatitude;
mLongitude = l.mLongitude;
mHasAltitude = l.mHasAltitude;
mAltitude = l.mAltitude;
mHasSpeed = l.mHasSpeed;
mSpeed = l.mSpeed;
mHasBearing = l.mHasBearing;
mBearing = l.mBearing;
mHasAccuracy = l.mHasAccuracy;
mAccuracy = l.mAccuracy;
mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
mIsFromMockProvider = l.mIsFromMockProvider;
|
public void | setAccuracy(float accuracy)Set the estimated accuracy of this location, meters.
See {@link #getAccuracy} for the definition of accuracy.
Following this call {@link #hasAccuracy} will return true.
mAccuracy = accuracy;
mHasAccuracy = true;
|
public void | setAltitude(double altitude)Set the altitude, in meters above the WGS 84 reference ellipsoid.
Following this call {@link #hasAltitude} will return true.
mAltitude = altitude;
mHasAltitude = true;
|
public void | setBearing(float bearing)Set the bearing, in degrees.
Bearing is the horizontal direction of travel of this device,
and is not related to the device orientation.
The input will be wrapped into the range (0.0, 360.0].
while (bearing < 0.0f) {
bearing += 360.0f;
}
while (bearing >= 360.0f) {
bearing -= 360.0f;
}
mBearing = bearing;
mHasBearing = true;
|
public void | setElapsedRealtimeNanos(long time)Set the time of this fix, in elapsed real-time since system boot.
mElapsedRealtimeNanos = time;
|
public void | setExtraLocation(java.lang.String key, android.location.Location value)Attaches an extra {@link Location} to this Location.
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putParcelable(key, value);
|
public void | setExtras(android.os.Bundle extras)Sets the extra information associated with this fix to the
given Bundle.
mExtras = (extras == null) ? null : new Bundle(extras);
|
public void | setIsFromMockProvider(boolean isFromMockProvider)Flag this Location as having come from a mock provider or not.
mIsFromMockProvider = isFromMockProvider;
|
public void | setLatitude(double latitude)Set the latitude, in degrees.
mLatitude = latitude;
|
public void | setLongitude(double longitude)Set the longitude, in degrees.
mLongitude = longitude;
|
public void | setProvider(java.lang.String provider)Sets the name of the provider that generated this fix.
mProvider = provider;
|
public void | setSpeed(float speed)Set the speed, in meters/second over ground.
Following this call {@link #hasSpeed} will return true.
mSpeed = speed;
mHasSpeed = true;
|
public void | setTime(long time)Set the UTC time of this fix, in milliseconds since January 1,
1970.
mTime = time;
|
public java.lang.String | toString()
StringBuilder s = new StringBuilder();
s.append("Location[");
s.append(mProvider);
s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
if (mHasAccuracy) s.append(String.format(" acc=%.0f", mAccuracy));
else s.append(" acc=???");
if (mTime == 0) {
s.append(" t=?!?");
}
if (mElapsedRealtimeNanos == 0) {
s.append(" et=?!?");
} else {
s.append(" et=");
TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
}
if (mHasAltitude) s.append(" alt=").append(mAltitude);
if (mHasSpeed) s.append(" vel=").append(mSpeed);
if (mHasBearing) s.append(" bear=").append(mBearing);
if (mIsFromMockProvider) s.append(" mock");
if (mExtras != null) {
s.append(" {").append(mExtras).append('}");
}
s.append(']");
return s.toString();
|
public void | writeToParcel(android.os.Parcel parcel, int flags)
parcel.writeString(mProvider);
parcel.writeLong(mTime);
parcel.writeLong(mElapsedRealtimeNanos);
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
parcel.writeInt(mHasAltitude ? 1 : 0);
parcel.writeDouble(mAltitude);
parcel.writeInt(mHasSpeed ? 1 : 0);
parcel.writeFloat(mSpeed);
parcel.writeInt(mHasBearing ? 1 : 0);
parcel.writeFloat(mBearing);
parcel.writeInt(mHasAccuracy ? 1 : 0);
parcel.writeFloat(mAccuracy);
parcel.writeBundle(mExtras);
parcel.writeInt(mIsFromMockProvider? 1 : 0);
|