方法一:
/** * 计算地球上任意两点(经纬度)距离 * * @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; }
方法二:(恋家厨房中用的)
private const double EARTH_RADIUS = 6378.137;
private static double rad(double d)
{
return d * Math.PI / 180.0;
}
public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
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; } }