方法一:java
/** * 計算地球上任意兩點(經緯度)距離 * * @param long1 * 第一點經度 * @param lat1 * 第一點緯度 * @param long2 * 第二點經度 * @param lat2 * 第二點緯度 * @return 返回距離 單位:米 */ public static double Distance(double long1, double lat1, double long2, double lat2) { double a, b, R; R = 6378137; // 地球半徑 lat1 = lat1 * Math.PI / 180.0; lat2 = lat2 * Math.PI / 180.0; a = lat1 - lat2; b = (long1 - long2) * Math.PI / 180.0; double d; double sa2, sb2; sa2 = Math.sin(a / 2.0); sb2 = Math.sin(b / 2.0); d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2)); return d; }
方法二:(戀家廚房中用的)android
private const double EARTH_RADIUS = 6378.137; git
private static double rad(double d) api
{ ide
return d * Math.PI / 180.0; 工具
} ui
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) code
{ get
double radLat1 = rad(lat1); it
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2)));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
工具類:
import android.util.Log; import com.baidu.mapapi.model.LatLng; /** * Created by SRain on 2015/10/16. * <p/> * 計算兩點間距離 * <p/> * 路線規劃提供了獲取路線距離的方法,見MKRoutePlan 類的 getDistance 方法。 * 若是是計算任意兩點的距離,有兩種方法: * 一種利用勾股定理計算,適用於兩點距離很近的狀況; * 一種按標準的球面大圓劣弧長度計算,適用於距離較遠的狀況。 */ public class CalculateDistanceUtils { static double DEF_PI = 3.14159265359; // PI static double DEF_2PI = 6.28318530712; // 2*PI static double DEF_PI180 = 0.01745329252; // PI/180.0 static double DEF_R = 6370693.5; // radius of earth /** * 利用勾股定理計算,適用於兩點距離很近的狀況; * * @param lon1 * @param lat1 * @param lon2 * @param lat2 * @return */ public double GetShortDistance(double lon1, double lat1, double lon2, double lat2) { double ew1, ns1, ew2, ns2; double dx, dy, dew; double distance; // 角度轉換爲弧度 ew1 = lon1 * DEF_PI180; ns1 = lat1 * DEF_PI180; ew2 = lon2 * DEF_PI180; ns2 = lat2 * DEF_PI180; // 經度差 dew = ew1 - ew2; // 若跨東經和西經180 度,進行調整 if (dew > DEF_PI) dew = DEF_2PI - dew; else if (dew < -DEF_PI) dew = DEF_2PI + dew; dx = DEF_R * Math.cos(ns1) * dew; // 東西方向長度(在緯度圈上的投影長度) dy = DEF_R * (ns1 - ns2); // 南北方向長度(在經度圈上的投影長度) // 勾股定理求斜邊長 distance = Math.sqrt(dx * dx + dy * dy); return distance; } /** * 按標準的球面大圓劣弧長度計算,適用於距離較遠的狀況。 * * @param lon1 * @param lat1 * @param lon2 * @param lat2 * @return */ public double GetLongDistance(double lon1, double lat1, double lon2, double lat2) { double ew1, ns1, ew2, ns2; double distance; // 角度轉換爲弧度 ew1 = lon1 * DEF_PI180; ns1 = lat1 * DEF_PI180; ew2 = lon2 * DEF_PI180; ns2 = lat2 * DEF_PI180; // 求大圓劣弧與球心所夾的角(弧度) distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2); // 調整到[-1..1]範圍內,避免溢出 if (distance > 1.0) distance = 1.0; else if (distance < -1.0) distance = -1.0; // 求大圓劣弧長度 distance = DEF_R * Math.acos(distance); return distance; } /** * 按標準的球面大圓劣弧長度計算,適用於距離較遠的狀況。 * * @param atLatLng 當前位置 * @param guideLatLng 景點位置 * @return */ public static double GetLongDistance(LatLng atLatLng, LatLng guideLatLng) { double ew1, ns1, ew2, ns2; double distance; // 角度轉換爲弧度 ew1 = atLatLng.longitude * DEF_PI180; ns1 = atLatLng.latitude * DEF_PI180; ew2 = guideLatLng.longitude * DEF_PI180; ns2 = guideLatLng.latitude * DEF_PI180; // 求大圓劣弧與球心所夾的角(弧度) distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2); // 調整到[-1..1]範圍內,避免溢出 if (distance > 1.0) distance = 1.0; else if (distance < -1.0) distance = -1.0; // 求大圓劣弧長度 distance = DEF_R * Math.acos(distance); return distance; } /** * 按標準的球面大圓劣弧長度計算,適用於距離較遠的狀況。 * * @param atLatLng 當前位置 * @param longitude 景點位置 * @param latitude 景點位置 * @return */ public static double GetLongDistance(LatLng atLatLng, double longitude, double latitude) { double ew1, ns1, ew2, ns2; double distance; // 角度轉換爲弧度 ew1 = atLatLng.longitude * DEF_PI180; ns1 = atLatLng.latitude * DEF_PI180; ew2 = longitude * DEF_PI180; ns2 = latitude * DEF_PI180; // 求大圓劣弧與球心所夾的角(弧度) distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2); // 調整到[-1..1]範圍內,避免溢出 if (distance > 1.0) distance = 1.0; else if (distance < -1.0) distance = -1.0; // 求大圓劣弧長度 distance = DEF_R * Math.acos(distance); // Log.e("distance", "atLatLng" + atLatLng.latitude + " " + atLatLng.longitude + "\n" + "longitude:" + longitude + "latitude" + latitude + "\n dis:" + distance); return distance; } /** * 比較景點信息 * 當前位置是否在景區中 * * @param atLatLng 當前位置 * @param longitude 景點位置 * @param latitude 景點位置 * @param radius 景點範圍半徑 * @return */ public static boolean isAtRange(LatLng atLatLng, double longitude, double latitude, double radius) { boolean b = false; // 獲取當前位置和景區位置的距離 double distance = GetLongDistance(atLatLng, longitude, latitude); if (radius > distance) { b = true; } Log.e("-----distance-----", "\n distance:" + distance + "\n radius:" + radius + "\n b:" + b); return b; } }