android 计算角度,Android 计算地球上任意两点(经纬度)距离

这篇博客介绍了两种计算地球上两点间距离的方法。一种是基于勾股定理,适用于近距离计算;另一种是按照球面大圆劣弧长度计算,适合远距离计算。两种方法都考虑了地球半径,并将角度转换为弧度进行运算,确保了精度。此外,还提供了一个工具类用于实际应用中的距离计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一:

/**

* 计算地球上任意两点(经纬度)距离

*

* @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.

* 计算两点间距离

* 路线规划提供了获取路线距离的方法,见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 

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 

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 

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 

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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值