本文主要是介绍Java计算经纬度距离的示例代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下...
在 Java 中计算两个经纬度之间的距离,可以使用以下多种方法(代码示例均返回米为单位):
1. Haversine公式(中等精度,推荐通用场景)
public class GeoDistanceCalculator { public static double haversineDistance(double lat1, double lon1, double lat2, double lon2) { final int EARTH_RADIUS_METERS = 6371000; double dLat = Math.toRadians(lat2 - lat1); double dLon = Math.toRadians(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return EARTH_RADIUS_METERS * c; } public static void main(String[] args) { double distance = haversineDistance(40.7128, -74.0060, 34.0522, -118.2437); System.out.println("距离:" + distance + " 米"); // 输出约 3933476 米 } }
2. 球面余弦定理(简单但精度较低)
public static double sphericalCosineLaw(double lat1, double lon1, double lat2, double lon2) { final int EARTH_RADIUS_METERS = 6371000; double lat1Rad = Math.toRadians(lat1); double lat2Rad = Math.toRadians(lat2); double dLon = Math.toRadians(lon2 - lon1); double distance = Math.acos( Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon) ) * EARTH_RADIUS_METERS; return distance; }
3. Vincenty公式(高精度,适用于复杂模型)
public static double vincentyDistance(double lat1, double lon1, double lat2, double lon2) { final double a = 6378137.0; // 赤道半径(米) final double b = 6356752.314245; // 极半径(米) final double f = 1 / 298.257223563; // 扁率 double L = Math.toRadians(lon2 - lon1); double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1))); double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2))); double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); double lambda = L, lambdaPrev; double sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, C; int maxIterations = 200; do { double sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda); sinSigma = Math.sqrt( (cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) ); if (sinSigma == 0) return 0; // 重合点 cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.atan2(sinSigma, cosSwww.chinasem.cnigma); javascript sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaPrev = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cosSigma + C * cosSigma * (-1 + 2 * C * cosSigma * cosSigma))); } while (Math.abs(lambda - lambdaPrev) > 1e-12 && --maxIterations > 0); double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double deltaSigma = B * sinSigma * (cosSigma + B / 4 * (cosSigma * (-1 + 2 * B * cosSigma * cosSigma) - B / 6 * cosSigma * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cosSigma * cosSigma))); return b * A * (sigma - deltaSigma); }
4. Android内置方法(仅限Android开发)
import android.location.Location; public static float androidLocationDistance(double lat1, double lon1, double lat2, double lon2) { Location location1 = new Location("point1"); location1.setLatitude(lat1); location1.setLongitude(lon1); Location location2 = new Location("point2"); location2.setLatitude(lat2); location2.setLongitude(lon2); return location1.distanceTo(location2); // 返回米 }
5. 极地坐标系近似法(快速但低精度)
public static double polarApproximation(double lat1, double lon1, double lat2, double lon2) { final int EARTH_RADIUS_METERS = 6371000; double dLat = Math.toRadians(lat2 - lat1); double dLon = Math.toRadians(lon2 - lon1); double avgLat = Math.toRadians((lat1 + lat2) / 2); double x = dLon * Math.cos(avgLat); double y = dLat; return Math.sqrt(x * x + y * y) * EARTH_RADIUS_METERS; }
6.方法对比
方法 | 精度 | 速度 | 适用场景 |
---|---|---|---|
Haversine公式 | 中等(~0.5%) | 快 | 通用场景(导航、LBhttp://www.chinasem.cnS服务) |
Vincenty公式 | 高(~0.5mm) | 慢 | 高精度需求(测绘、科学研究) |
球面余弦定理 | 低 | 快 | 快速估算(非关键场景) |
Android Location | 中等 | 中等 | Android应用开发 |
极地近似法 | 低 | 极快 | 快速筛选大量坐标点 |
7.选择建议
推荐使用 Haversine 公式:适用于大多数应用(如计算两个城市间的距离)。
需要高精度时选择 Vincenty 公式:例如地质勘测或导航系统。
Android 开发直接使用 Location.distanceTo():无需手动实现算法。
快速筛选坐标点用极地近似法:例如在数据库中筛选附近地点。
8.知识延展
python计算经纬度两点之间距离方法
在Python中计算两个经纬度之间的距离有多种方法,常用的包括Haversine公式和Vincenty公式。下面是这两种方法的实现示例。
1. Haversine公式
Haversine公式是一种简单且常用的计算地球表面两点之间最短距离(大圆距离)的方法。
import math def haversine_distance(lat1, lon1, lat2, lon2): # 地球半径,单位:公里 R = 6371.0 # 将经纬度转换为弧度 lat1_rad = math.radians(lat1) lon1_rad = math.radians(lon1) lat2_rad = math.radians(lat2) lon2_rad = math.radians(lon2) # 计算差值 dlat = lat2_rad - lat1_rad dlon = lon2_rad - lon1_rad # Haversine公式 a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rChina编程ad) * math.sin(dlon / 2)**2 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) distance = R * c return distance # 示例使用 lat1, lon1 = 34.052235, -118.243683 # 洛杉矶的经纬度 lat2, lon2 = 40.712776, -74.005974 # 纽约的经纬度 distance = haversine_distance(lat1, lon1, lat2, lon2) print(f"Distance using Haversine formula: {distance} km")
2. Vincenty公式
Vincenty公式提供了更高的精度,适用于需要精确测量的情况。
第一种使用geographiclib库
pip install geographiclib from geographiclib.geodesic import Geodesic def vincenty_distance(lat1, lon1, lat2, lon2): geod = Geodesic.WGS84 # 使用WGS84椭球体模型 result = geod.Inverse(lat1, lon1, lat2, lon2) distance = result['s12'] / 1000.0 # 距离单位:公里 return distance # 示例使用 lat1, lon1 = 34.052235, -118.243683 # 洛杉矶的经纬度 lat2, lon2 = 40.712776, -74.005974 # 纽约的经纬度 distance = vincenty_distance(lat1, lon1, lat2, lon2) print(f"Distance using Vincenty formula: {distance} km")
第二种使用geopy库
pip install geopy from geopy.distance import geodesic def calculate_distance_with_geopy(lat1, lon1, lat2, lon2): # 定义两个点 point1 = (lat1, lon1) point2 = (lahttp://www.chinasem.cnt2, lon2) # 计算两点之间的距离 distance = geodesic(point1, point2).kilometers return distance # 示例使用 lat1, lon1 = 34.052235, -118.243683 # 洛杉矶的经纬度 lat2, lon2 = 40.712776, -74.005974 # 纽约的经纬度 distance = calculate_distance_with_geopy(lat1, lon1, lat2, lon2) print(f"Distance using Vincenty formula: {distance} km")
Haversine公式:简单易用,适合大多数情况。
Vincenty公式:更高精度,适用于需要精确测量的情况。
到此这篇关于Java计算经纬度距离的示例代码的文章就介绍到这了,更多相关Java计算经纬度距离内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Java计算经纬度距离的示例代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!