android 两个经纬度计算方位角和距离(Java版本)
生活随笔
收集整理的這篇文章主要介紹了
android 两个经纬度计算方位角和距离(Java版本)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前被同事緊急問起,location出來的經緯度怎么自已算出來方位角和距離。如果是自已算的話,一般來說是前后兩秒經緯度進行計算。我在android 系統源碼也看到計算方式。在這里進行貼出來,記錄一下。
1、location 類
這個是location類。有android api源碼都能找到的。
2、關鍵代碼
private static void computeDistanceAndBearing(double lat1, double lon1,double lat2, double lon2, float[] results) {// Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf// using the "Inverse Formula" (section 4)int MAXITERS = 20;// Convert lat/long to radianslat1 *= Math.PI / 180.0;lat2 *= Math.PI / 180.0;lon1 *= Math.PI / 180.0;lon2 *= Math.PI / 180.0;double a = 6378137.0; // WGS84 major axisdouble b = 6356752.3142; // WGS84 semi-major axisdouble f = (a - b) / a;double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);double L = lon2 - lon1;double A = 0.0;double U1 = Math.atan((1.0 - f) * Math.tan(lat1));double U2 = Math.atan((1.0 - f) * Math.tan(lat2));double cosU1 = Math.cos(U1);double cosU2 = Math.cos(U2);double sinU1 = Math.sin(U1);double sinU2 = Math.sin(U2);double cosU1cosU2 = cosU1 * cosU2;double sinU1sinU2 = sinU1 * sinU2;double sigma = 0.0;double deltaSigma = 0.0;double cosSqAlpha = 0.0;double cos2SM = 0.0;double cosSigma = 0.0;double sinSigma = 0.0;double cosLambda = 0.0;double sinLambda = 0.0;double lambda = L; // initial guessfor (int iter = 0; iter < MAXITERS; iter++) {double lambdaOrig = lambda;cosLambda = Math.cos(lambda);sinLambda = Math.sin(lambda);double t1 = cosU2 * sinLambda;double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;double sinSqSigma = t1 * t1 + t2 * t2; // (14)sinSigma = Math.sqrt(sinSqSigma);cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)sigma = Math.atan2(sinSigma, cosSigma); // (16)double sinAlpha = (sinSigma == 0) ? 0.0 :cosU1cosU2 * sinLambda / sinSigma; // (17)cosSqAlpha = 1.0 - sinAlpha * sinAlpha;cos2SM = (cosSqAlpha == 0) ? 0.0 :cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defnA = 1 + (uSquared / 16384.0) * // (3)(4096.0 + uSquared *(-768 + uSquared * (320.0 - 175.0 * uSquared)));double B = (uSquared / 1024.0) * // (4)(256.0 + uSquared *(-128.0 + uSquared * (74.0 - 47.0 * uSquared)));double C = (f / 16.0) *cosSqAlpha *(4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)double cos2SMSq = cos2SM * cos2SM;deltaSigma = B * sinSigma * // (6)(cos2SM + (B / 4.0) *(cosSigma * (-1.0 + 2.0 * cos2SMSq) -(B / 6.0) * cos2SM *(-3.0 + 4.0 * sinSigma * sinSigma) *(-3.0 + 4.0 * cos2SMSq)));lambda = L +(1.0 - C) * f * sinAlpha *(sigma + C * sinSigma *(cos2SM + C * cosSigma *(-1.0 + 2.0 * cos2SM * cos2SM))); // (11)double delta = (lambda - lambdaOrig) / lambda;if (Math.abs(delta) < 1.0e-12) {break;}}float distance = (float) (b * A * (sigma - deltaSigma));results[0] = distance;if (results.length > 1) {float initialBearing = (float) Math.atan2(cosU2 * sinLambda,cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);initialBearing *= 180.0 / Math.PI;results[1] = initialBearing;if (results.length > 2) {float finalBearing = (float) Math.atan2(cosU1 * sinLambda,-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);finalBearing *= 180.0 / Math.PI;results[2] = finalBearing;}}}傳入兩個經緯度值,這個就不用高程。不用做過多的解釋了。
源碼封裝的調用方式
方位角(航向角)
/*** Returns the approximate initial bearing in degrees East of true* North when traveling along the shortest path between this* location and the given location. The shortest path is defined* using the WGS84 ellipsoid. Locations that are (nearly)* antipodal may produce meaningless results.** @param dest the destination location* @return the initial bearing in degrees*/public float bearingTo(Location dest) {synchronized (mResults) {// See if we already have the resultif (mLatitude != mLat1 || mLongitude != mLon1 ||dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {computeDistanceAndBearing(mLatitude, mLongitude,dest.mLatitude, dest.mLongitude, mResults);mLat1 = mLatitude;mLon1 = mLongitude;mLat2 = dest.mLatitude;mLon2 = dest.mLongitude;mDistance = mResults[0];mInitialBearing = mResults[1];}return mInitialBearing;}}距離:
/*** Returns the approximate distance in meters between this* location and the given location. Distance is defined using* the WGS84 ellipsoid.** @param dest the destination location* @return the approximate distance in meters*/public float distanceTo(Location dest) {// See if we already have the resultsynchronized (mResults) {if (mLatitude != mLat1 || mLongitude != mLon1 ||dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {computeDistanceAndBearing(mLatitude, mLongitude,dest.mLatitude, dest.mLongitude, mResults);mLat1 = mLatitude;mLon1 = mLongitude;mLat2 = dest.mLatitude;mLon2 = dest.mLongitude;mDistance = mResults[0];mInitialBearing = mResults[1];}return mDistance;}}都是調用這個方法進行計算的computeDistanceAndBearing。
想多了解android location方面:
android 模擬位置信息Location使用示例
android 自帶gps定位Location相關知識
? ? ??android location 數據標準輸出,原始mnea輸出和GpsStatus衛星狀態的變化
總結
以上是生活随笔為你收集整理的android 两个经纬度计算方位角和距离(Java版本)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员必须要掌握的 Git 操作技巧
- 下一篇: 深入优化GPU编程概述