19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.location;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19c20b795cf05b48fe5e024c19dab9c7e4b18cd10fDavid Christieimport android.annotation.SystemApi;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
232eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pellyimport android.os.SystemClock;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.util.TimeUtils;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.text.DecimalFormat;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.StringTokenizer;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
314e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * A data class representing a geographic location.
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
334e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * <p>A location can consist of a latitude, longitude, timestamp,
344e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * and other information such as bearing, altitude and velocity.
354e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly *
364e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * <p>All locations generated by the {@link LocationManager} are
374e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * guaranteed to have a valid latitude, longitude, and timestamp
384e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * (both UTC time and elapsed real-time since boot), all other
394e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly * parameters are optional.
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Location implements Parcelable {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constant used to specify formatting of a latitude or longitude
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the form "[+-]DDD.DDDDD where D indicates degrees.
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FORMAT_DEGREES = 0;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constant used to specify formatting of a latitude or longitude
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the form "[+-]DDD:MM.MMMMM" where D indicates degrees and
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * M indicates minutes of arc (1 minute = 1/60th of a degree).
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FORMAT_MINUTES = 1;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constant used to specify formatting of a latitude or longitude
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the form "DDD:MM:SS.SSSSS" where D indicates degrees, M
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * indicates minutes of arc, and S indicates seconds of arc (1
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * minute = 1/60th of a degree, 1 second = 1/3600th of a degree).
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FORMAT_SECONDS = 2;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6309016ab4dd056a16809419d612cb865a14980880Victoria Lease    /**
64779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * Bundle key for a version of the location that has been fed through
65779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * LocationFudger. Allows location providers to flag locations as being
66779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * safe for use with ACCESS_COARSE_LOCATION permission.
67779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     *
6809016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @hide
6909016ab4dd056a16809419d612cb865a14980880Victoria Lease     */
7009016ab4dd056a16809419d612cb865a14980880Victoria Lease    public static final String EXTRA_COARSE_LOCATION = "coarseLocation";
7109016ab4dd056a16809419d612cb865a14980880Victoria Lease
7209016ab4dd056a16809419d612cb865a14980880Victoria Lease    /**
73779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * Bundle key for a version of the location containing no GPS data.
74779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * Allows location providers to flag locations as being safe to
75779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     * feed to LocationFudger.
76779b77455fc51382ecafa210b8a805d2a616da55Victoria Lease     *
7709016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @hide
7809016ab4dd056a16809419d612cb865a14980880Victoria Lease     */
7909016ab4dd056a16809419d612cb865a14980880Victoria Lease    public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
8009016ab4dd056a16809419d612cb865a14980880Victoria Lease
81923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
82923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * Bit mask for mFieldsMask indicating the presence of mAltitude.
83923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
844402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_ALTITUDE_MASK = 1;
85923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
86923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * Bit mask for mFieldsMask indicating the presence of mSpeed.
87923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
884402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_SPEED_MASK = 2;
89923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
90923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * Bit mask for mFieldsMask indicating the presence of mBearing.
91923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
924402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_BEARING_MASK = 4;
93923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
944402af6be9de4782d218170203033618f079551dgomo     * Bit mask for mFieldsMask indicating the presence of mHorizontalAccuracy.
95923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
964402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_HORIZONTAL_ACCURACY_MASK = 8;
97923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
98923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * Bit mask for mFieldsMask indicating location is from a mock provider.
99923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
1004402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_MOCK_PROVIDER_MASK = 16;
1014402af6be9de4782d218170203033618f079551dgomo    /**
1024402af6be9de4782d218170203033618f079551dgomo     * Bit mask for mFieldsMask indicating the presence of mVerticalAccuracy.
1034402af6be9de4782d218170203033618f079551dgomo     */
1044402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_VERTICAL_ACCURACY_MASK = 32;
1054402af6be9de4782d218170203033618f079551dgomo    /**
1064402af6be9de4782d218170203033618f079551dgomo     * Bit mask for mFieldsMask indicating the presence of mSpeedAccuracy.
1074402af6be9de4782d218170203033618f079551dgomo     */
1084402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_SPEED_ACCURACY_MASK = 64;
1094402af6be9de4782d218170203033618f079551dgomo    /**
1104402af6be9de4782d218170203033618f079551dgomo     * Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
1114402af6be9de4782d218170203033618f079551dgomo     */
1124402af6be9de4782d218170203033618f079551dgomo    private static final int HAS_BEARING_ACCURACY_MASK = 128;
113923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie
114923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    // Cached data to make bearing/distance computations more efficient for the case
115923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    // where distanceTo and bearingTo are called in sequence.  Assume this typically happens
116923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    // on the same thread for caching purposes.
117923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    private static ThreadLocal<BearingDistanceCache> sBearingDistanceCache
118923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            = new ThreadLocal<BearingDistanceCache>() {
119923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        @Override
120923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        protected BearingDistanceCache initialValue() {
121923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            return new BearingDistanceCache();
122923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        }
123923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    };
124923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mProvider;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private long mTime = 0;
1274118012da9a22694b3353040a485f8cdc27e2f17Philip Milne    private long mElapsedRealtimeNanos = 0;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private double mLatitude = 0.0;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private double mLongitude = 0.0;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private double mAltitude = 0.0f;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float mSpeed = 0.0f;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float mBearing = 0.0f;
1334402af6be9de4782d218170203033618f079551dgomo    private float mHorizontalAccuracyMeters = 0.0f;
1344402af6be9de4782d218170203033618f079551dgomo    private float mVerticalAccuracyMeters = 0.0f;
1354402af6be9de4782d218170203033618f079551dgomo    private float mSpeedAccuracyMetersPerSecond = 0.0f;
1364402af6be9de4782d218170203033618f079551dgomo    private float mBearingAccuracyDegrees = 0.0f;
1374402af6be9de4782d218170203033618f079551dgomo
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Bundle mExtras = null;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
140923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    // A bitmask of fields present in this object (see HAS_* constants defined above).
141923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    private byte mFieldsMask = 0;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1444e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Construct a new Location with a named provider.
1454e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
1464e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>By default time, latitude and longitude are 0, and the location
1474e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * has no bearing, altitude, speed, accuracy or extras.
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1494e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * @param provider the name of the provider that generated this location
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Location(String provider) {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProvider = provider;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1564e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Construct a new Location object that is copied from an existing one.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Location(Location l) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        set(l);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the contents of the location to the values from the given location.
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void set(Location l) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProvider = l.mProvider;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTime = l.mTime;
1684118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
169923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask = l.mFieldsMask;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLatitude = l.mLatitude;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLongitude = l.mLongitude;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAltitude = l.mAltitude;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSpeed = l.mSpeed;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBearing = l.mBearing;
1754402af6be9de4782d218170203033618f079551dgomo        mHorizontalAccuracyMeters = l.mHorizontalAccuracyMeters;
1764402af6be9de4782d218170203033618f079551dgomo        mVerticalAccuracyMeters = l.mVerticalAccuracyMeters;
1774402af6be9de4782d218170203033618f079551dgomo        mSpeedAccuracyMetersPerSecond = l.mSpeedAccuracyMetersPerSecond;
1784402af6be9de4782d218170203033618f079551dgomo        mBearingAccuracyDegrees = l.mBearingAccuracyDegrees;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Clears the contents of the location.
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reset() {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProvider = null;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTime = 0;
1884118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        mElapsedRealtimeNanos = 0;
189923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask = 0;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLatitude = 0;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLongitude = 0;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAltitude = 0;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSpeed = 0;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBearing = 0;
1954402af6be9de4782d218170203033618f079551dgomo        mHorizontalAccuracyMeters = 0;
1964402af6be9de4782d218170203033618f079551dgomo        mVerticalAccuracyMeters = 0;
1974402af6be9de4782d218170203033618f079551dgomo        mSpeedAccuracyMetersPerSecond = 0;
1984402af6be9de4782d218170203033618f079551dgomo        mBearingAccuracyDegrees = 0;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtras = null;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Converts a coordinate to a String representation. The outputType
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The coordinate must be a valid double between -180.0 and 180.0.
20671f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * This conversion is performed in a method that is dependent on the
20771f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * default locale, and so is not guaranteed to round-trip with
20871f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * {@link #convert(String)}.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if coordinate is less than
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -180.0, greater than 180.0, or is not a number.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if outputType is not one of
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String convert(double coordinate, int outputType) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (coordinate < -180.0 || coordinate > 180.0 ||
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Double.isNaN(coordinate)) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("coordinate=" + coordinate);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((outputType != FORMAT_DEGREES) &&
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (outputType != FORMAT_MINUTES) &&
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (outputType != FORMAT_SECONDS)) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("outputType=" + outputType);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder sb = new StringBuilder();
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Handle negative values
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (coordinate < 0) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append('-');
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            coordinate = -coordinate;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DecimalFormat df = new DecimalFormat("###.#####");
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int degrees = (int) Math.floor(coordinate);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(degrees);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sb.append(':');
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            coordinate -= degrees;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            coordinate *= 60.0;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outputType == FORMAT_SECONDS) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int minutes = (int) Math.floor(coordinate);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(minutes);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(':');
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                coordinate -= minutes;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                coordinate *= 60.0;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sb.append(df.format(coordinate));
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sb.toString();
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Converts a String in one of the formats described by
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a
25671f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * double. This conversion is performed in a locale agnostic
25771f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * method, and so is not guaranteed to round-trip with
25871f0cd45eff088d26309564d6766003bb788a04bSoonil Nagarkar     * {@link #convert(double, int)}.
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws NullPointerException if coordinate is null
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the coordinate is not
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in one of the valid formats.
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static double convert(String coordinate) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // IllegalArgumentException if bad syntax
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (coordinate == null) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException("coordinate");
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean negative = false;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (coordinate.charAt(0) == '-') {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            coordinate = coordinate.substring(1);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            negative = true;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringTokenizer st = new StringTokenizer(coordinate, ":");
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int tokens = st.countTokens();
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tokens < 1) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("coordinate=" + coordinate);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String degrees = st.nextToken();
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double val;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (tokens == 1) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                val = Double.parseDouble(degrees);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return negative ? -val : val;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String minutes = st.nextToken();
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int deg = Integer.parseInt(degrees);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double min;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double sec = 0.0;
2935575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie            boolean secPresent = false;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (st.hasMoreTokens()) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                min = Integer.parseInt(minutes);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String seconds = st.nextToken();
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sec = Double.parseDouble(seconds);
2995575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie                secPresent = true;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                min = Double.parseDouble(minutes);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean isNegative180 = negative && (deg == 180) &&
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (min == 0) && (sec == 0);
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // deg must be in [0, 179] except for the case of -180 degrees
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((deg < 0.0) || (deg > 179 && !isNegative180)) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("coordinate=" + coordinate);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3115575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie
3125575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie            // min must be in [0, 59] if seconds are present, otherwise [0.0, 60.0)
3135575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie            if (min < 0 || min >= 60 || (secPresent && (min > 59))) {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("coordinate=" +
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        coordinate);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3175575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie
3185575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie            // sec must be in [0.0, 60.0)
3195575ddfcc1a1a7873d493ad6bbc522a9652d4ffcDavid Christie            if (sec < 0 || sec >= 60) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("coordinate=" +
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        coordinate);
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            val = deg*3600.0 + min*60.0 + sec;
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            val /= 3600.0;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return negative ? -val : val;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (NumberFormatException nfe) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("coordinate=" + coordinate);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void computeDistanceAndBearing(double lat1, double lon1,
333923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        double lat2, double lon2, BearingDistanceCache results) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // using the "Inverse Formula" (section 4)
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int MAXITERS = 20;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Convert lat/long to radians
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lat1 *= Math.PI / 180.0;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lat2 *= Math.PI / 180.0;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lon1 *= Math.PI / 180.0;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lon2 *= Math.PI / 180.0;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double a = 6378137.0; // WGS84 major axis
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double b = 6356752.3142; // WGS84 semi-major axis
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double f = (a - b) / a;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double L = lon2 - lon1;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double A = 0.0;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double U1 = Math.atan((1.0 - f) * Math.tan(lat1));
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double U2 = Math.atan((1.0 - f) * Math.tan(lat2));
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosU1 = Math.cos(U1);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosU2 = Math.cos(U2);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sinU1 = Math.sin(U1);
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sinU2 = Math.sin(U2);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosU1cosU2 = cosU1 * cosU2;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sinU1sinU2 = sinU1 * sinU2;
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sigma = 0.0;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double deltaSigma = 0.0;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosSqAlpha = 0.0;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cos2SM = 0.0;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosSigma = 0.0;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sinSigma = 0.0;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double cosLambda = 0.0;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double sinLambda = 0.0;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double lambda = L; // initial guess
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int iter = 0; iter < MAXITERS; iter++) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double lambdaOrig = lambda;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cosLambda = Math.cos(lambda);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sinLambda = Math.sin(lambda);
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double t1 = cosU2 * sinLambda;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double sinSqSigma = t1 * t1 + t2 * t2; // (14)
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sinSigma = Math.sqrt(sinSqSigma);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sigma = Math.atan2(sinSigma, cosSigma); // (16)
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double sinAlpha = (sinSigma == 0) ? 0.0 :
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cosU1cosU2 * sinLambda / sinSigma; // (17)
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cos2SM = (cosSqAlpha == 0) ? 0.0 :
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            A = 1 + (uSquared / 16384.0) * // (3)
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (4096.0 + uSquared *
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 (-768 + uSquared * (320.0 - 175.0 * uSquared)));
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double B = (uSquared / 1024.0) * // (4)
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (256.0 + uSquared *
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 (-128.0 + uSquared * (74.0 - 47.0 * uSquared)));
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double C = (f / 16.0) *
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cosSqAlpha *
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double cos2SMSq = cos2SM * cos2SM;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            deltaSigma = B * sinSigma * // (6)
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (cos2SM + (B / 4.0) *
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 (cosSigma * (-1.0 + 2.0 * cos2SMSq) -
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  (B / 6.0) * cos2SM *
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  (-3.0 + 4.0 * sinSigma * sinSigma) *
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  (-3.0 + 4.0 * cos2SMSq)));
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lambda = L +
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (1.0 - C) * f * sinAlpha *
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (sigma + C * sinSigma *
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 (cos2SM + C * cosSigma *
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  (-1.0 + 2.0 * cos2SM * cos2SM))); // (11)
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            double delta = (lambda - lambdaOrig) / lambda;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Math.abs(delta) < 1.0e-12) {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float distance = (float) (b * A * (sigma - deltaSigma));
418923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mDistance = distance;
419923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        float initialBearing = (float) Math.atan2(cosU2 * sinLambda,
420923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
421923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        initialBearing *= 180.0 / Math.PI;
422923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mInitialBearing = initialBearing;
423923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        float finalBearing = (float) Math.atan2(cosU1 * sinLambda,
424923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
425923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        finalBearing *= 180.0 / Math.PI;
426923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mFinalBearing = finalBearing;
427923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mLat1 = lat1;
428923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mLat2 = lat2;
429923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mLon1 = lon1;
430923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results.mLon2 = lon2;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Computes the approximate distance in meters between two
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * locations, and optionally the initial and final bearings of the
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * shortest path between them.  Distance and bearing are defined using the
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * WGS84 ellipsoid.
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p> The computed distance is stored in results[0].  If results has length
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 2 or greater, the initial bearing is stored in results[1]. If results has
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * length 3 or greater, the final bearing is stored in results[2].
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param startLatitude the starting latitude
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param startLongitude the starting longitude
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param endLatitude the ending latitude
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param endLongitude the ending longitude
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param results an array of floats to hold the results
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if results is null or has length < 1
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static void distanceBetween(double startLatitude, double startLongitude,
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        double endLatitude, double endLongitude, float[] results) {
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (results == null || results.length < 1) {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("results is null or has length < 1");
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
456923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        BearingDistanceCache cache = sBearingDistanceCache.get();
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        computeDistanceAndBearing(startLatitude, startLongitude,
458923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                endLatitude, endLongitude, cache);
459923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        results[0] = cache.mDistance;
460923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (results.length > 1) {
461923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            results[1] = cache.mInitialBearing;
462923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            if (results.length > 2) {
463923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                results[2] = cache.mFinalBearing;
464923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            }
465923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        }
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the approximate distance in meters between this
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * location and the given location.  Distance is defined using
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the WGS84 ellipsoid.
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dest the destination location
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the approximate distance in meters
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float distanceTo(Location dest) {
477923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        BearingDistanceCache cache = sBearingDistanceCache.get();
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // See if we already have the result
479923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 ||
480923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) {
481923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            computeDistanceAndBearing(mLatitude, mLongitude,
482923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                dest.mLatitude, dest.mLongitude, cache);
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
484923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return cache.mDistance;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the approximate initial bearing in degrees East of true
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * North when traveling along the shortest path between this
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * location and the given location.  The shortest path is defined
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * using the WGS84 ellipsoid.  Locations that are (nearly)
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * antipodal may produce meaningless results.
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dest the destination location
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the initial bearing in degrees
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float bearingTo(Location dest) {
498923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        BearingDistanceCache cache = sBearingDistanceCache.get();
499923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        // See if we already have the result
500923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 ||
501923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                        dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) {
502923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            computeDistanceAndBearing(mLatitude, mLongitude,
503923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie                dest.mLatitude, dest.mLongitude, cache);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
505923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return cache.mInitialBearing;
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5094e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Returns the name of the provider that generated this fix.
5104e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5114e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * @return the provider, or null if it has not been set
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getProvider() {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mProvider;
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the name of the provider that generated this fix.
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setProvider(String provider) {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProvider = provider;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5254e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Return the UTC time of this fix, in milliseconds since January 1, 1970.
5264e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5272eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * <p>Note that the UTC time on a device is not monotonic: it
5282eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * can jump forwards or backwards unpredictably. So always use
5294118012da9a22694b3353040a485f8cdc27e2f17Philip Milne     * {@link #getElapsedRealtimeNanos} when calculating time deltas.
5304e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5314e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>On the other hand, {@link #getTime} is useful for presenting
5322eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * a human readable time to the user, or for carefully comparing
5332eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * location fixes across reboot or across devices.
5344e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5354e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>All locations generated by the {@link LocationManager}
5364e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * are guaranteed to have a valid UTC time, however remember that
5374e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * the system time may have changed since the location was generated.
5382eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     *
5392eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @return time of fix, in milliseconds since January 1, 1970.
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public long getTime() {
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTime;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5462eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * Set the UTC time of this fix, in milliseconds since January 1,
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 1970.
5482eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     *
5492eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @param time UTC time of this fix, in milliseconds since January 1, 1970
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTime(long time) {
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTime = time;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5562eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * Return the time of this fix, in elapsed real-time since system boot.
5574e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5582eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * <p>This value can be reliably compared to
5594118012da9a22694b3353040a485f8cdc27e2f17Philip Milne     * {@link android.os.SystemClock#elapsedRealtimeNanos},
5604e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * to calculate the age of a fix and to compare Location fixes. This
5614e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * is reliable because elapsed real-time is guaranteed monotonic for
5624e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * each system boot and continues to increment even when the system
5634e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * is in deep sleep (unlike {@link #getTime}.
5644e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5654e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>All locations generated by the {@link LocationManager}
5664e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * are guaranteed to have a valid elapsed real-time.
5672eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     *
5682eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @return elapsed real-time of fix, in nanoseconds since system boot.
5692eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     */
5704118012da9a22694b3353040a485f8cdc27e2f17Philip Milne    public long getElapsedRealtimeNanos() {
5714118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        return mElapsedRealtimeNanos;
5722eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    }
5732eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly
5742eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    /**
5752eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * Set the time of this fix, in elapsed real-time since system boot.
5762eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     *
5772eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @param time elapsed real-time of fix, in nanoseconds since system boot.
5782eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     */
5794118012da9a22694b3353040a485f8cdc27e2f17Philip Milne    public void setElapsedRealtimeNanos(long time) {
5804118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        mElapsedRealtimeNanos = time;
5812eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    }
5822eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly
5832eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    /**
5844e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Get the latitude, in degrees.
5854e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
5864e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>All locations generated by the {@link LocationManager}
5874e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * will have a valid latitude.
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public double getLatitude() {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLatitude;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5944e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Set the latitude, in degrees.
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLatitude(double latitude) {
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLatitude = latitude;
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6014e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Get the longitude, in degrees.
6024e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6034e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>All locations generated by the {@link LocationManager}
6044e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * will have a valid longitude.
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public double getLongitude() {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLongitude;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6114e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Set the longitude, in degrees.
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLongitude(double longitude) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLongitude = longitude;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6184e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * True if this location has an altitude.
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasAltitude() {
621923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return (mFieldsMask & HAS_ALTITUDE_MASK) != 0;
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
625552bd68c2c592348b45fb823b939fb289afb4af7David Christie     * Get the altitude if available, in meters above the WGS 84 reference
626552bd68c2c592348b45fb823b939fb289afb4af7David Christie     * ellipsoid.
6274e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6284e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>If this location does not have an altitude then 0.0 is returned.
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public double getAltitude() {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAltitude;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
635552bd68c2c592348b45fb823b939fb289afb4af7David Christie     * Set the altitude, in meters above the WGS 84 reference ellipsoid.
6364e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6374e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasAltitude} will return true.
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAltitude(double altitude) {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAltitude = altitude;
641923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask |= HAS_ALTITUDE_MASK;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6454e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Remove the altitude from this location.
6464e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6474e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasAltitude} will return false,
6484e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * and {@link #getAltitude} will return 0.0.
649b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
650b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
652b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeAltitude() {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAltitude = 0.0f;
655923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask &= ~HAS_ALTITUDE_MASK;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6594e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * True if this location has a speed.
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasSpeed() {
662923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return (mFieldsMask & HAS_SPEED_MASK) != 0;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6664e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Get the speed if it is available, in meters/second over ground.
6674e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6684e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>If this location does not have a speed then 0.0 is returned.
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float getSpeed() {
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mSpeed;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6754e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Set the speed, in meters/second over ground.
6764e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6774e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasSpeed} will return true.
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSpeed(float speed) {
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSpeed = speed;
681923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask |= HAS_SPEED_MASK;
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6854e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Remove the speed from this location.
6864e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
6874e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasSpeed} will return false,
6884e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * and {@link #getSpeed} will return 0.0.
689b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
690b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
692b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeSpeed() {
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSpeed = 0.0f;
695923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask &= ~HAS_SPEED_MASK;
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6994e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * True if this location has a bearing.
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasBearing() {
702923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return (mFieldsMask & HAS_BEARING_MASK) != 0;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7064e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Get the bearing, in degrees.
7074e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7084e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Bearing is the horizontal direction of travel of this device,
7094e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * and is not related to the device orientation. It is guaranteed to
7104e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * be in the range (0.0, 360.0] if the device has a bearing.
7114e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7124e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>If this location does not have a bearing then 0.0 is returned.
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float getBearing() {
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBearing;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7194e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Set the bearing, in degrees.
7204e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7214e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Bearing is the horizontal direction of travel of this device,
7224e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * and is not related to the device orientation.
7234e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7244e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>The input will be wrapped into the range (0.0, 360.0].
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBearing(float bearing) {
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (bearing < 0.0f) {
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bearing += 360.0f;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (bearing >= 360.0f) {
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bearing -= 360.0f;
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBearing = bearing;
734923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask |= HAS_BEARING_MASK;
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7384e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Remove the bearing from this location.
7394e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7404e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasBearing} will return false,
7414e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * and {@link #getBearing} will return 0.0.
742b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
743b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
745b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeBearing() {
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBearing = 0.0f;
748923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        mFieldsMask &= ~HAS_BEARING_MASK;
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7524402af6be9de4782d218170203033618f079551dgomo     * True if this location has a horizontal accuracy.
7534e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7544402af6be9de4782d218170203033618f079551dgomo     * <p>All locations generated by the {@link LocationManager} have an horizontal accuracy.
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasAccuracy() {
7574402af6be9de4782d218170203033618f079551dgomo        return (mFieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7614402af6be9de4782d218170203033618f079551dgomo     * Get the estimated horizontal accuracy of this location, radial, in meters.
7624e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7634402af6be9de4782d218170203033618f079551dgomo     * <p>We define horizontal accuracy as the radius of 68% confidence. In other
7644e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * words, if you draw a circle centered at this location's
7654e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * latitude and longitude, and with a radius equal to the accuracy,
7664e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * then there is a 68% probability that the true location is inside
7674e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * the circle.
7684e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7694e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>In statistical terms, it is assumed that location errors
7704e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * are random with a normal distribution, so the 68% confidence circle
7714e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * represents one standard deviation. Note that in practice, location
7724e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * errors do not always follow such a simple distribution.
7734e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7744e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>This accuracy estimation is only concerned with horizontal
7754e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * accuracy, and does not indicate the accuracy of bearing,
7764e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * velocity or altitude if those are included in this Location.
7774e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7784402af6be9de4782d218170203033618f079551dgomo     * <p>If this location does not have a horizontal accuracy, then 0.0 is returned.
7794402af6be9de4782d218170203033618f079551dgomo     * All locations generated by the {@link LocationManager} include horizontal accuracy.
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float getAccuracy() {
7824402af6be9de4782d218170203033618f079551dgomo        return mHorizontalAccuracyMeters;
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7864402af6be9de4782d218170203033618f079551dgomo     * Set the estimated horizontal accuracy of this location, meters.
7874e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7884402af6be9de4782d218170203033618f079551dgomo     * <p>See {@link #getAccuracy} for the definition of horizontal accuracy.
7894e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
7904e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasAccuracy} will return true.
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7924402af6be9de4782d218170203033618f079551dgomo    public void setAccuracy(float horizontalAccuracy) {
7934402af6be9de4782d218170203033618f079551dgomo        mHorizontalAccuracyMeters = horizontalAccuracy;
7944402af6be9de4782d218170203033618f079551dgomo        mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7984402af6be9de4782d218170203033618f079551dgomo     * Remove the horizontal accuracy from this location.
7994e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
8004e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Following this call {@link #hasAccuracy} will return false, and
8014e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * {@link #getAccuracy} will return 0.0.
802b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
803b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
805b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeAccuracy() {
8074402af6be9de4782d218170203033618f079551dgomo        mHorizontalAccuracyMeters = 0.0f;
8084402af6be9de4782d218170203033618f079551dgomo        mFieldsMask &= ~HAS_HORIZONTAL_ACCURACY_MASK;
8094402af6be9de4782d218170203033618f079551dgomo    }
8104402af6be9de4782d218170203033618f079551dgomo
8114402af6be9de4782d218170203033618f079551dgomo    /**
8124402af6be9de4782d218170203033618f079551dgomo     * True if this location has a vertical accuracy.
8134402af6be9de4782d218170203033618f079551dgomo     */
8144402af6be9de4782d218170203033618f079551dgomo    public boolean hasVerticalAccuracy() {
8154402af6be9de4782d218170203033618f079551dgomo        return (mFieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0;
8164402af6be9de4782d218170203033618f079551dgomo    }
8174402af6be9de4782d218170203033618f079551dgomo
8184402af6be9de4782d218170203033618f079551dgomo    /**
8194402af6be9de4782d218170203033618f079551dgomo     * Get the estimated vertical accuracy of this location, in meters.
8204402af6be9de4782d218170203033618f079551dgomo     *
8214402af6be9de4782d218170203033618f079551dgomo     * <p>We define vertical accuracy as the radius of 68% confidence. In other
8224402af6be9de4782d218170203033618f079551dgomo     * words, if you draw a circle centered at this location's altitude, and with a radius
8234402af6be9de4782d218170203033618f079551dgomo     * equal to the vertical accuracy, then there is a 68% probability that the true altitude is
8244402af6be9de4782d218170203033618f079551dgomo     * inside the circle.
8254402af6be9de4782d218170203033618f079551dgomo     *
8264402af6be9de4782d218170203033618f079551dgomo     * <p>In statistical terms, it is assumed that location errors
8274402af6be9de4782d218170203033618f079551dgomo     * are random with a normal distribution, so the 68% confidence circle
8284402af6be9de4782d218170203033618f079551dgomo     * represents one standard deviation. Note that in practice, location
8294402af6be9de4782d218170203033618f079551dgomo     * errors do not always follow such a simple distribution.
8304402af6be9de4782d218170203033618f079551dgomo     *
8314402af6be9de4782d218170203033618f079551dgomo     * <p>If this location does not have a vertical accuracy, then 0.0 is returned.
8324402af6be9de4782d218170203033618f079551dgomo     */
8334402af6be9de4782d218170203033618f079551dgomo    public float getVerticalAccuracyMeters() {
8344402af6be9de4782d218170203033618f079551dgomo        return mVerticalAccuracyMeters;
8354402af6be9de4782d218170203033618f079551dgomo    }
8364402af6be9de4782d218170203033618f079551dgomo
8374402af6be9de4782d218170203033618f079551dgomo    /**
8384402af6be9de4782d218170203033618f079551dgomo     * Set the estimated vertical accuracy of this location, meters.
8394402af6be9de4782d218170203033618f079551dgomo     *
8404402af6be9de4782d218170203033618f079551dgomo     * <p>See {@link #getVerticalAccuracyMeters} for the definition of vertical accuracy.
8414402af6be9de4782d218170203033618f079551dgomo     *
8424402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasVerticalAccuracy} will return true.
8434402af6be9de4782d218170203033618f079551dgomo     */
8444402af6be9de4782d218170203033618f079551dgomo    public void setVerticalAccuracyMeters(float verticalAccuracyMeters) {
8454402af6be9de4782d218170203033618f079551dgomo        mVerticalAccuracyMeters = verticalAccuracyMeters;
8464402af6be9de4782d218170203033618f079551dgomo        mFieldsMask |= HAS_VERTICAL_ACCURACY_MASK;
8474402af6be9de4782d218170203033618f079551dgomo    }
8484402af6be9de4782d218170203033618f079551dgomo
8494402af6be9de4782d218170203033618f079551dgomo    /**
8504402af6be9de4782d218170203033618f079551dgomo     * Remove the vertical accuracy from this location.
8514402af6be9de4782d218170203033618f079551dgomo     *
8524402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasVerticalAccuracy} will return false, and
8534402af6be9de4782d218170203033618f079551dgomo     * {@link #getVerticalAccuracyMeters} will return 0.0.
854b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
855b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
856b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @removed
8574402af6be9de4782d218170203033618f079551dgomo     */
858b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
8594402af6be9de4782d218170203033618f079551dgomo    public void removeVerticalAccuracy() {
8604402af6be9de4782d218170203033618f079551dgomo        mVerticalAccuracyMeters = 0.0f;
8614402af6be9de4782d218170203033618f079551dgomo        mFieldsMask &= ~HAS_VERTICAL_ACCURACY_MASK;
8624402af6be9de4782d218170203033618f079551dgomo    }
8634402af6be9de4782d218170203033618f079551dgomo
8644402af6be9de4782d218170203033618f079551dgomo    /**
8654402af6be9de4782d218170203033618f079551dgomo     * True if this location has a speed accuracy.
8664402af6be9de4782d218170203033618f079551dgomo     */
8674402af6be9de4782d218170203033618f079551dgomo    public boolean hasSpeedAccuracy() {
8684402af6be9de4782d218170203033618f079551dgomo        return (mFieldsMask & HAS_SPEED_ACCURACY_MASK) != 0;
8694402af6be9de4782d218170203033618f079551dgomo    }
8704402af6be9de4782d218170203033618f079551dgomo
8714402af6be9de4782d218170203033618f079551dgomo    /**
8724402af6be9de4782d218170203033618f079551dgomo     * Get the estimated speed accuracy of this location, in meters per second.
8734402af6be9de4782d218170203033618f079551dgomo     *
8744402af6be9de4782d218170203033618f079551dgomo     * <p>We define speed accuracy as the radius of 68% confidence. In other
8754402af6be9de4782d218170203033618f079551dgomo     * words, if you draw a circle centered at this location's speed, and with a radius
8764402af6be9de4782d218170203033618f079551dgomo     * equal to the speed accuracy, then there is a 68% probability that the true speed is
8774402af6be9de4782d218170203033618f079551dgomo     * inside the circle.
8784402af6be9de4782d218170203033618f079551dgomo     *
8794402af6be9de4782d218170203033618f079551dgomo     * <p>If this location does not have a speed accuracy, then 0.0 is returned.
8804402af6be9de4782d218170203033618f079551dgomo     */
8814402af6be9de4782d218170203033618f079551dgomo    public float getSpeedAccuracyMetersPerSecond() {
8824402af6be9de4782d218170203033618f079551dgomo        return mSpeedAccuracyMetersPerSecond;
8834402af6be9de4782d218170203033618f079551dgomo    }
8844402af6be9de4782d218170203033618f079551dgomo
8854402af6be9de4782d218170203033618f079551dgomo    /**
8864402af6be9de4782d218170203033618f079551dgomo     * Set the estimated speed accuracy of this location, meters per second.
8874402af6be9de4782d218170203033618f079551dgomo     *
8884402af6be9de4782d218170203033618f079551dgomo     * <p>See {@link #getSpeedAccuracyMetersPerSecond} for the definition of speed accuracy.
8894402af6be9de4782d218170203033618f079551dgomo     *
8904402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasSpeedAccuracy} will return true.
8914402af6be9de4782d218170203033618f079551dgomo     */
8924402af6be9de4782d218170203033618f079551dgomo    public void setSpeedAccuracyMetersPerSecond(float speedAccuracyMeterPerSecond) {
8934402af6be9de4782d218170203033618f079551dgomo        mSpeedAccuracyMetersPerSecond = speedAccuracyMeterPerSecond;
8944402af6be9de4782d218170203033618f079551dgomo        mFieldsMask |= HAS_SPEED_ACCURACY_MASK;
8954402af6be9de4782d218170203033618f079551dgomo    }
8964402af6be9de4782d218170203033618f079551dgomo
8974402af6be9de4782d218170203033618f079551dgomo    /**
8984402af6be9de4782d218170203033618f079551dgomo     * Remove the speed accuracy from this location.
8994402af6be9de4782d218170203033618f079551dgomo     *
9004402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasSpeedAccuracy} will return false, and
9014402af6be9de4782d218170203033618f079551dgomo     * {@link #getSpeedAccuracyMetersPerSecond} will return 0.0.
902b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
903b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
904b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @removed
9054402af6be9de4782d218170203033618f079551dgomo     */
906b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
9074402af6be9de4782d218170203033618f079551dgomo    public void removeSpeedAccuracy() {
9084402af6be9de4782d218170203033618f079551dgomo        mSpeedAccuracyMetersPerSecond = 0.0f;
9094402af6be9de4782d218170203033618f079551dgomo        mFieldsMask &= ~HAS_SPEED_ACCURACY_MASK;
9104402af6be9de4782d218170203033618f079551dgomo    }
9114402af6be9de4782d218170203033618f079551dgomo
9124402af6be9de4782d218170203033618f079551dgomo    /**
9134402af6be9de4782d218170203033618f079551dgomo     * True if this location has a bearing accuracy.
9144402af6be9de4782d218170203033618f079551dgomo     */
9154402af6be9de4782d218170203033618f079551dgomo    public boolean hasBearingAccuracy() {
9164402af6be9de4782d218170203033618f079551dgomo        return (mFieldsMask & HAS_BEARING_ACCURACY_MASK) != 0;
9174402af6be9de4782d218170203033618f079551dgomo    }
9184402af6be9de4782d218170203033618f079551dgomo
9194402af6be9de4782d218170203033618f079551dgomo    /**
9204402af6be9de4782d218170203033618f079551dgomo     * Get the estimated bearing accuracy of this location, in degrees.
9214402af6be9de4782d218170203033618f079551dgomo     *
9224402af6be9de4782d218170203033618f079551dgomo     * <p>We define bearing accuracy as the radius of 68% confidence. In other
9234402af6be9de4782d218170203033618f079551dgomo     * words, if you draw a circle centered at this location's bearing, and with a radius
9244402af6be9de4782d218170203033618f079551dgomo     * equal to the bearing accuracy, then there is a 68% probability that the true bearing is
9254402af6be9de4782d218170203033618f079551dgomo     * inside the circle.
9264402af6be9de4782d218170203033618f079551dgomo     *
9274402af6be9de4782d218170203033618f079551dgomo     * <p>If this location does not have a bearing accuracy, then 0.0 is returned.
9284402af6be9de4782d218170203033618f079551dgomo     */
9294402af6be9de4782d218170203033618f079551dgomo    public float getBearingAccuracyDegrees() {
9304402af6be9de4782d218170203033618f079551dgomo        return mBearingAccuracyDegrees;
9314402af6be9de4782d218170203033618f079551dgomo    }
9324402af6be9de4782d218170203033618f079551dgomo
9334402af6be9de4782d218170203033618f079551dgomo    /**
9344402af6be9de4782d218170203033618f079551dgomo     * Set the estimated bearing accuracy of this location, degrees.
9354402af6be9de4782d218170203033618f079551dgomo     *
9364402af6be9de4782d218170203033618f079551dgomo     * <p>See {@link #getBearingAccuracyDegrees} for the definition of bearing accuracy.
9374402af6be9de4782d218170203033618f079551dgomo     *
9384402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasBearingAccuracy} will return true.
9394402af6be9de4782d218170203033618f079551dgomo     */
9404402af6be9de4782d218170203033618f079551dgomo    public void setBearingAccuracyDegrees(float bearingAccuracyDegrees) {
9414402af6be9de4782d218170203033618f079551dgomo        mBearingAccuracyDegrees = bearingAccuracyDegrees;
9424402af6be9de4782d218170203033618f079551dgomo        mFieldsMask |= HAS_BEARING_ACCURACY_MASK;
9434402af6be9de4782d218170203033618f079551dgomo    }
9444402af6be9de4782d218170203033618f079551dgomo
9454402af6be9de4782d218170203033618f079551dgomo    /**
9464402af6be9de4782d218170203033618f079551dgomo     * Remove the bearing accuracy from this location.
9474402af6be9de4782d218170203033618f079551dgomo     *
9484402af6be9de4782d218170203033618f079551dgomo     * <p>Following this call {@link #hasBearingAccuracy} will return false, and
9494402af6be9de4782d218170203033618f079551dgomo     * {@link #getBearingAccuracyDegrees} will return 0.0.
950b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     *
951b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @deprecated use a new Location object for location updates.
952b87243cb43753c6f90d54afd3bc0839882742942Yu Liu     * @removed
9534402af6be9de4782d218170203033618f079551dgomo     */
954b87243cb43753c6f90d54afd3bc0839882742942Yu Liu    @Deprecated
9554402af6be9de4782d218170203033618f079551dgomo    public void removeBearingAccuracy() {
9564402af6be9de4782d218170203033618f079551dgomo        mBearingAccuracyDegrees = 0.0f;
9574402af6be9de4782d218170203033618f079551dgomo        mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK;
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9614e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Return true if this Location object is complete.
9624e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
9634e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>A location object is currently considered complete if it has
9644e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * a valid provider, accuracy, wall-clock time and elapsed real-time.
9654e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
9664e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>All locations supplied by the {@link LocationManager} to
9674e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * applications must be complete.
9684e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
9692eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @see #makeComplete
9702eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @hide
9712eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     */
972c20b795cf05b48fe5e024c19dab9c7e4b18cd10fDavid Christie    @SystemApi
9732eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    public boolean isComplete() {
9742eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        if (mProvider == null) return false;
975923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (!hasAccuracy()) return false;
9762eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        if (mTime == 0) return false;
9774118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        if (mElapsedRealtimeNanos == 0) return false;
9782eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        return true;
9792eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    }
9802eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly
9812eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    /**
9824e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Helper to fill incomplete fields.
9834e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
9844e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * <p>Used to assist in backwards compatibility with
9854e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     * Location objects received from applications.
9864e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly     *
9872eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @see #isComplete
9882eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     * @hide
9892eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly     */
990c20b795cf05b48fe5e024c19dab9c7e4b18cd10fDavid Christie    @SystemApi
9912eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    public void makeComplete() {
9922eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        if (mProvider == null) mProvider = "?";
993923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (!hasAccuracy()) {
9944402af6be9de4782d218170203033618f079551dgomo            mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
9954402af6be9de4782d218170203033618f079551dgomo            mHorizontalAccuracyMeters = 100.0f;
9962eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        }
9972eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly        if (mTime == 0) mTime = System.currentTimeMillis();
9984118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
9992eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    }
10002eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly
10012eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly    /**
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns additional provider-specific information about the
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * location fix as a Bundle.  The keys and values are determined
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the provider.  If no additional information is available,
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null is returned.
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p> A number of common key/value pairs are listed
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * below. Providers that use any of the keys on this list must
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provide the corresponding value as described below.
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> satellites - the number of satellites used to derive the fix
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </ul>
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bundle getExtras() {
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mExtras;
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the extra information associated with this fix to the
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * given Bundle.
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setExtras(Bundle extras) {
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtras = (extras == null) ? null : new Bundle(extras);
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
10286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public String toString() {
10296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        StringBuilder s = new StringBuilder();
10306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        s.append("Location[");
10316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        s.append(mProvider);
10326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
10334402af6be9de4782d218170203033618f079551dgomo        if (hasAccuracy()) s.append(String.format(" hAcc=%.0f", mHorizontalAccuracyMeters));
10344402af6be9de4782d218170203033618f079551dgomo        else s.append(" hAcc=???");
10356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        if (mTime == 0) {
10366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            s.append(" t=?!?");
10376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        }
10384118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        if (mElapsedRealtimeNanos == 0) {
10396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            s.append(" et=?!?");
10406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        } else {
10415584b497b7fcd8660cc49cfc8ab4dd0c6dad1060Nick Pelly            s.append(" et=");
10424118012da9a22694b3353040a485f8cdc27e2f17Philip Milne            TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
10436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        }
1044923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (hasAltitude()) s.append(" alt=").append(mAltitude);
1045923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (hasSpeed()) s.append(" vel=").append(mSpeed);
1046923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (hasBearing()) s.append(" bear=").append(mBearing);
10474402af6be9de4782d218170203033618f079551dgomo        if (hasVerticalAccuracy()) s.append(String.format(" vAcc=%.0f", mVerticalAccuracyMeters));
10484402af6be9de4782d218170203033618f079551dgomo        else s.append(" vAcc=???");
10494402af6be9de4782d218170203033618f079551dgomo        if (hasSpeedAccuracy()) s.append(String.format(" sAcc=%.0f", mSpeedAccuracyMetersPerSecond));
10504402af6be9de4782d218170203033618f079551dgomo        else s.append(" sAcc=???");
10514402af6be9de4782d218170203033618f079551dgomo        if (hasBearingAccuracy()) s.append(String.format(" bAcc=%.0f", mBearingAccuracyDegrees));
10524402af6be9de4782d218170203033618f079551dgomo        else s.append(" bAcc=???");
1053923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (isFromMockProvider()) s.append(" mock");
10546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
10556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        if (mExtras != null) {
10566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly            s.append(" {").append(mExtras).append('}');
10576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        }
10586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        s.append(']');
10596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        return s.toString();
10606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
10616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly
10626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    public void dump(Printer pw, String prefix) {
10636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        pw.println(prefix + toString());
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<Location> CREATOR =
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new Parcelable.Creator<Location>() {
10686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        @Override
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Location createFromParcel(Parcel in) {
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String provider = in.readString();
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Location l = new Location(provider);
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mTime = in.readLong();
10734118012da9a22694b3353040a485f8cdc27e2f17Philip Milne            l.mElapsedRealtimeNanos = in.readLong();
1074923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            l.mFieldsMask = in.readByte();
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mLatitude = in.readDouble();
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mLongitude = in.readDouble();
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mAltitude = in.readDouble();
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mSpeed = in.readFloat();
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            l.mBearing = in.readFloat();
10804402af6be9de4782d218170203033618f079551dgomo            l.mHorizontalAccuracyMeters = in.readFloat();
10814402af6be9de4782d218170203033618f079551dgomo            l.mVerticalAccuracyMeters = in.readFloat();
10824402af6be9de4782d218170203033618f079551dgomo            l.mSpeedAccuracyMetersPerSecond = in.readFloat();
10834402af6be9de4782d218170203033618f079551dgomo            l.mBearingAccuracyDegrees = in.readFloat();
1084a04c7a7c6442b8c6f87f5dd11fc5659cdb92deccJeff Sharkey            l.mExtras = Bundle.setDefusable(in.readBundle(), true);
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return l;
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly        @Override
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Location[] newArray(int size) {
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new Location[size];
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    @Override
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel parcel, int flags) {
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeString(mProvider);
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeLong(mTime);
11034118012da9a22694b3353040a485f8cdc27e2f17Philip Milne        parcel.writeLong(mElapsedRealtimeNanos);
1104923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        parcel.writeByte(mFieldsMask);
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeDouble(mLatitude);
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeDouble(mLongitude);
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeDouble(mAltitude);
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeFloat(mSpeed);
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeFloat(mBearing);
11104402af6be9de4782d218170203033618f079551dgomo        parcel.writeFloat(mHorizontalAccuracyMeters);
11114402af6be9de4782d218170203033618f079551dgomo        parcel.writeFloat(mVerticalAccuracyMeters);
11124402af6be9de4782d218170203033618f079551dgomo        parcel.writeFloat(mSpeedAccuracyMetersPerSecond);
11134402af6be9de4782d218170203033618f079551dgomo        parcel.writeFloat(mBearingAccuracyDegrees);
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeBundle(mExtras);
11156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly    }
111609016ab4dd056a16809419d612cb865a14980880Victoria Lease
111709016ab4dd056a16809419d612cb865a14980880Victoria Lease    /**
111809016ab4dd056a16809419d612cb865a14980880Victoria Lease     * Returns one of the optional extra {@link Location}s that can be attached
111909016ab4dd056a16809419d612cb865a14980880Victoria Lease     * to this Location.
112009016ab4dd056a16809419d612cb865a14980880Victoria Lease     *
112109016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @param key the key associated with the desired extra Location
112209016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @return the extra Location, or null if unavailable
112309016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @hide
112409016ab4dd056a16809419d612cb865a14980880Victoria Lease     */
112509016ab4dd056a16809419d612cb865a14980880Victoria Lease    public Location getExtraLocation(String key) {
112609016ab4dd056a16809419d612cb865a14980880Victoria Lease        if (mExtras != null) {
112709016ab4dd056a16809419d612cb865a14980880Victoria Lease            Parcelable value = mExtras.getParcelable(key);
112809016ab4dd056a16809419d612cb865a14980880Victoria Lease            if (value instanceof Location) {
112909016ab4dd056a16809419d612cb865a14980880Victoria Lease                return (Location) value;
113009016ab4dd056a16809419d612cb865a14980880Victoria Lease            }
113109016ab4dd056a16809419d612cb865a14980880Victoria Lease        }
113209016ab4dd056a16809419d612cb865a14980880Victoria Lease        return null;
113309016ab4dd056a16809419d612cb865a14980880Victoria Lease    }
113409016ab4dd056a16809419d612cb865a14980880Victoria Lease
113509016ab4dd056a16809419d612cb865a14980880Victoria Lease    /**
113609016ab4dd056a16809419d612cb865a14980880Victoria Lease     * Attaches an extra {@link Location} to this Location.
113709016ab4dd056a16809419d612cb865a14980880Victoria Lease     *
113809016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @param key the key associated with the Location extra
1139923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * @param value the Location to attach
114009016ab4dd056a16809419d612cb865a14980880Victoria Lease     * @hide
114109016ab4dd056a16809419d612cb865a14980880Victoria Lease     */
114209016ab4dd056a16809419d612cb865a14980880Victoria Lease    public void setExtraLocation(String key, Location value) {
114309016ab4dd056a16809419d612cb865a14980880Victoria Lease        if (mExtras == null) {
114409016ab4dd056a16809419d612cb865a14980880Victoria Lease            mExtras = new Bundle();
114509016ab4dd056a16809419d612cb865a14980880Victoria Lease        }
114609016ab4dd056a16809419d612cb865a14980880Victoria Lease        mExtras.putParcelable(key, value);
114709016ab4dd056a16809419d612cb865a14980880Victoria Lease    }
114854ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease
114954ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    /**
115054ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     * Returns true if the Location came from a mock provider.
115154ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     *
115254ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     * @return true if this Location came from a mock provider, false otherwise
115354ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     */
115454ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    public boolean isFromMockProvider() {
1155923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        return (mFieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
115654ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    }
115754ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease
115854ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    /**
115954ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     * Flag this Location as having come from a mock provider or not.
116054ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     *
116154ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     * @param isFromMockProvider true if this Location came from a mock provider, false otherwise
116254ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     * @hide
116354ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease     */
1164c20b795cf05b48fe5e024c19dab9c7e4b18cd10fDavid Christie    @SystemApi
116554ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    public void setIsFromMockProvider(boolean isFromMockProvider) {
1166923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        if (isFromMockProvider) {
1167923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            mFieldsMask |= HAS_MOCK_PROVIDER_MASK;
1168923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        } else {
1169923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie            mFieldsMask &= ~HAS_MOCK_PROVIDER_MASK;
1170923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        }
1171923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    }
1172923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie
1173923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    /**
1174923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * Caches data used to compute distance and bearing (so successive calls to {@link #distanceTo}
1175923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     * and {@link #bearingTo} don't duplicate work.
1176923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie     */
1177923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie    private static class BearingDistanceCache {
1178923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private double mLat1 = 0.0;
1179923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private double mLon1 = 0.0;
1180923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private double mLat2 = 0.0;
1181923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private double mLon2 = 0.0;
1182923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private float mDistance = 0.0f;
1183923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private float mInitialBearing = 0.0f;
1184923b2602583021b97ac7a8dcbca8395e309b938eDavid Christie        private float mFinalBearing = 0.0f;
118554ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease    }
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1187