根据经纬度坐标计算距离和方向

前段时间由于项目需要,了解了一下不同经纬度坐标间距离的计算和方向的相关问题,本文理论主要参考下面作者提出的方法,需要访问原作者内容,请点击下面的链接:https://www.cnblogs.com/zhoug2020/p/8993750.html

此处我采用的也是Haversine formula公式来计算球面上任意两个坐标间的距离。

定义的类如下:

DistanceBetweenLonAndLat.h

#include 
#define M_PI 3.14159265358979323846
#define EARTH_RADIUS 6371.0

class DistanceBetweenLonAndLat
{
public:
	DistanceBetweenLonAndLat();
	~DistanceBetweenLonAndLat();
protected:
	double HaverSin(double thera);
	double ConvertDegreesToRadians(double degrees);
	double ConvertRadiansToDegrees(double radian);
	double get_distance(double lon1, double lat1, double lon2, double lat2);
	int get_angle(double lon1, double lat1, double lon2, double lat2);
	int AngleSpecification(int angle);
};

具体实现的方法如下:

#include "DistanceBetweenLonAndLat.h"

DistanceBetweenLonAndLat::DistanceBetweenLonAndLat()
{
}


DistanceBetweenLonAndLat::~DistanceBetweenLonAndLat()
{
}

double DistanceBetweenLonAndLat::HaverSin(double thera)
{
	double v = sin(thera / 2);
	return v * v;
}

//角度转换为弧度
double DistanceBetweenLonAndLat::ConvertDegreesToRadians(double degrees)
{
	return degrees * M_PI / 180;
}

//弧度转换为角度
double DistanceBetweenLonAndLat::ConvertRadiansToDegrees(double radian)
{
	return radian * 180.0 / M_PI;
}

//计算两个经纬度坐标间的距离(单位:米)
//参数:lon1为经度1;lat1为纬度1;lon2为经度2;lat2为纬度2
double DistanceBetweenLonAndLat::get_distance(double lon1, double lat1, double lon2, double lat2)
{
	lat1 = ConvertDegreesToRadians(lat1);
	lon1 = ConvertDegreesToRadians(lon1);
	lat2 = ConvertDegreesToRadians(lat2);
	lon2 = ConvertDegreesToRadians(lon2);

	double vLon = fabs(lon1 - lon2);
	double vLat = fabs(lat1 - lat2);
	double h = HaverSin(vLat) + cos(lat1) * cos(lat2) * HaverSin(vLon);
	double distance = 2 * EARTH_RADIUS * asin(sqrt(h));

	return distance * 1000;
}

//两个经纬度间连线与正北方向的夹角
//参数:lon1为经度1;lat1为纬度1;lon2为经度2;lat2为纬度
double DistanceBetweenLonAndLat::get_angle(double lon1, double lat1, double lon2, double lat2)
{
	double x = lat1 - lat2;
	double y = lon1 - lon2;
	int angle = -1;
	if (y == 0 && x > 0)
		angle = 0;
	if (y == 0 && x < 0)
		angle = 180;
	if (x == 0 && y > 0)
		angle = 90;
	if (x == 0 && y < 0)
		angle = 270;
	if (angle == -1)
	{
		double dislon = get_distance(lon1, lat2, lon2, lat2);
		double dislat = get_distance(lon2, lat1, lon2, lat2);
		if (x > 0 && y > 0)
			angle = atan2(dislon, dislat) / M_PI * 180;
		if (x < 0 && y > 0)
			angle = atan2(dislat, dislon) / M_PI * 180 + 90;
		if (x < 0 && y < 0)
			angle = atan2(dislon, dislat) / M_PI * 180 + 180;
		if (x > 0 && y < 0)
			angle = atan2(dislat, dislon) / M_PI * 180 + 270;
	}
	return angle;
}

//将角度限制在[0,360),0--北,90--东,180--南,270--西;与指南针一致
int DistanceBetweenLonAndLat::AngleSpecification(int angle)
{
	int curAngle;
	if (angle < 0)
	{
		curAngle = (angle + 360) % 360;
	}
	else {
		curAngle = angle % 360;
	}
	return curAngle;
}

调用也很简单,由于项目保密级别较高,此处就不展示如何调用了。

谨以此记录这个重要的知识点,愿本篇文章对您有所帮助。

你可能感兴趣的:(根据经纬度坐标计算距离和方向)