⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coordinateconv.cpp

📁 经纬度之间的转换:知道两点的经纬度求的两点之间的方位和距离;以及知道一点的经纬度和方位距离求另一点的经纬度
💻 CPP
字号:
// CoordinateConv.cpp: implementation of the CCoordinateConv class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CCoordinateTranslateDemo.h"
#include "CoordinateConv.h"
#include "math.h"  // 数学库

const double PI = 3.1415926;

// 角度转化成弧度
inline double DTOR(double Degree)
{
	return Degree * PI / 180.0;
}

// 弧度转化成角度
inline double RTOD(double Radian)
{
	return Radian * 180.0 / PI;
}


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCoordinateConv::CCoordinateConv()
{

}

CCoordinateConv::~CCoordinateConv()
{

}


// 功  能:已知起点经纬度和航向(方位)、航程(距离),求终点经纬度
// 输入值:起点经纬度和航向(方位)、航程(距离)
// 返回值:终点经纬度(引用形式)
void CCoordinateConv::StartLatLonCSToEndLatLon(double dBeginLat,
										       double dBeginLong,
											   double dOrient,
											   double dDist,
											   double& dEndLat,
											   double& dEndLong)
{
	// 判断值的有效性
	ASSERT(dBeginLat>=0 && dBeginLat <= 90);
	ASSERT(dBeginLong>=0 && dBeginLong <= 180);
	ASSERT(dOrient>=0 && dOrient <= 360);
	ASSERT(dDist>=0);

	// 计算终点纬度
	double deltaLat = dDist/1.8520 * cos(DTOR(dOrient)); // 终点和起点的纬差,单位海里
	dEndLat = dBeginLat + deltaLat/60.0;                 // 海里转化成度,除以60

	// 计算终点经度
    double DMP = 7915.70447*(log10(tan(DTOR(45+dEndLat/2.0))) - log10(tan(DTOR(45+dBeginLat/2.0))));	// 计算纬度渐长率差,单位:分	
	double deltaLong = tan(DTOR(dOrient)) * DMP; // 终点和起点的经差,单位海里
	dEndLong = dBeginLong + deltaLong/60.0;                // 海里转化成度,除以60
}


// 功  能:已知起点和终点经纬度,求航向(方位)、航程(距离)
// 输入值:起点和终点经纬度
// 返回值:终点经纬度(引用形式)
void CCoordinateConv::LongLatToXY(double dBeginLat,
								  double dBeginLong,
								  double dEndLat,
								  double dEndLong,
								  double& dOrient,
								  double& dDist)
{
	// 判断值的有效性
	ASSERT(dBeginLat>=0 && dBeginLat <= 90);
	ASSERT(dBeginLong>=0 && dBeginLong <= 180);
	ASSERT(dEndLat>=0 && dEndLat <= 180);
	ASSERT(dEndLong>=0 && dEndLong <= 180);
	
	// 计算航向(方位)
    double DMP = 7915.70447*(log10(tan(DTOR(45+dEndLat/2.0))) - log10(tan(DTOR(45+dBeginLat/2.0))));	// 计算纬度渐长率差,单位:分

    double tmpdOrient = atan((dEndLong-dBeginLong)*60/DMP);  //dEndLong-dBeginLong单位是度,而DMP单位是分,故*60
	tmpdOrient = RTOD(fabs(tmpdOrient));	

	//  由于tmpdOrient的角度值在[0,90]之间,应讨论
	if(dEndLong >= dBeginLong) // 向东
	{
		if(dEndLat >= dBeginLat) // 向北[0 90] NE
		{
			dOrient = tmpdOrient;
		}                        
		else                     // 向南(90 180] SE
		{
			dOrient = 180 - tmpdOrient;
		}
	}
	else   // 向西
	{
		if(dEndLat >= dBeginLat) // 向北[270 360) NW
		{
			dOrient = 360 - tmpdOrient;
		}                        // 向南(90 180]  SW
		else
		{
			dOrient = 180 + tmpdOrient;
		}
	}


	// 计算航程(距离)
	BOOL bNear270 = IsNearRightAngle(dOrient); // 判断是否在90/270度附近

	if(!bNear270) 
	{
		dDist = (dEndLat - dBeginLat)*60 / cos(DTOR(dOrient)) * 1.852; 
	}
	else
	{
		// 在纬度较低、纬差不大、航程不远的情况下(即dEndLat - dBeginLat 不大),为简化计算,可用平均纬度代替中分纬度
		if(fabs(dEndLat - dBeginLat) < 5.0)   // 平均纬度 (dEndLat + dBeginLat)/2.0)
		{
			dDist = (dEndLong - dBeginLong)*60 * cos(DTOR((dEndLat + dBeginLat)/2.0)) / sin(DTOR(dOrient)) * 1.852;  		
		}
		else                                  // 中分纬度 (acos((dEndLat - dBeginLat)*60/DMP)) 
		{
			dDist = (dEndLong - dBeginLong)*60 * cos(acos((dEndLat - dBeginLat)*60/DMP)) / sin(DTOR(dOrient)) * 1.852;
		}
	}

}


// 功  能:判断航向是否接近90/270
// 输入值:航向
// 返回值:是否接近90/270度标志
BOOL CCoordinateConv::IsNearRightAngle(double dOrient)
{
	BOOL bNewRightAngle = FALSE;
	// 确保dOrient在[0,360]
	if(dOrient < 0)
	{
		AfxMessageBox("航向/方位角为负值,请转化成[0 360]之间");
		dOrient = 360 + int(dOrient)%360 + (dOrient - int(dOrient));
	}
	if(dOrient > 360)
	{
		AfxMessageBox("航向/方位角为大于360,请转化成[0 360]之间");	
		dOrient = (int)dOrient%360 + (dOrient - int(dOrient));
	}

	// 判断是否接近90/270
	double Angle = (int)dOrient%180;
	if((Angle > 80) && (Angle < 100) )
	{
		bNewRightAngle = TRUE;
	}
	else
	{
		bNewRightAngle = FALSE;
	}

	return bNewRightAngle;		
}





















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -