经纬度计算距离
1、经纬度计算距离
经纬度可以使用球面三角法来计算距离。一种常用的方法是使用Haversine公式。
Haversine公式:
d = 2r * arcsin(√(sin²((lat2 - lat1)/2) + cos(lat1) * cos(lat2) * sin²((lon2 - lon1)/2)))
其中,d是地球上两点之间的直线距离,r是地球半径(常用平均值为6371千米),lat1和lat2是两点的纬度,lon1和lon2是两点的经度。
C++代码
要计算两个地点之间的距离,可以使用经纬度坐标计算方法如下:
(1.) 首先,定义地球的平均半径,可以使用常量来表示:
cpp
const double EARTH_RADIUS = 6371.0; // 单位为千米
(2). 然后,定义两个地点的经纬度坐标(以度为单位):
cpp
double lat1 = 40.7128; // 纬度1
double lon1 = -74.0060; // 经度1
double lat2 = 34.0522; // 纬度2
double lon2 = -118.2437; // 经度2
(3). 将经纬度从度转换为弧度:
cpp
double lat1_rad = lat1 * M_PI / 180.0;
double lon1_rad = lon1 * M_PI / 180.0;
double lat2_rad = lat2 * M_PI / 180.0;
double lon2_rad = lon2 * M_PI / 180.0;
(4). 计算两个地点的纬度差和经度差的绝对值:
cpp
double delta_lat = fabs(lat2_rad - lat1_rad);
double delta_lon = fabs(lon2_rad - lon1_rad);
(5). 使用Haversine公式进行距离计算:
cpp
double a = sin(delta_lat / 2) * sin(delta_lat / 2) + cos(lat1_rad) * cos(lat2_rad) * sin(delta_lon / 2) * sin(delta_lon / 2);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
double distance = EARTH_RADIUS * c;
(6.) 最后,可将计算出的距离以所需的单位进行输出(如公里或英里):
cpp
cout << "Distance between the two locations is " << distance << " kilometers." << endl;
(7.) 完整代码如下:
cpp
#include <iostream>
#include <cmath>
using namespace std;
const double EARTH_RADIUS = 6371.0; // 单位为千米
int main() {
double lat1 = 40.7128; // 纬度1
double lon1 = -74.0060; // 经度1
double lat2 = 34.0522; // 纬度2
double lon2 = -118.2437; // 经度2
double lat1_rad = lat1 * M_PI / 180.0;
double lon1_rad = lon1 * M_PI / 180.0;
double lat2_rad = lat2 * M_PI / 180.0;
double lon2_rad = lon2 * M_PI / 180.0;
double delta_lat = fabs(lat2_rad - lat1_rad);
double delta_lon = fabs(lon2_rad - lon1_rad);
double a = sin(delta_lat / 2) * sin(delta_lat / 2) + cos(lat1_rad) * cos(lat2_rad) * sin(delta_lon / 2) * sin(delta_lon / 2);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
double distance = EARTH_RADIUS * c;
cout << "Distance between the two locations is " << distance << " kilometers." << endl;
return 0;
}
上述代码给出的距离是以千米为单位的,如果需要以其他单位表示(如米或英里),可以根据需要进行转换。
C语言代码
计算两个地点之间的距离可以使用球面三角法,根据经纬度的差值来计算。
以下是使用C语言计算经纬度距离的示例代码:
c
#include <math.h>
#define PI 3.14159265
#define R 6371 // 地球半径,单位为千米
double to_rad(double degree) {
return degree * PI / 180.0;
}
double distance(double lat1, double lon1, double lat2, double lon2) {
double dlat = to_rad(lat2 - lat1);
double dlon = to_rad(lon2 - lon1);
double a = sin(dlat/2) * sin(dlat/2) + cos(to_rad(lat1)) * cos(to_rad(lat2)) * sin(dlon/2) * sin(dlon/2);
double c = 2 * atan2(sqrt(a), sqrt(1-a));
double d = R * c;
return d;
}
int main() {
double lat1 = 39.9075;
double lon1 = 116.39723;
double lat2 = 31.2304;
double lon2 = 121.4737;
double dist = distance(lat1, lon1, lat2, lon2);
printf("距离:%lf千米\n", dist);
return 0;
}
需要注意的是,C语言中的sin、cos、sqrt、atan2等函数的参数单位是弧度,而不是角度。因此,需要先将经纬度的度数转换为弧度,然后再进行计算。函数to_rad
用于将度数转换为弧度。
以上示例代码中,计算的是北京(39.9075°N, 116.39723°E)到上海(31.2304°N, 121.4737°E)之间的距离。计算结果为多少千米。
Python示例代码
以下是一个示例Python代码,可以计算两个经纬度之间的距离:
import math
def distance(lat1, lon1, lat2, lon2):
r = 6371 # 地球半径(单位:千米)
lat1 = math.radians(lat1)
lon1 = math.radians(lon1)
lat2 = math.radians(lat2)
lon2 = math.radians(lon2)
dlat = lat2 - lat1
dlon = lon2 - lon1
a = math.sin(dlat/2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2) ** 2
c = 2 * math.asin(math.sqrt(a))
distance = r * c
return distance
···
## 示例调用
lat1 = 40.7128
lon1 = -74.0060
lat2 = 34.0522
lon2 = -118.2437
d = distance(lat1, lon1, lat2, lon2)
print("Distance: ", d, " km")
C#示例代码
https://blog.csdn.net/jasonsong2008/article/details/78423496
/// <summary>
/// 通过地图上的两个坐标计算距离(C#版本)
/// Add by 成长的小猪(Jason.Song) on 2017/11/01
/// http://blog.csdn.net/jasonsong2008
/// </summary>
public class MapHelper
{
/// <summary>
/// 地球半径
/// </summary>
private const double EarthRadius = 6378.137;
/// <summary>
/// 经纬度转化成弧度
/// Add by 成长的小猪(Jason.Song) on 2017/11/01
/// http://blog.csdn.net/jasonsong2008
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
private static double Rad(double d)
{
return d * Math.PI / 180d;
}
/// <summary>
/// 计算两个坐标点之间的距离
/// Add by 成长的小猪(Jason.Song) on 2017/11/01
/// http://blog.csdn.net/jasonsong2008
/// </summary>
/// <param name="firstLatitude">第一个坐标的纬度</param>
/// <param name="firstLongitude">第一个坐标的经度</param>
/// <param name="secondLatitude">第二个坐标的纬度</param>
/// <param name="secondLongitude">第二个坐标的经度</param>
/// <returns>返回两点之间的距离,单位:公里/千米</returns>
public static double GetDistance(double firstLatitude, double firstLongitude, double secondLatitude, double secondLongitude)
{
var firstRadLat = Rad(firstLatitude);
var firstRadLng = Rad(firstLongitude);
var secondRadLat = Rad(secondLatitude);
var secondRadLng = Rad(secondLongitude);
var a = firstRadLat - secondRadLat;
var b = firstRadLng - secondRadLng;
var cal = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(firstRadLat)
* Math.Cos(secondRadLat) * Math.Pow(Math.Sin(b / 2), 2))) * EarthRadius;
var result = Math.Round(cal * 10000) / 10000;
return result;
}
/// <summary>
/// 计算两个坐标点之间的距离
/// Add by 成长的小猪(Jason.Song) on 2017/11/01
/// http://blog.csdn.net/jasonsong2008
/// </summary>
/// <param name="firstPoint">第一个坐标点的(纬度,经度)</param>
/// <param name="secondPoint">第二个坐标点的(纬度,经度)</param>
/// <returns>返回两点之间的距离,单位:公里/千米</returns>
public static double GetPointDistance(string firstPoint, string secondPoint)
{
var firstArray = firstPoint.Split(',');
var secondArray = secondPoint.Split(',');
var firstLatitude = Convert.ToDouble(firstArray[0].Trim());
var firstLongitude = Convert.ToDouble(firstArray[1].Trim());
var secondLatitude = Convert.ToDouble(secondArray[0].Trim());
var secondLongitude = Convert.ToDouble(secondArray[1].Trim());
return GetDistance(firstLatitude, firstLongitude, secondLatitude, secondLongitude);
}
}
C#调用示例代码
/// <summary>
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//第一种调用方法
var result = MapHelper.GetDistance(31.2553210000, 121.4620020000, 31.2005470000, 121.3269970000);
//第二种调用方法
result = MapHelper.GetPointDistance("31.2553210000,121.4620020000", "31.2005470000,121.3269970000");
}
Java示例代码
http://blog.csdn.net/jasonsong2008/article/details/78434237
/**
* 通过地图上的两个坐标计算距离(Java版本)
* Add by 成长的小猪(Jason.Song) on 2017/11/01
* http://blog.csdn.net/jasonsong2008
*/
public class MapHelper {
/**
* 地球半径
*/
private static double EarthRadius = 6378.137;
/**
* 经纬度转化成弧度
* Add by 成长的小猪(Jason.Song) on 2017/11/01
* http://blog.csdn.net/jasonsong2008
*
* @param d 经度/纬度
* @return
*/
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 计算两个坐标点之间的距离
* Add by 成长的小猪(Jason.Song) on 2017/11/01
* http://blog.csdn.net/jasonsong2008
*
* @param firstLatitude 第一个坐标的纬度
* @param firstLongitude 第一个坐标的经度
* @param secondLatitude 第二个坐标的纬度
* @param secondLongitude 第二个坐标的经度
* @return 返回两点之间的距离,单位:公里/千米
*/
public static double getDistance(double firstLatitude, double firstLongitude,
double secondLatitude, double secondLongitude) {
double firstRadLat = rad(firstLatitude);
double firstRadLng = rad(firstLongitude);
double secondRadLat = rad(secondLatitude);
double secondRadLng = rad(secondLongitude);
double a = firstRadLat - secondRadLat;
double b = firstRadLng - secondRadLng;
double cal = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(firstRadLat)
* Math.cos(secondRadLat) * Math.pow(Math.sin(b / 2), 2))) * EarthRadius;
double result = Math.round(cal * 10000d) / 10000d;
return result;
}
/**
* 计算两个坐标点之间的距离
* Add by 成长的小猪(Jason.Song) on 2017/11/01
* http://blog.csdn.net/jasonsong2008
*
* @param firstPoint 第一个坐标点的(纬度,经度) 例如:"31.2553210000,121.4620020000"
* @param secondPoint 第二个坐标点的(纬度,经度) 例如:"31.2005470000,121.3269970000"
* @return 返回两点之间的距离,单位:公里/千米
*/
public static double GetPointDistance(String firstPoint, String secondPoint) {
String[] firstArray = firstPoint.split(",");
String[] secondArray = secondPoint.split(",");
double firstLatitude = Double.valueOf(firstArray[0].trim());
double firstLongitude = Double.valueOf(firstArray[1].trim());
double secondLatitude = Double.valueOf(secondArray[0].trim());
double secondLongitude = Double.valueOf(secondArray[1].trim());
return getDistance(firstLatitude, firstLongitude, secondLatitude, secondLongitude);
}
}
Java调用示例代码
/**
* 文章来源于成长的小猪
* http://blog.csdn.net/jasonsong2008
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/applicationContext.xml"})
public class MapHelperTest {
@Test
public void getDistance() throws Exception {
/**
* 第一种调用方法
*/
double result = MapHelper.getDistance(31.2553210000, 121.4620020000, 31.2005470000, 121.3269970000);
System.out.println(result);
double expected = 14.2243;
TestCase.assertEquals(expected, result);
}
@Test
public void getPointDistance() throws Exception {
/**
* 第二种调用方法
*/
double result = MapHelper.GetPointDistance("31.2553210000,121.4620020000", "31.2005470000,121.3269970000");
System.out.println(result);
double expected = 14.2243;
TestCase.assertEquals(expected, result);
}
}
2、经纬度计算距离_考虑地球椭圆半径
要计算两个经纬度点之间的距离,并考虑地球的椭圆形状,可以使用Haversine公式。
Haversine公式是一种用于计算球面上两点之间距离的公式,它考虑地球的曲率和椭圆形状。
下面是使用Haversine公式计算距离的示例代码(使用Python):
```python
import math
def haversine(lat1, lon1, lat2, lon2):
"""
Calculate the great circle distance in kilometers between two points
on the earth specified in decimal degrees.
"""
# 将经纬度从度转换为弧度
lat1 = math.radians(lat1)
lon1 = math.radians(lon1)
lat2 = math.radians(lat2)
lon2 = math.radians(lon2)
# Haversine公式
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
# 地球平均半径(千米)
R = 6371
# 计算距离
distance = R * c
return distance
使用该函数可以计算两个经纬度点之间的距离(单位为千米)。例如:
python
distance = haversine(40.7128, -74.0060, 34.0522, -118.2437)
print(distance)
这将打印出两个城市(纽约和洛杉矶)之间的大圆距离(单位为千米)。
3 、经纬度计算距离_考虑地球椭圆半径不均匀误差
计算地球上两点之间的距离时,一般采用大圆距离近似公式,即球面上两点之间的距离等于两点之间的弧长。
如果要考虑地球的椭圆形状和半径的不均匀误差,可以使用Vincenty公式来计算。这个公式考虑了地球的椭圆形状和半径的不均匀性,可以得到更精确的结果。
以下是使用Vincenty公式计算地球上两点之间距离的方法:
1. 定义常量:
- a为地球的赤道半径;
- b为地球的极半径;
- f为地球扁率(f = (a-b)/a)。
2. 输入两点的经纬度坐标(纬度用正负表示,0度在赤道上)。
3. 将经纬度转换为弧度(角度乘以π/180)。
4. 计算U1和U2:
- U1 = atan((1-f) * tan(lat1)),
- U2 = atan((1-f) * tan(lat2))。
5. 计算sinU1、cosU1、sinU2、cosU2和L,其中L表示两点经度之差。
- sinU1 = sin(U1),
- cosU1 = cos(U1),
- sinU2 = sin(U2),
- cosU2 = cos(U2),
- L = lon2 - lon1。
6. 计算sin^2σ和cos^2σ:
- sin^2σ = (cosU2 * sinL)^2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosL)^2,
- cos^2σ = 1 - sin^2σ。
7. 计算σ:
- σ = atan2(sqrt(sin^2σ, cos^2σ)。
8. 计算sinα、cos^2α和cos^2σm:
- sinα = (cosU1 * cosU2 * sinL) / sinσ,
- cos^2α = 1 - sinα^2,
- cos^2σm = cos^2σ - (2 * sinU1 * sinU2) / cos^2α。
9. 计算C:
- C = f / 16 * cos^2α * (4 + f * (4 - 3 * cos^2α))。
10. 计算λ:
- λ = L + (1 - C) * f * sinα * (σ + C * sinσ * (cos^2σm + C * cosσ * (-1 + 2 * cos^2σm^2)))。
11. 计算距离d:
- d = b * (σ - C * sinσ * (cos^2σm + C * cosσ * (-1 + 2 * cos^2σm^2)))。
请注意,这只是一个粗略描述,实际使用时需要进行适当的数值计算和程序编写。