|
|
// DlgLightRegion.cpp : 实现文件
|
|
|
//
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
#include "DlgLightRegion.h"
|
|
|
#include "afxdialogex.h"
|
|
|
|
|
|
#include "MapElevation.h"
|
|
|
#include<io.h>
|
|
|
|
|
|
MapElevation m_mapElevation2;
|
|
|
|
|
|
HWND g_hwndDlgLight = nullptr;
|
|
|
|
|
|
//计算地球上两点间的斜率(假定地球是圆的)
|
|
|
double CalSlopeBetweenTwoPoint(const double fromPtLon, const double fromPtLat, const float fromPtAlt, const double endPtLon, const double endPtLat, const float endPtAlt)
|
|
|
{
|
|
|
double _distance = 0.0;
|
|
|
CalculateTwoPtsDistance(_distance,fromPtLon,fromPtLat,endPtLon,endPtLat,3);
|
|
|
|
|
|
//考虑大气折射等原因,地球半径乘以系数4/3,作为等效半径
|
|
|
double _radiusEarth = 6371137.0 * 4/3;
|
|
|
|
|
|
//求解两点在地球表面的投影点连成的弧线对应的圆心角,单位为弧度
|
|
|
double _centralAngle = _distance/_radiusEarth;
|
|
|
|
|
|
double _slope = 0.0,d1 = 0.0, d2 = 0.0;
|
|
|
|
|
|
//从起始点处水平看向终点处,能看到的终点的高度
|
|
|
double _compareAlt = ((_radiusEarth + fromPtAlt)/cos(_centralAngle) - _radiusEarth);
|
|
|
|
|
|
//斜率为正
|
|
|
if ( _compareAlt < endPtAlt)
|
|
|
{
|
|
|
_compareAlt = endPtAlt - _compareAlt;
|
|
|
|
|
|
d1 = _compareAlt * cos(_centralAngle);
|
|
|
|
|
|
d2 = (_radiusEarth + fromPtAlt) * tan(_centralAngle) + _compareAlt * sin(_centralAngle);
|
|
|
|
|
|
_slope = d1/d2;
|
|
|
}
|
|
|
else //斜率为负
|
|
|
{
|
|
|
_compareAlt = _compareAlt - endPtAlt;
|
|
|
|
|
|
d1 = _compareAlt * cos(_centralAngle);
|
|
|
|
|
|
d2 = (_radiusEarth + fromPtAlt) * tan(_centralAngle) - _compareAlt * sin(_centralAngle);
|
|
|
|
|
|
_slope = -d1/d2;
|
|
|
}
|
|
|
|
|
|
return _slope;
|
|
|
}
|
|
|
|
|
|
//已知地球A点经纬度高,以及B点和A点连线相对于水平方向的斜率,求B点的高度
|
|
|
double CalAltFromSlope(const double fromPtLon, const double fromPtLat, const float fromPtAlt, const double endPtLon, const double endPtLat,const double slope)
|
|
|
{
|
|
|
double _distance = 0.0;
|
|
|
CalculateTwoPtsDistance(_distance,fromPtLon,fromPtLat,endPtLon,endPtLat,3);
|
|
|
|
|
|
//考虑大气折射等原因,地球半径乘以系数4/3,作为等效半径
|
|
|
double _radiusEarth = 6371137.0 * 4/3;
|
|
|
|
|
|
//求解两点在地球表面的投影点连成的弧线对应的圆心角,单位为弧度
|
|
|
double _centralAngle = _distance/_radiusEarth;
|
|
|
|
|
|
double endPtAlt = 0.0;
|
|
|
|
|
|
if (slope > 0.0)
|
|
|
{
|
|
|
endPtAlt = (_radiusEarth + fromPtAlt) * tan(_centralAngle) * slope / (cos(_centralAngle)-(sin(_centralAngle)*slope));
|
|
|
|
|
|
endPtAlt = ((_radiusEarth + fromPtAlt)/cos(_centralAngle) - _radiusEarth) + endPtAlt;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
endPtAlt = (_radiusEarth + fromPtAlt) * tan(_centralAngle) * (-slope) / (cos(_centralAngle)+(sin(_centralAngle)*(-slope)));
|
|
|
endPtAlt = ((_radiusEarth + fromPtAlt)/cos(_centralAngle) - _radiusEarth) - endPtAlt;
|
|
|
}
|
|
|
|
|
|
return endPtAlt;
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:可视域分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//可视域分析线程开启标志
|
|
|
volatile bool m_bRunRegion = false;
|
|
|
|
|
|
double g_dGroundLonTemp = 0.0; //地面站经度
|
|
|
double g_dGroundLatTemp = 0.0; //地面站纬度
|
|
|
float g_fGroundAltTemp = 0.0; //地面站高度
|
|
|
int g_iFlightAlt = 0; //飞行高度
|
|
|
int g_iRegionRadius = 0; //分析半径
|
|
|
int g_iAnalysisStep = 0; //分析角度
|
|
|
|
|
|
//线程函数,处理可视域分析
|
|
|
void ThreadFuncLightRegion()
|
|
|
{
|
|
|
while(m_bRunRegion)
|
|
|
{
|
|
|
//依次完成地面站0~360度方向的通视分析,每执行一次,分析1度
|
|
|
if ((g_iAnalysisStep >= 0) && (g_iAnalysisStep < 360))
|
|
|
{
|
|
|
if (false == AnalysisLightRegion(g_iAnalysisStep,g_iRegionRadius))
|
|
|
{
|
|
|
//高程信息不全,终止分析
|
|
|
g_iAnalysisStep = -1;
|
|
|
|
|
|
m_bRunRegion = false;
|
|
|
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)1,(LPARAM)-1);
|
|
|
|
|
|
continue ;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//发送消息到对话框,更新可视域分析进度
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)1,(LPARAM)g_iAnalysisStep);
|
|
|
}
|
|
|
|
|
|
g_iAnalysisStep++;
|
|
|
}
|
|
|
else if (360 == g_iAnalysisStep)
|
|
|
{
|
|
|
//终止分析
|
|
|
g_iAnalysisStep = -1;
|
|
|
|
|
|
g_structPointNotVisible[360] = g_structPointNotVisible[0];
|
|
|
|
|
|
//通视分析后,需要将最外侧的圆逆时针逐个加入不可视区域图层,这样才能形成一个闭合的不可视区域
|
|
|
for (int i=360;i>=0;i--)
|
|
|
{
|
|
|
structPoint _structPoint;
|
|
|
CalculatePtCoordinate(_structPoint.lon,_structPoint.lat,g_dGroundLonTemp,g_dGroundLatTemp,i,g_iRegionRadius*1000,3);
|
|
|
|
|
|
g_structPointNotVisible[720 - i + 1] = _structPoint;
|
|
|
}
|
|
|
|
|
|
//发送到地图,绘制可视域
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_NOTVISIBLE,0,0);
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_ISVISIBLE,0,0);
|
|
|
|
|
|
m_bRunRegion = false;
|
|
|
}
|
|
|
|
|
|
Sleep(10);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//给定飞行高度,进行通视分析并在地图上标绘可视域,iAngle 角度,iRadius 距离
|
|
|
bool AnalysisLightRegion(int iAngle, int iRadius)
|
|
|
{
|
|
|
double dTanMaxAngle = 0.0; //最小通视角度
|
|
|
double fMinLightAlt = 0.0; //最小通视高度
|
|
|
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//中间变量
|
|
|
double _tempAngle = 0.0; //当前点与地面站的连线 与水平方向的夹角
|
|
|
structPoint _structPoint;
|
|
|
|
|
|
//以60为采样间距,计算插值个数
|
|
|
int interPolDis = 60;
|
|
|
int interPolNum = (iRadius*1000)/interPolDis;
|
|
|
|
|
|
for(int i = 1; i <= interPolNum; i++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, g_dGroundLonTemp, g_dGroundLatTemp, iAngle, i*interPolDis, 3);
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
_tempAngle = CalSlopeBetweenTwoPoint(g_dGroundLonTemp, g_dGroundLatTemp, g_fGroundAltTemp, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
dTanMaxAngle = max(_tempAngle,dTanMaxAngle);
|
|
|
|
|
|
fMinLightAlt = (float)CalAltFromSlope(g_dGroundLonTemp, g_dGroundLatTemp, g_fGroundAltTemp, interPolLon, interPolLat, dTanMaxAngle);
|
|
|
|
|
|
//给定飞行高度,判断是否可通视,若遇到第一个不通视的点,认为此点是通视与不通视的分割点,直接返回
|
|
|
if (g_iFlightAlt < fMinLightAlt)
|
|
|
{
|
|
|
_structPoint.lon = interPolLon;
|
|
|
_structPoint.lat = interPolLat;
|
|
|
|
|
|
g_structPointVisible[iAngle] = _structPoint;
|
|
|
g_structPointNotVisible[iAngle] = _structPoint;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
CalculatePtCoordinate(_structPoint.lon,_structPoint.lat,g_dGroundLonTemp,g_dGroundLatTemp,iAngle,g_iRegionRadius*1000,3);
|
|
|
|
|
|
g_structPointVisible[iAngle] = _structPoint;
|
|
|
g_structPointNotVisible[iAngle] = _structPoint;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时通视检测
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//实时通视检测线程开启标志
|
|
|
volatile bool m_bRunDetect = false;
|
|
|
|
|
|
double g_dRealTime_GCSlon = 0.0; //地面站经度
|
|
|
double g_dRealTime_GCSlat = 0.0; //地面站纬度
|
|
|
float g_fRealTime_GCSalt = 0.0f; //地面站高度
|
|
|
double g_dRealTime_UavAlt = 0.0; //无人机高度
|
|
|
double g_dRealTime_AngToGCS = 0.0; //地面站-飞机方位
|
|
|
double g_dRealTime_DisToGCS = 0.0; //地面站-飞机距离
|
|
|
double g_dRealTime_MinAngle = 0.0;
|
|
|
double g_dRealTime_AngleDiff = 0.0;
|
|
|
int g_iRealTime_CurStep = -1;
|
|
|
int g_iPointNumInLayer = 0; //实时通视检测中分析的点数
|
|
|
|
|
|
//线程函数,处理实时通视检测
|
|
|
void ThreadFuncRealTimeDetection()
|
|
|
{
|
|
|
while(m_bRunDetect)
|
|
|
{
|
|
|
if (-1 == g_iRealTime_CurStep)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (g_iRealTime_CurStep <= 12)
|
|
|
{
|
|
|
if (false == AnalysisVisiArea(g_dRealTime_UavAlt, g_dRealTime_MinAngle+g_iRealTime_CurStep*g_dRealTime_AngleDiff, g_dRealTime_DisToGCS-3000, g_dRealTime_DisToGCS+3000, g_dRealTime_GCSlon, g_dRealTime_GCSlat))
|
|
|
{
|
|
|
g_iRealTime_CurStep = -1;
|
|
|
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)2,(LPARAM)-1);
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
g_iRealTime_CurStep++;
|
|
|
}
|
|
|
|
|
|
if (g_iRealTime_CurStep == (12 + 1))
|
|
|
{
|
|
|
g_iRealTime_CurStep++;
|
|
|
}
|
|
|
|
|
|
if (g_iRealTime_CurStep == (12 + 2))
|
|
|
{
|
|
|
for (int i=0; i<=12;i++)
|
|
|
{
|
|
|
g_iPointNumInLayer++;
|
|
|
|
|
|
structPoint _structPoint;
|
|
|
|
|
|
CalculatePtCoordinate(_structPoint.lon, _structPoint.lat, g_dRealTime_GCSlon, g_dRealTime_GCSlat, g_dRealTime_MinAngle+(12-i)*g_dRealTime_AngleDiff, g_dRealTime_DisToGCS-3000, 3);
|
|
|
|
|
|
//插入可视图层
|
|
|
g_structPointVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
|
|
|
CalculatePtCoordinate(_structPoint.lon, _structPoint.lat, g_dRealTime_GCSlon, g_dRealTime_GCSlat, g_dRealTime_MinAngle+(12-i)*g_dRealTime_AngleDiff, g_dRealTime_DisToGCS+3000, 3);
|
|
|
|
|
|
//插入不可视图层
|
|
|
g_structPointNotVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
}
|
|
|
|
|
|
g_iRealTime_CurStep++;
|
|
|
}
|
|
|
|
|
|
if (g_iRealTime_CurStep == (12 + 3))
|
|
|
{
|
|
|
//清除实时可视域绘制图层
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_VISI_DELETE,0,0);
|
|
|
|
|
|
//绘制实时不可视域图层
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_NOTVISI_REALTIME,(WPARAM)g_iPointNumInLayer,0);
|
|
|
|
|
|
g_iRealTime_CurStep++;
|
|
|
}
|
|
|
|
|
|
if (g_iRealTime_CurStep == (12 + 4))
|
|
|
{
|
|
|
//绘制实时可视域图层
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_VISI_REALTIME,(WPARAM)g_iPointNumInLayer,0);
|
|
|
|
|
|
g_iRealTime_CurStep = -1;
|
|
|
}
|
|
|
|
|
|
Sleep(10);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//给定角度和距离范围,进行通视检测
|
|
|
bool AnalysisVisiArea(double uavAlt, double dAngle, double dDistanceMin, double dDistanceMax, double lonGCS, double latGCS)
|
|
|
{
|
|
|
double dTanMaxAngle = 0.0; //最小通视角度
|
|
|
double fMinLightAlt = 0.0; //最小通视高度
|
|
|
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//中间变量
|
|
|
double _tempAngle = 0.0; //当前点与地面站的连线 与水平方向的夹角
|
|
|
structPoint _structPoint;
|
|
|
|
|
|
//以30为采样间距,计算插值个数
|
|
|
int interPolDis = 30;
|
|
|
int interPolNum = (int)(floor((double)(dDistanceMax/interPolDis)));
|
|
|
|
|
|
for(int i = 1; i <= interPolNum; i++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, lonGCS, latGCS, dAngle, i*interPolDis, 3);
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
_tempAngle = CalSlopeBetweenTwoPoint(lonGCS, latGCS, g_fRealTime_GCSalt, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
dTanMaxAngle = max(_tempAngle,dTanMaxAngle);
|
|
|
|
|
|
fMinLightAlt = (float)CalAltFromSlope(lonGCS, latGCS, g_fRealTime_GCSalt, interPolLon, interPolLat, dTanMaxAngle);
|
|
|
|
|
|
//给定飞行高度,判断是否可通视,若遇到第一个不通视的点,认为此点是通视与不通视的分割点,直接返回
|
|
|
if (uavAlt < fMinLightAlt)
|
|
|
{
|
|
|
if ((i*interPolDis) < dDistanceMin)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, lonGCS, latGCS, dAngle, dDistanceMin, 3);
|
|
|
|
|
|
_structPoint.lon = interPolLon;
|
|
|
_structPoint.lat = interPolLat;
|
|
|
|
|
|
//插入可视与不可视图层
|
|
|
g_iPointNumInLayer++;
|
|
|
g_structPointVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
g_structPointNotVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_structPoint.lon = interPolLon;
|
|
|
_structPoint.lat = interPolLat;
|
|
|
|
|
|
//插入可视与不可视图层
|
|
|
g_iPointNumInLayer++;
|
|
|
g_structPointVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
g_structPointNotVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, lonGCS, latGCS, dAngle, dDistanceMax, 3);
|
|
|
|
|
|
_structPoint.lon = interPolLon;
|
|
|
_structPoint.lat = interPolLat;
|
|
|
|
|
|
//插入可视与不可视图层
|
|
|
g_iPointNumInLayer++;
|
|
|
g_structPointVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
g_structPointNotVisiReal[g_iPointNumInLayer] = _structPoint;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时碰撞检测
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//实时碰撞检测线程开启标志
|
|
|
volatile bool m_bRunCrash = false;
|
|
|
|
|
|
bool g_bCrashDetection = false;
|
|
|
double g_dCrashUavLon = 0.0;
|
|
|
double g_dCrashUavLat = 0.0;
|
|
|
float g_fCrashUavAlt = 0.0f;
|
|
|
|
|
|
//线程函数,处理实时碰撞检测
|
|
|
void ThreadFuncRealTimeCrash()
|
|
|
{
|
|
|
while(m_bRunCrash)
|
|
|
{
|
|
|
if (true == g_bCrashDetection)
|
|
|
{
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//0到360方向,依次分析飞机半径为3km内的高程信息
|
|
|
for (int i=0;i<360;i++)
|
|
|
{
|
|
|
for (int j=0;j<=20;j++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, g_dCrashUavLon, g_dCrashUavLat, i, j*150, 3);
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
g_bCrashDetection = false;
|
|
|
m_bRunCrash = false;
|
|
|
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if ((20 == j) || (interPolHight > (g_fCrashUavAlt - 200))) //200米为考虑GPS高度与DEM高程差等之后给出的余量
|
|
|
{
|
|
|
g_structPointCrashReal[i].lon = interPolLon;
|
|
|
g_structPointCrashReal[i].lat = interPolLat;
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//为避免关闭线程时,线程内语句尚未执行完,从而停止检测后,依然会执行到此处
|
|
|
if (true == g_bCrashDetection)
|
|
|
{
|
|
|
//绘制碰撞检测后的结果
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_CRASH_REALTIME,1,0);
|
|
|
|
|
|
g_bCrashDetection = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:航线通视分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//航线通视分析线程开启标志
|
|
|
volatile bool m_bRunRoute = false;
|
|
|
|
|
|
double g_dRoute_GCSlon = 0.0; //地面站经度
|
|
|
double g_dRoute_GCSlat = 0.0; //地面站纬度
|
|
|
float g_fRoute_GCSalt = 0.0f; //地面站高度
|
|
|
|
|
|
#pragma pack(1)
|
|
|
typedef struct _PTSTRUCT
|
|
|
{
|
|
|
unsigned char/*BYTE*/ lineID; //航线号
|
|
|
unsigned char/*BYTE*/ ptID; //航点号
|
|
|
|
|
|
double lon; //经度
|
|
|
double lat; //纬度
|
|
|
short alt; //高度
|
|
|
|
|
|
unsigned char/*BYTE*/ speed; //速度
|
|
|
|
|
|
char taskCharacter; //任务特征字
|
|
|
char lineCharacter; //航路特征字
|
|
|
|
|
|
}PtStruct;
|
|
|
#pragma pack()
|
|
|
|
|
|
PtStruct pts[257]; //航线的航线信息
|
|
|
int g_iWayPointNum; //航线的航点个数
|
|
|
int g_iCurWaypoint; //当前在分析的航点号
|
|
|
|
|
|
int g_iTotalInterNum = 0; //航线中的插值总点数
|
|
|
int g_totalLinePtNum; //航线中已分析的插值点数
|
|
|
|
|
|
int g_iInterNumSec = 0; //航段中的插值点数
|
|
|
|
|
|
double *g_ptrArraySeries1 = nullptr; //航线上各点的高程值
|
|
|
double *g_ptrArraySeries2 = nullptr; //航线上各点的最小通视高度
|
|
|
int *g_ptrArraySeries3 = nullptr; //航点所设置的高度
|
|
|
|
|
|
//线程函数,处理航线通视分析
|
|
|
void ThreadFuncAnalysisRoute()
|
|
|
{
|
|
|
while (m_bRunRoute)
|
|
|
{
|
|
|
for (int i=0;i<(g_iWayPointNum-1);i++)
|
|
|
{
|
|
|
//航点高程
|
|
|
g_ptrArraySeries3[i] = g_totalLinePtNum;
|
|
|
|
|
|
double _dLineSecDis, _dLineSecDir; //航段两点的距离和方向
|
|
|
|
|
|
//计算航段起点和终点的水平距离和方位角
|
|
|
CalculateTwoPtsDistanceAzimuth(_dLineSecDis, _dLineSecDir, pts[i].lon, pts[i].lat, pts[i+1].lon,pts[i+1].lat, 3);
|
|
|
|
|
|
//以100米为间距,计算插值个数
|
|
|
g_iInterNumSec = (int)(floor(_dLineSecDis/100));
|
|
|
|
|
|
for (int j=0;j<=g_iInterNumSec;j++)
|
|
|
{
|
|
|
//插值点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, pts[i].lon, pts[i].lat, _dLineSecDir, j*100, 3);
|
|
|
|
|
|
//获取插值点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)3,(LPARAM)-1);
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunRoute = false;
|
|
|
|
|
|
g_iInterNumSec = 0;
|
|
|
g_iWayPointNum = 0;
|
|
|
g_iCurWaypoint = 0;
|
|
|
g_iTotalInterNum = 0;
|
|
|
g_totalLinePtNum = 0;
|
|
|
|
|
|
continue ;
|
|
|
}
|
|
|
g_ptrArraySeries1[g_totalLinePtNum] = interPolHight;
|
|
|
|
|
|
//获取最小通视高度
|
|
|
float _minVisiAlt = CalculateVisibleAlt(interPolLon, interPolLat);
|
|
|
if (_minVisiAlt > 0.1f)
|
|
|
{
|
|
|
g_ptrArraySeries2[g_totalLinePtNum] = _minVisiAlt;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunRoute = false;
|
|
|
|
|
|
g_iInterNumSec = 0;
|
|
|
g_iWayPointNum = 0;
|
|
|
g_iCurWaypoint = 0;
|
|
|
g_iTotalInterNum = 0;
|
|
|
g_totalLinePtNum = 0;
|
|
|
|
|
|
continue ;
|
|
|
}
|
|
|
|
|
|
g_totalLinePtNum++;
|
|
|
|
|
|
//发送消息到对话框,更新分析进度
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)3,(LPARAM)1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (true == m_bRunRoute)
|
|
|
{
|
|
|
//航点高程
|
|
|
g_ptrArraySeries3[g_iWayPointNum-1] = g_totalLinePtNum-1;
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunRoute = false;
|
|
|
|
|
|
//完成航线分析,发送消息到对话框,绘制分析结果,并提示分析完成
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)3,(LPARAM)-2);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//给定某点的经度、纬度,计算该点相对于地面站的最小通视高度
|
|
|
float CalculateVisibleAlt(const double& lon, const double& lat)
|
|
|
{
|
|
|
//计算两个点间的水平距离和方位角
|
|
|
double dis = 0.0, angle = 0.0;
|
|
|
CalculateTwoPtsDistanceAzimuth(dis, angle, g_dRoute_GCSlon, g_dRoute_GCSlat, lon, lat, 3);
|
|
|
|
|
|
//以30米为间距,计算插值个数
|
|
|
int interPolDis = 30;
|
|
|
int interPolNum = (int)floor(dis/interPolDis);
|
|
|
|
|
|
//插值点位置计算
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
double _dTanMaxAngle = 0.0;
|
|
|
float _fMinLightAlt = 0.0f;
|
|
|
|
|
|
double _tempAngle = 0.0;
|
|
|
|
|
|
for(int i = 1; i <= interPolNum; i++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, g_dRoute_GCSlon, g_dRoute_GCSlat, angle, i*interPolDis, 3);
|
|
|
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)3,(LPARAM)-1);
|
|
|
|
|
|
return 0.0f;
|
|
|
}
|
|
|
|
|
|
_tempAngle = CalSlopeBetweenTwoPoint(g_dRoute_GCSlon, g_dRoute_GCSlat, g_fRoute_GCSalt, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
_dTanMaxAngle = max(_tempAngle,_dTanMaxAngle);
|
|
|
|
|
|
_fMinLightAlt = (float)CalAltFromSlope(g_dRoute_GCSlon, g_dRoute_GCSlat, g_fRoute_GCSalt, interPolLon, interPolLat, _dTanMaxAngle);
|
|
|
}
|
|
|
|
|
|
return _fMinLightAlt;
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时视线通视分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//实时视线通视分析线程开启标志
|
|
|
volatile bool m_bRunRealTimeLOS = false;
|
|
|
|
|
|
bool g_bHandlingLOS = false;
|
|
|
|
|
|
double *g_ptrArrayLight1 = nullptr;
|
|
|
double *g_ptrArrayLight2 = nullptr;
|
|
|
int g_iTotalAnalyNum = 0;
|
|
|
|
|
|
double g_dLightGCSlon; //地面站经度
|
|
|
double g_dLightGCSlat; //地面站纬度
|
|
|
float g_fLightGCSAlt; //地面站高度(地面站处的高程加上方舱高度)
|
|
|
double g_dLightAngle; //地面站-飞机方位
|
|
|
double g_dLightDis; //地面站-飞机距离
|
|
|
|
|
|
double g_dLightUavAlt; //飞机高度
|
|
|
float g_fUavLosAlt; //飞机距离处的通视高度
|
|
|
|
|
|
//线程函数,处理实时视线通视分析
|
|
|
void ThreadFuncAnalysisLOS()
|
|
|
{
|
|
|
while(m_bRunRealTimeLOS)
|
|
|
{
|
|
|
if (true == g_bHandlingLOS)
|
|
|
{
|
|
|
//插值点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0f;
|
|
|
|
|
|
g_iTotalAnalyNum = (int)(g_dLightDis/30);
|
|
|
|
|
|
if (g_ptrArrayLight1 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArrayLight1;
|
|
|
g_ptrArrayLight1 = nullptr;
|
|
|
}
|
|
|
|
|
|
g_ptrArrayLight1 = new double[g_iTotalAnalyNum + 1];
|
|
|
g_ptrArrayLight2 = new double[g_iTotalAnalyNum + 1];
|
|
|
|
|
|
memset(g_ptrArrayLight1, 0, sizeof(double) * (g_iTotalAnalyNum + 1));
|
|
|
memset(g_ptrArrayLight2, 0, sizeof(double) * (g_iTotalAnalyNum + 1));
|
|
|
|
|
|
g_ptrArrayLight1[0] = g_fLightGCSAlt;
|
|
|
g_ptrArrayLight2[0] = g_fLightGCSAlt;
|
|
|
|
|
|
double _dTanMaxSlope = -1000.0; //最大斜率
|
|
|
float _fMinLOSAlt = 0.0; //最小通视高度
|
|
|
double _tempSlope = 0.0; //当前点与地面站的连线的斜率
|
|
|
|
|
|
for (int i=1;i<=g_iTotalAnalyNum;i++)
|
|
|
{
|
|
|
//获取插值点经纬度
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, g_dLightGCSlon, g_dLightGCSlat, g_dLightAngle, i*30, 3);
|
|
|
|
|
|
//获取插值点高程值
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)4,(LPARAM)-1);
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunRealTimeLOS = false;
|
|
|
|
|
|
continue ;
|
|
|
}
|
|
|
g_ptrArrayLight1[i] = interPolHight;
|
|
|
|
|
|
_tempSlope = CalSlopeBetweenTwoPoint(g_dLightGCSlon, g_dLightGCSlat, g_fLightGCSAlt, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
//若当前点-地面站的斜率,小于之前所有点中的最大值,则当前点-地面站可以通视的斜率取最大值
|
|
|
_dTanMaxSlope = max(_tempSlope,_dTanMaxSlope);
|
|
|
|
|
|
//计算当前插值点可以通视的最小高度
|
|
|
_fMinLOSAlt = (float)CalAltFromSlope(g_dLightGCSlon, g_dLightGCSlat, g_fLightGCSAlt, interPolLon, interPolLat, _dTanMaxSlope);
|
|
|
|
|
|
g_ptrArrayLight2[i] = _fMinLOSAlt;
|
|
|
}
|
|
|
|
|
|
g_fUavLosAlt = _fMinLOSAlt;
|
|
|
|
|
|
//完成实时通视分析,发送消息到对话框,绘制分析结果
|
|
|
::SendMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)4,(LPARAM)-2);
|
|
|
|
|
|
g_bHandlingLOS = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:通视等高线分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
//通视等高线分析线程开启标志
|
|
|
volatile bool m_bRunContour = false;
|
|
|
|
|
|
double g_dGroundLonCountour = 0.0; //地面站经度
|
|
|
double g_dGroundLatCountour = 0.0; //地面站纬度
|
|
|
float g_fGroundAltCountour = 0.0; //地面站高度
|
|
|
|
|
|
float g_fLastLightAlt = 0.0f;
|
|
|
|
|
|
int g_iMaxLosAlt = 8000;
|
|
|
|
|
|
//线程函数,处理通视等高线分析
|
|
|
void ThreadFuncAnalysisContour()
|
|
|
{
|
|
|
while (m_bRunContour)
|
|
|
{
|
|
|
for (int i=0;i<360;i++)
|
|
|
{
|
|
|
g_fLastLightAlt = g_fGroundAltCountour;
|
|
|
|
|
|
if (false == AnalysisContourLine(i))
|
|
|
{
|
|
|
//发送消息到对话框,提示高程信息不全
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)5,(LPARAM)-1);
|
|
|
|
|
|
//终止线程
|
|
|
m_bRunContour = false;
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//发送消息到对话框,提示进度
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)5,(LPARAM)i);
|
|
|
}
|
|
|
|
|
|
//线程已终止
|
|
|
if (false == m_bRunContour)
|
|
|
{
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)5,(LPARAM)-3);
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (true == m_bRunContour)
|
|
|
{
|
|
|
//发送消息到对话框,提示分析完成
|
|
|
::PostMessage(g_hwndDlgLight,WM_SEND_UPDATEDIALOG,(WPARAM)5,(LPARAM)-2);
|
|
|
|
|
|
//终止线程
|
|
|
m_bRunContour = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//通视等高线分析并在地图上标绘等高线,iAngle 角度
|
|
|
bool AnalysisContourLine(int iAngle)
|
|
|
{
|
|
|
double _dTanMaxAngle = 0.0; //最小通视角度
|
|
|
float _fMinLightAlt = 0.0; //最小通视高度
|
|
|
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//中间变量
|
|
|
double _tempAngle = 0.0; //当前点与地面站的连线 与水平方向的夹角
|
|
|
|
|
|
int _iStep = 1;
|
|
|
|
|
|
while (_fMinLightAlt < g_iMaxLosAlt)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, g_dGroundLonCountour, g_dGroundLatCountour, iAngle, _iStep*30, 3); //30为采样间距
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
_tempAngle = CalSlopeBetweenTwoPoint(g_dGroundLonCountour, g_dGroundLatCountour, g_fGroundAltCountour, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
_dTanMaxAngle = max(_tempAngle,_dTanMaxAngle);
|
|
|
|
|
|
_fMinLightAlt = (float)CalAltFromSlope(g_dGroundLonCountour, g_dGroundLatCountour, g_fGroundAltCountour, interPolLon, interPolLat, _dTanMaxAngle);
|
|
|
|
|
|
if (true == m_bRunContour)
|
|
|
{
|
|
|
//添加点到通视等高线图层
|
|
|
InsertPtToContourLine(_fMinLightAlt, interPolLon, interPolLat);
|
|
|
}
|
|
|
|
|
|
_iStep++;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//添加点到通视等高线图层
|
|
|
void InsertPtToContourLine(float _fLightAlt, double _dPtLon, double _dPtLat)
|
|
|
{
|
|
|
for (int i = 1;i<=20;i++)
|
|
|
{
|
|
|
if ((g_fLastLightAlt < (500*i)) && (_fLightAlt > (500*i)))
|
|
|
{
|
|
|
structPoint _pt;
|
|
|
_pt.lon = _dPtLon;
|
|
|
_pt.lat = _dPtLat;
|
|
|
|
|
|
//添加点到通视等高线图层
|
|
|
::SendMessage(g_mapHwnd,WM_ADD_LINELAYER,WPARAM(&_pt),LPARAM(i));
|
|
|
|
|
|
g_fLastLightAlt = _fLightAlt;
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// CDlgLightRegion 对话框
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CDlgLightRegion, CBCGPDialog)
|
|
|
|
|
|
CDlgLightRegion::CDlgLightRegion(CWnd* pParent /*=NULL*/)
|
|
|
: CBCGPDialog(CDlgLightRegion::IDD, pParent)
|
|
|
{
|
|
|
EnableVisualManagerStyle(TRUE, TRUE);
|
|
|
|
|
|
m_dGroundLon = 107.4203869;
|
|
|
m_dGroundLat = 37.8544731;
|
|
|
m_fGroudAlt = 0.0f;
|
|
|
m_dCabinHgt = 4.0;
|
|
|
|
|
|
m_iFlightAlt = 3500;
|
|
|
m_iRegionRadius = 30;
|
|
|
|
|
|
m_bRTlight = FALSE;
|
|
|
|
|
|
m_pLine1 = nullptr;
|
|
|
m_strokeStyle.SetDashStyle(CBCGPStrokeStyle::BCGP_DASH_STYLE_DOT);
|
|
|
|
|
|
m_pTextTip = nullptr;
|
|
|
|
|
|
m_bRealTime_Visi = FALSE;
|
|
|
m_bRealTime_Crash = FALSE;
|
|
|
m_iMaxLosAlt = 8000;
|
|
|
m_iFightRegion = 280;
|
|
|
}
|
|
|
|
|
|
CDlgLightRegion::~CDlgLightRegion()
|
|
|
{
|
|
|
m_bRunRegion = false;
|
|
|
m_bRunDetect = false;
|
|
|
m_bRunRoute = false;
|
|
|
m_bRunRealTimeLOS = false;
|
|
|
m_bRunCrash = false;
|
|
|
|
|
|
if (g_ptrArraySeries1 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries1;
|
|
|
g_ptrArraySeries1 = nullptr;
|
|
|
}
|
|
|
|
|
|
if (g_ptrArraySeries2 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries2;
|
|
|
g_ptrArraySeries2 = nullptr;
|
|
|
}
|
|
|
|
|
|
if (g_ptrArraySeries3 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries3;
|
|
|
g_ptrArraySeries3 = nullptr;
|
|
|
}
|
|
|
|
|
|
if (g_ptrArrayLight1 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArrayLight1;
|
|
|
g_ptrArrayLight1 = nullptr;
|
|
|
}
|
|
|
|
|
|
if (g_ptrArrayLight2 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArrayLight2;
|
|
|
g_ptrArrayLight2 = nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CDlgLightRegion::DoDataExchange(CDataExchange* pDX)
|
|
|
{
|
|
|
CBCGPDialog::DoDataExchange(pDX);
|
|
|
DDX_Control(pDX, IDC_CONTAINER_ALTCHART, m_wndChart);
|
|
|
DDX_Text(pDX, IDC_EDIT_GROUND_LON, m_dGroundLon);
|
|
|
DDX_Text(pDX, IDC_EDIT_GROUND_LAT, m_dGroundLat);
|
|
|
DDX_Text(pDX, IDC_EDIT_BASEALT, m_iFlightAlt);
|
|
|
DDX_Text(pDX, IDC_EDIT_REGIONRADIUS, m_iRegionRadius);
|
|
|
DDX_Check(pDX, IDC_CHECK_REALTIME, m_bRealTime_Visi);
|
|
|
DDX_Check(pDX, IDC_CHECK_RT_DETECTION, m_bRealTime_Crash);
|
|
|
DDX_Text(pDX, IDC_EDIT_CABINALT, m_dCabinHgt);
|
|
|
DDX_Check(pDX, IDC_CHECK_RT_LIGHT, m_bRTlight);
|
|
|
DDX_Control(pDX, IDC_GAUGE_PROMPT_LINE, m_LineTextContainer);
|
|
|
DDX_Control(pDX, IDC_GAUGE_PROMPT_REGION, m_RegionTextContainer);
|
|
|
DDX_Control(pDX, IDC_GAUGE_PROMPT_CONTOUR, m_ContourTextContainer);
|
|
|
DDX_Text(pDX, IDC_EDIT_MAXLOSALT, m_iMaxLosAlt);
|
|
|
DDX_Text(pDX, IDC_EDIT_FIGHTRADIUS, m_iFightRegion);
|
|
|
DDV_MinMaxInt(pDX, m_iFightRegion, 0, 500);
|
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgLightRegion, CBCGPDialog)
|
|
|
ON_WM_TIMER()
|
|
|
ON_WM_SIZE()
|
|
|
ON_BN_CLICKED(IDC_BUTTON_DRAWPOINT, &CDlgLightRegion::OnBnClickedButtonDrawPoint)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_REGIONANAYLSIS, &CDlgLightRegion::OnBnClickedButtonRegionAnaylsis)
|
|
|
ON_BN_CLICKED(IDC_CHECK_REALTIME, &CDlgLightRegion::OnBnClickedCheckRealtime)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_REGIONDELETE, &CDlgLightRegion::OnBnClickedButtonRegionDelete)
|
|
|
ON_BN_CLICKED(IDC_CHECK_RT_LIGHT, &CDlgLightRegion::OnBnClickedCheckRtLight)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_LOADROUTE, &CDlgLightRegion::OnBnClickedButtonLoadRoute)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_SAVEIMAGE, &CDlgLightRegion::OnBnClickedButtonSaveImage)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_STOPROUTE, &CDlgLightRegion::OnBnClickedButtonStopRoute)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_CONTOURLINE, &CDlgLightRegion::OnBnClickedButtonContourline)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_CONTOURDELETE, &CDlgLightRegion::OnBnClickedButtonContourDelete)
|
|
|
ON_MESSAGE(WM_SEND_UPDATEDIALOG, &CDlgLightRegion::OnSendUpdateDialog)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_SELECTPTINMAP, &CDlgLightRegion::OnBnClickedButtonSelectPtInMap)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_CLEARLINELAYER, &CDlgLightRegion::OnBnClickedButtonClearLineLayer)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_GETALTVALUE, &CDlgLightRegion::OnBnClickedButtonGetAltValue)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_REVERSE, &CDlgLightRegion::OnBnClickedButtonReverse)
|
|
|
ON_REGISTERED_MESSAGE(BCGM_ON_CHART_MOUSE_DOWN, OnMouseDown)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_CLEARRESULT, &CDlgLightRegion::OnBnClickedButtonClearResult)
|
|
|
ON_BN_CLICKED(IDC_CHECK_RT_DETECTION, &CDlgLightRegion::OnBnClickedCheckRtDetection)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_DRAWFIGHT, &CDlgLightRegion::OnBnClickedButtonDrawFight)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_DELETEFIGHT, &CDlgLightRegion::OnBnClickedButtonDeleteFight)
|
|
|
ON_BN_CLICKED(IDC_BUTTON_GETDEMREGION, &CDlgLightRegion::OnBnClickedButtonGetDemRegion)
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// CDlgLightRegion 消息处理程序
|
|
|
|
|
|
BOOL CDlgLightRegion::OnInitDialog()
|
|
|
{
|
|
|
CBCGPDialog::OnInitDialog();
|
|
|
|
|
|
g_hwndDlgLight = this->GetSafeHwnd();
|
|
|
|
|
|
CenterWindow();
|
|
|
|
|
|
pChart = m_wndChart.GetChart();
|
|
|
ASSERT_VALID(pChart);
|
|
|
|
|
|
//Release模式下,曲线背景会变白,在此设置颜色
|
|
|
#ifdef DEBUG
|
|
|
//pChart->SetColors(CBCGPChartTheme::CT_DEFAULT);
|
|
|
#else
|
|
|
pChart->SetColors(CBCGPChartTheme::CT_DEFAULT, TRUE);
|
|
|
#endif
|
|
|
|
|
|
//设置放大缩小方式
|
|
|
pChart->SetZoomScrollConfig(BCGPChartMouseConfig::ZSO_WHEEL_PAN, BCGPChartFormatSelection::ST_VERT_AXIS_ONLY);
|
|
|
pChart->SetSelectionType(BCGPChartFormatSelection::ST_VERT_AXIS_ONLY);
|
|
|
|
|
|
//曲线使能鼠标跟踪
|
|
|
pChart->EnableMouseTrackingMode(
|
|
|
BCGPChartHitInfo::HIT_DATA_POINT |
|
|
|
BCGPChartHitInfo::HIT_DATA_LABEL |
|
|
|
BCGPChartHitInfo::HIT_AXIS |
|
|
|
BCGPChartHitInfo::HIT_AXIS_NAME |
|
|
|
BCGPChartHitInfo::HIT_CHART_AREA |
|
|
|
BCGPChartHitInfo::HIT_LEGEND |
|
|
|
BCGPChartHitInfo::HIT_TITLE |
|
|
|
BCGPChartHitInfo::HIT_DIAGRAM |
|
|
|
BCGPChartHitInfo::HIT_DATA_TABLE |
|
|
|
BCGPChartHitInfo::HIT_ALL_ELEMENTS);
|
|
|
|
|
|
//设置:当鼠标移动到曲线上,会显示当前点的信息
|
|
|
CBCGPInfoTipOptions infoTipOptions;
|
|
|
infoTipOptions.m_StemLocation = CBCGPPopupWindow::BCGPPopupWindowStemLocation_BottomCenter;
|
|
|
m_wndChart.EnableInfoTip(TRUE, &infoTipOptions);
|
|
|
|
|
|
pXAxis = pChart->GetChartAxis(BCGP_CHART_X_PRIMARY_AXIS);
|
|
|
pYAxis = pChart->GetChartAxis(BCGP_CHART_Y_PRIMARY_AXIS);
|
|
|
|
|
|
//创建曲线1,绘制高程信息
|
|
|
pSeries1 = pChart->CreateSeries(_T("DEM Alt"), CBCGPColor(), BCGP_CT_DEFAULT, BCGPChartArea);
|
|
|
|
|
|
//创建曲线2,绘制最小通视高度
|
|
|
pSeries2 = pChart->CreateSeries(_T("LOS Alt"), CBCGPColor(CBCGPColor::OrangeRed), BCGP_CT_DEFAULT, BCGPChartLine);
|
|
|
pSeries2->SetSeriesLineWidth(2);
|
|
|
|
|
|
//创建曲线3,绘制无人机位置
|
|
|
pSeries3 = pChart->CreateSeries(_T("UAV Alt"), CBCGPColor(CBCGPColor::LimeGreen), BCGP_CT_DEFAULT, BCGPChartLine);
|
|
|
BCGPChartFormatSeries style = pSeries3->GetSeriesFormat();
|
|
|
style.m_curveType = BCGPChartFormatSeries::CCT_NO_LINE;
|
|
|
pSeries3->SetSeriesFormat(style);
|
|
|
|
|
|
pSeries3->ShowMarker(TRUE, 0);
|
|
|
pSeries3->SetMarkerSize(4, 0);
|
|
|
|
|
|
/*pSeries3->ShowDataLabel(TRUE,0);
|
|
|
pSeries3->SetDataLabelAngle(60, 0);
|
|
|
pSeries3->SetDataLabelDataFormat(_T("%.1f"),0);*/
|
|
|
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
|
|
|
//初始化可视域分析提示文字显示仪表
|
|
|
InitRegionTextContainer();
|
|
|
|
|
|
//初始化航线通视分析提示文字显示仪表
|
|
|
InitLineTextContainer();
|
|
|
|
|
|
//初始化通视等高线分析提示文字显示仪表
|
|
|
InitContourTextContainer();
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
void CDlgLightRegion::OnSize(UINT nType, int cx, int cy)
|
|
|
{
|
|
|
CBCGPDialog::OnSize(nType, cx, cy);
|
|
|
|
|
|
//图表控件随对话框大小变化而变化
|
|
|
if (m_wndChart.GetSafeHwnd())
|
|
|
{
|
|
|
CRect rect;
|
|
|
GetClientRect(&rect);
|
|
|
|
|
|
CRect rectChart;
|
|
|
m_wndChart.GetWindowRect(rectChart);
|
|
|
|
|
|
ScreenToClient(rectChart);
|
|
|
|
|
|
rectChart.right = rect.right - 5;
|
|
|
rectChart.bottom = rect.bottom - 5;
|
|
|
|
|
|
m_wndChart.MoveWindow(&rectChart,TRUE);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//初始化可视域分析提示文字显示仪表
|
|
|
void CDlgLightRegion::InitRegionTextContainer()
|
|
|
{
|
|
|
CBCGPVisualContainer* pContainer = m_RegionTextContainer.GetVisualContainer();
|
|
|
ASSERT_VALID(pContainer);
|
|
|
|
|
|
pContainer->SetFillBrush(CBCGPBrush());
|
|
|
pContainer->SetOutlineBrush(CBCGPBrush());
|
|
|
|
|
|
CBCGPBrush m_arBrushes(CBCGPColor::AliceBlue);
|
|
|
m_pRegionTTextIndicator = new CBCGPTextGaugeImpl(_T("进度提示"), m_arBrushes, pContainer);
|
|
|
|
|
|
CBCGPTextFormat m_TextFormat = m_pRegionTTextIndicator->GetTextFormat();
|
|
|
m_TextFormat.SetFontSize(15);
|
|
|
m_TextFormat.SetTextAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_TextFormat.SetTextVerticalAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_pRegionTTextIndicator->SetTextFormat(m_TextFormat);
|
|
|
|
|
|
CBCGPRect rect = pContainer->GetRect();
|
|
|
m_pRegionTTextIndicator->SetRect(rect);
|
|
|
|
|
|
m_RegionTextContainer.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//初始化航线通视分析提示文字显示仪表
|
|
|
void CDlgLightRegion::InitLineTextContainer()
|
|
|
{
|
|
|
CBCGPVisualContainer* pContainer = m_LineTextContainer.GetVisualContainer();
|
|
|
ASSERT_VALID(pContainer);
|
|
|
|
|
|
pContainer->SetFillBrush(CBCGPBrush());
|
|
|
pContainer->SetOutlineBrush(CBCGPBrush());
|
|
|
|
|
|
CBCGPBrush m_arBrushes(CBCGPColor::AliceBlue);
|
|
|
m_pLineTextIndicator = new CBCGPTextGaugeImpl(_T("进度提示"), m_arBrushes, pContainer);
|
|
|
|
|
|
CBCGPTextFormat m_TextFormat = m_pLineTextIndicator->GetTextFormat();
|
|
|
m_TextFormat.SetFontSize(15);
|
|
|
m_TextFormat.SetTextAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_TextFormat.SetTextVerticalAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_pLineTextIndicator->SetTextFormat(m_TextFormat);
|
|
|
|
|
|
CBCGPRect rect = pContainer->GetRect();
|
|
|
m_pLineTextIndicator->SetRect(rect);
|
|
|
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//初始化通视等高线分析提示文字显示仪表
|
|
|
void CDlgLightRegion::InitContourTextContainer()
|
|
|
{
|
|
|
CBCGPVisualContainer* pContainer = m_ContourTextContainer.GetVisualContainer();
|
|
|
ASSERT_VALID(pContainer);
|
|
|
|
|
|
pContainer->SetFillBrush(CBCGPBrush());
|
|
|
pContainer->SetOutlineBrush(CBCGPBrush());
|
|
|
|
|
|
CBCGPBrush m_arBrushes(CBCGPColor::AliceBlue);
|
|
|
m_pContourTextIndicator = new CBCGPTextGaugeImpl(_T("进度提示"), m_arBrushes, pContainer);
|
|
|
|
|
|
CBCGPTextFormat m_TextFormat = m_pContourTextIndicator->GetTextFormat();
|
|
|
m_TextFormat.SetFontSize(15);
|
|
|
m_TextFormat.SetTextAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_TextFormat.SetTextVerticalAlignment(CBCGPTextFormat::BCGP_TEXT_ALIGNMENT_CENTER);
|
|
|
m_pContourTextIndicator->SetTextFormat(m_TextFormat);
|
|
|
|
|
|
CBCGPRect rect = pContainer->GetRect();
|
|
|
m_pContourTextIndicator->SetRect(rect);
|
|
|
|
|
|
m_ContourTextContainer.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//接收其他线程来的消息,更新对话框内容
|
|
|
afx_msg LRESULT CDlgLightRegion::OnSendUpdateDialog(WPARAM wParam, LPARAM lParam)
|
|
|
{
|
|
|
if (1 == (int)wParam) //可视域分析
|
|
|
{
|
|
|
if (-1 == int(lParam))
|
|
|
{
|
|
|
m_pRegionTTextIndicator->SetText(_T("高程不全!"));
|
|
|
m_RegionTextContainer.RedrawWindow();
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_REGIONANAYLSIS)->EnableWindow(TRUE);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CString str;
|
|
|
str.Format(_T("%d%%"),(int)(((int)lParam+1) * 100 / 360));
|
|
|
|
|
|
m_pRegionTTextIndicator->SetText(str);
|
|
|
m_RegionTextContainer.RedrawWindow();
|
|
|
|
|
|
if (359 == int(lParam))
|
|
|
{
|
|
|
GetDlgItem(IDC_BUTTON_REGIONANAYLSIS)->EnableWindow(TRUE);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (2 == (int)wParam) //实时通视检测
|
|
|
{
|
|
|
if (-1 == int(lParam))
|
|
|
{
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
}
|
|
|
}
|
|
|
else if (3 == (int)wParam) //航线通视分析
|
|
|
{
|
|
|
if (-1 == int(lParam))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
m_pLineTextIndicator->SetText(_T("高程不全!"));
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
}
|
|
|
else if (-2 == int(lParam))
|
|
|
{
|
|
|
for (int i=0;i<g_iTotalInterNum;i++)
|
|
|
{
|
|
|
pSeries1->AddDataPoint(g_ptrArraySeries1[i],i);
|
|
|
pSeries2->AddDataPoint(g_ptrArraySeries2[i],i);
|
|
|
}
|
|
|
|
|
|
//航点的高程
|
|
|
for (int i=0;i<g_iWayPointNum;i++)
|
|
|
{
|
|
|
pSeries3->AddDataPoint(pts[i].alt,g_ptrArraySeries3[i]);
|
|
|
|
|
|
pSeries1->ShowDataLabel(TRUE,g_ptrArraySeries3[i]);
|
|
|
pSeries1->SetDataLabelAngle(0, g_ptrArraySeries3[i]);
|
|
|
pSeries1->ShowMarker(TRUE, g_ptrArraySeries3[i]);
|
|
|
pSeries1->SetMarkerSize(4, g_ptrArraySeries3[i]);
|
|
|
|
|
|
CString str;
|
|
|
str.Format(_T("%d-%d"),pts[i].lineID,pts[i].ptID);
|
|
|
pSeries1->SetDataLabelDataFormat(str,g_ptrArraySeries3[i]);
|
|
|
}
|
|
|
|
|
|
pChart->SetAutoDisplayRange(TRUE, TRUE);
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
|
|
|
m_pLineTextIndicator->SetText(_T("分析完成!"));
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
}
|
|
|
else if (1 == int(lParam))
|
|
|
{
|
|
|
if (g_iTotalInterNum > 0)
|
|
|
{
|
|
|
CString str;
|
|
|
str.Format(_T("%d%%"),(g_totalLinePtNum)*100/g_iTotalInterNum);
|
|
|
|
|
|
m_pLineTextIndicator->SetText(str);
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (4 == (int)wParam) //实时视线分析
|
|
|
{
|
|
|
if (-1 == int(lParam)) //未获取到高程值
|
|
|
{
|
|
|
m_bRTlight = FALSE;
|
|
|
UpdateData(FALSE);
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_LOADROUTE)->EnableWindow(TRUE);
|
|
|
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
}
|
|
|
else if (-2 == int(lParam)) //分析完成
|
|
|
{
|
|
|
pSeries1->AddDataPoint(g_ptrArrayLight1[0],0.0);
|
|
|
pSeries2->AddDataPoint(g_ptrArrayLight2[0],0.0);
|
|
|
|
|
|
for (int i=1;i<=g_iTotalAnalyNum;i++)
|
|
|
{
|
|
|
pSeries1->AddDataPoint(g_ptrArrayLight1[i],i*30);
|
|
|
pSeries2->AddDataPoint(g_ptrArrayLight2[i],i*30);
|
|
|
}
|
|
|
|
|
|
//在Chart上更新无人机的位置(距离和高度)
|
|
|
pSeries3->AddDataPoint(g_dLightUavAlt,30*g_iTotalAnalyNum);
|
|
|
pSeries3->ShowMarker(TRUE, 30*g_iTotalAnalyNum);
|
|
|
pSeries3->SetMarkerSize(4, 30*g_iTotalAnalyNum);
|
|
|
|
|
|
pChart->RemoveAllChartObjects();
|
|
|
|
|
|
//连接无人机高度和最小通视高度
|
|
|
m_pLine1 = pChart->AddChartLineObject(30*g_iTotalAnalyNum, g_dLightUavAlt, 30*g_iTotalAnalyNum, g_fUavLosAlt, CBCGPBrush(CBCGPColor::Tomato), 1.5, &m_strokeStyle);
|
|
|
|
|
|
CString str;
|
|
|
str.Format(_T("%.1fm"),g_dLightUavAlt - g_fUavLosAlt);
|
|
|
|
|
|
//显示无人机高度和最小通视高度的差值
|
|
|
m_pTextTip = nullptr;
|
|
|
m_pTextTip = new CBCGPChartTextObject(pChart, str, 30*g_iTotalAnalyNum, min(g_dLightUavAlt,g_fUavLosAlt) + abs(g_dLightUavAlt - g_fUavLosAlt)/2,
|
|
|
CBCGPBrush(CBCGPColor::White), CBCGPBrush(), CBCGPBrush(CBCGPColor::Tomato), 30, 90, TRUE);
|
|
|
pChart->AddChartObject(m_pTextTip);
|
|
|
|
|
|
pChart->SetAutoDisplayRange(TRUE, TRUE);
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
}
|
|
|
}
|
|
|
else if (5 == (int)wParam) //通视等高线分析
|
|
|
{
|
|
|
if (int(lParam) >= 0)
|
|
|
{
|
|
|
//进度提示
|
|
|
CString str;
|
|
|
str.Format(_T("%d%%"),(int)((int(lParam)+1) * 100 / 360));
|
|
|
|
|
|
m_pContourTextIndicator->SetText(str);
|
|
|
m_ContourTextContainer.RedrawWindow();
|
|
|
}
|
|
|
else if (-1 == int(lParam)) //未获取到高程值
|
|
|
{
|
|
|
m_pContourTextIndicator->SetText(_T("高程信息不全!"));
|
|
|
m_ContourTextContainer.RedrawWindow();
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_CONTOURLINE)->EnableWindow(TRUE);
|
|
|
}
|
|
|
else if (-2 == int(lParam))
|
|
|
{
|
|
|
m_pContourTextIndicator->SetText(_T("分析完成!"));
|
|
|
m_ContourTextContainer.RedrawWindow();
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_CONTOURLINE)->EnableWindow(TRUE);
|
|
|
}
|
|
|
else if (-3 == int(lParam))
|
|
|
{
|
|
|
//清除通视等高线分析结果
|
|
|
OnBnClickedButtonContourDelete();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//在地图上标绘地面站位置
|
|
|
void CDlgLightRegion::OnBnClickedButtonDrawPoint()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
::SendMessage(g_mapHwnd,WM_SHOW_POINTINMAP,0,0);
|
|
|
|
|
|
//获取地面站的高程信息
|
|
|
float ptAlt = 0.0f;
|
|
|
if(!m_mapElevation2.getElevation(ptAlt, m_dGroundLon, m_dGroundLat))
|
|
|
{
|
|
|
ptAlt = 0.0f;
|
|
|
}
|
|
|
|
|
|
CString str;
|
|
|
str.Format(_T("%.1f"),ptAlt);
|
|
|
GetDlgItem(IDC_EDIT_GROUND_ALT)->SetWindowText(str);
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:可视域分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//点击“可视域分析”按钮
|
|
|
void CDlgLightRegion::OnBnClickedButtonRegionAnaylsis()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
//获取地面站高程信息
|
|
|
if(!m_mapElevation2.getElevation(g_fGroundAltTemp, m_dGroundLon, m_dGroundLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("地面站处无高程信息!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
g_fGroundAltTemp += (float)m_dCabinHgt;
|
|
|
|
|
|
if (g_fGroundAltTemp > m_iFlightAlt)
|
|
|
{
|
|
|
BCGPMessageBox(_T("飞行高度应大于地面站高度!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//清除可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SEND_CLEARSHAPE,0,0);
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_REGIONANAYLSIS)->EnableWindow(FALSE);
|
|
|
|
|
|
g_dGroundLonTemp = m_dGroundLon;
|
|
|
g_dGroundLatTemp = m_dGroundLat;
|
|
|
g_iFlightAlt = m_iFlightAlt;
|
|
|
g_iRegionRadius = m_iRegionRadius;
|
|
|
g_iAnalysisStep = 0;
|
|
|
|
|
|
//开启线程
|
|
|
hThreadRegion = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncLightRegion, NULL, 0, &ThreadIDRegion);
|
|
|
|
|
|
m_bRunRegion = true;
|
|
|
}
|
|
|
|
|
|
//清除可视域分析结果
|
|
|
void CDlgLightRegion::OnBnClickedButtonRegionDelete()
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunRegion = false;
|
|
|
|
|
|
//清除可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SEND_CLEARSHAPE,0,0);
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_REGIONANAYLSIS)->EnableWindow(TRUE);
|
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时通视检测
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//选中实时通视检测
|
|
|
void CDlgLightRegion::OnBnClickedCheckRealtime()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
if (TRUE == m_bRealTime_Visi)
|
|
|
{
|
|
|
//清除实时可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SHOW_VISI_DELETE,0,0);
|
|
|
|
|
|
g_iRealTime_CurStep = -1;
|
|
|
|
|
|
//开启线程
|
|
|
hThreadDetect = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncRealTimeDetection, NULL, 0, &ThreadIDDetect);
|
|
|
|
|
|
m_bRunDetect = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunDetect = false;
|
|
|
|
|
|
//清除实时可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SHOW_VISI_DELETE,0,0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//地图上实时绘制检测区域
|
|
|
void CDlgLightRegion::DrawVisiAreaRealTime(double uavAlt, double distanceToGCS, double angleToGCS, double lonGCS, double latGCS)
|
|
|
{
|
|
|
//若未选中实时通视检测
|
|
|
if (FALSE == m_bRealTime_Visi)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//当实时检测已终止
|
|
|
if (-1 == g_iRealTime_CurStep)
|
|
|
{
|
|
|
//地面站-飞机距离小于5km,不进行实时检测
|
|
|
if (distanceToGCS < 5000.0)
|
|
|
{
|
|
|
m_bRealTime_Visi = FALSE;
|
|
|
UpdateData(FALSE);
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunDetect = false;
|
|
|
|
|
|
BCGPMessageBox(_T("地面站-飞机距离过短!"));
|
|
|
|
|
|
//清除实时可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SHOW_VISI_DELETE,0,0);
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//获取地面站高程信息
|
|
|
if(!m_mapElevation2.getElevation(g_fRealTime_GCSalt, lonGCS, latGCS))
|
|
|
{
|
|
|
m_bRealTime_Visi = FALSE;
|
|
|
UpdateData(FALSE);
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunDetect = false;
|
|
|
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("地面站处无高程信息!"));
|
|
|
|
|
|
//清除实时可视域绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_SHOW_VISI_DELETE,0,0);
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
g_fRealTime_GCSalt += (float)m_dCabinHgt;
|
|
|
|
|
|
double _tempAngle = (asin(3000.0/distanceToGCS) * 57.295779513082322864647721871733665466308593750000);
|
|
|
|
|
|
double _tempMinAngle = angleToGCS - _tempAngle;
|
|
|
|
|
|
if (_tempMinAngle < 0)
|
|
|
{
|
|
|
_tempMinAngle += 360.0;
|
|
|
}
|
|
|
|
|
|
g_dRealTime_GCSlon = lonGCS;
|
|
|
g_dRealTime_GCSlat = latGCS;
|
|
|
g_dRealTime_UavAlt = uavAlt;
|
|
|
g_dRealTime_AngToGCS = angleToGCS;
|
|
|
g_dRealTime_DisToGCS = distanceToGCS;
|
|
|
g_dRealTime_MinAngle = _tempMinAngle;
|
|
|
g_dRealTime_AngleDiff = _tempAngle/6.0;
|
|
|
|
|
|
//开始绘制实时可视域
|
|
|
g_iRealTime_CurStep = 0;
|
|
|
|
|
|
g_iPointNumInLayer = -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时碰撞检测
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//选中实时碰撞检测
|
|
|
void CDlgLightRegion::OnBnClickedCheckRtDetection()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
if (TRUE == m_bRealTime_Crash)
|
|
|
{
|
|
|
g_bCrashDetection = false;
|
|
|
|
|
|
//开启线程
|
|
|
hThreadCrash = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncRealTimeCrash, NULL, 0, &ThreadIDCrash);
|
|
|
|
|
|
m_bRunCrash = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
g_bCrashDetection = false;
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunCrash = false;
|
|
|
|
|
|
//清除碰撞检测后的结果
|
|
|
::PostMessage(g_mapHwnd,WM_SHOW_CRASH_REALTIME,0,0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//地图上实时在无人机周边检测高程
|
|
|
void CDlgLightRegion::DrawCrashAreaRealTime(double uavAlt, double uavLon, double uavLat)
|
|
|
{
|
|
|
//若未选中实时碰撞检测
|
|
|
if (FALSE == m_bRealTime_Crash)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (false == g_bCrashDetection)
|
|
|
{
|
|
|
g_dCrashUavLon = uavLon;
|
|
|
g_dCrashUavLat = uavLat;
|
|
|
g_fCrashUavAlt = (float)uavAlt;
|
|
|
|
|
|
g_bCrashDetection = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------------------------------------------------
|
|
|
说明:实时视线分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//选中实时视线分析
|
|
|
void CDlgLightRegion::OnBnClickedCheckRtLight()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
if (TRUE == m_bRTlight)
|
|
|
{
|
|
|
GetDlgItem(IDC_BUTTON_LOADROUTE)->EnableWindow(FALSE);
|
|
|
|
|
|
//两点通视分析时,隐藏了pSeries3,实时视线分析时需要显示
|
|
|
pChart->ShowSeries(TRUE, 2);
|
|
|
|
|
|
//设置曲线3类型为NO_LINE
|
|
|
BCGPChartFormatSeries style = pSeries3->GetSeriesFormat();
|
|
|
style.m_curveType = BCGPChartFormatSeries::CCT_NO_LINE;
|
|
|
pSeries3->SetSeriesFormat(style);
|
|
|
|
|
|
pSeries3->ShowMarker(TRUE, 0);
|
|
|
pSeries3->SetMarkerSize(4, 0);
|
|
|
|
|
|
pSeries3->m_strSeriesName = _T("UAV Alt");
|
|
|
|
|
|
//开启线程
|
|
|
hThreadLight = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncAnalysisLOS, NULL, 0, &ThreadIDLight);
|
|
|
|
|
|
m_bRunRealTimeLOS = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
g_bHandlingLOS = false;
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunRealTimeLOS = false;
|
|
|
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
pChart->RemoveAllChartObjects();
|
|
|
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_LOADROUTE)->EnableWindow(TRUE);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//实时视线分析,地面站-飞机连线,绘制图表
|
|
|
void CDlgLightRegion::AnalysisRealTime(double uavAlt, double distanceToGCS, double angleToGCS, double lonGCS, double latGCS)
|
|
|
{
|
|
|
//若未选中实时视线分析,返回
|
|
|
if (FALSE == m_bRTlight)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (false == g_bHandlingLOS)
|
|
|
{
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
|
|
|
g_dLightGCSlon = lonGCS; //地面站经度
|
|
|
g_dLightGCSlat = latGCS; //地面站纬度
|
|
|
g_dLightAngle = angleToGCS; //地面站-飞机方位
|
|
|
g_dLightDis = distanceToGCS; //地面站-飞机距离
|
|
|
g_dLightUavAlt = uavAlt; //飞机高度
|
|
|
|
|
|
//获取地面站所在位置高程值
|
|
|
if(!m_mapElevation2.getElevation(g_fLightGCSAlt, g_dLightGCSlon, g_dLightGCSlat))
|
|
|
{
|
|
|
//未获取到高程值,取消实时视线分析
|
|
|
m_bRTlight = FALSE;
|
|
|
UpdateData(FALSE);
|
|
|
|
|
|
//关闭线程
|
|
|
m_bRunRealTimeLOS = false;
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_LOADROUTE)->EnableWindow(TRUE);
|
|
|
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱的高度
|
|
|
g_fLightGCSAlt += (float)m_dCabinHgt;
|
|
|
|
|
|
g_bHandlingLOS = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:航线通视分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//加载航线
|
|
|
void CDlgLightRegion::OnBnClickedButtonLoadRoute()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
//弹出文件对话框
|
|
|
CFileDialog dlg(true, NULL, NULL,OFN_HIDEREADONLY, _T("(*.txt)|*.txt||"), NULL);
|
|
|
|
|
|
if (dlg.DoModal() == IDOK)
|
|
|
{
|
|
|
CString strFile = dlg.GetPathName();
|
|
|
|
|
|
int ptNum = 0;
|
|
|
|
|
|
//初始化航线的航点数据
|
|
|
memset(pts, 0, sizeof(PtStruct)*257);
|
|
|
|
|
|
FILE *fpReadFlyLine;
|
|
|
int err;
|
|
|
err = fopen_s(&fpReadFlyLine,strFile.GetBuffer(), "r");
|
|
|
strFile.ReleaseBuffer();
|
|
|
|
|
|
if (fpReadFlyLine != NULL)
|
|
|
{
|
|
|
while (!feof(fpReadFlyLine))
|
|
|
{
|
|
|
//航路文件是否导入正确的标识
|
|
|
int redFlag = fscanf_s(fpReadFlyLine, "%d, %d, %lf, %lf, %d, %d, %02X, %02X\n", &pts[ptNum].lineID,&pts[ptNum].ptID,
|
|
|
&pts[ptNum].lon, &pts[ptNum].lat, &pts[ptNum].alt, &pts[ptNum].speed, &pts[ptNum].taskCharacter, &pts[ptNum].lineCharacter);
|
|
|
|
|
|
if (redFlag != 8) //航路文件不对,返回
|
|
|
{
|
|
|
//关闭文件
|
|
|
fclose(fpReadFlyLine);
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (0 != pts[ptNum].ptID)
|
|
|
{
|
|
|
ptNum ++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//关闭文件
|
|
|
fclose(fpReadFlyLine);
|
|
|
|
|
|
//航路点个数的有效范围为[0,255]共256个
|
|
|
//检测的有效范围为【2,256】
|
|
|
if ((ptNum>257) || (ptNum<2))
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//对单个航点的数据进行检查
|
|
|
for (int i=0; i<ptNum; i++)
|
|
|
{
|
|
|
if ( (pts[i].ptID<0) || (pts[i].ptID>255)
|
|
|
|| (pts[i].lon<-180) || (pts[i].lon>180)
|
|
|
|| (pts[i].lat<-90) || (pts[i].lat>90)
|
|
|
|| (pts[i].alt<-500) || (pts[i].alt>10000)
|
|
|
|| (pts[i].speed<0) || (pts[i].speed>100)
|
|
|
|| (pts[i].taskCharacter<0) || (pts[i].taskCharacter>255)
|
|
|
|| (pts[i].lineCharacter<0) || (pts[i].lineCharacter>255) )
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//对航点的航线编号进行严格检查
|
|
|
//当存在航线编号不一样时,返回false
|
|
|
int ptLineID = pts[0].lineID;
|
|
|
for (int i=1; i<ptNum; i++)
|
|
|
{
|
|
|
if (ptLineID != pts[i].lineID)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//对航线的航点编号进行严格检查,判断规则为,起点为1,依次递增1
|
|
|
//当存在航点编号不符合规则时,返回
|
|
|
if (pts[0].ptID != 1)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
int toComparePtId = pts[0].ptID + 1;
|
|
|
for (int i=1; i<ptNum; i++)
|
|
|
{
|
|
|
if (pts[i].ptID != toComparePtId)
|
|
|
{
|
|
|
return ;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
toComparePtId++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//显示航线
|
|
|
//::SendMessage(g_mapHwnd, WM_SHOW_LINE, pts[0].lineID, 0);
|
|
|
|
|
|
pts[ptNum] = pts[0];
|
|
|
g_iWayPointNum = ptNum + 1;
|
|
|
g_totalLinePtNum = 0;
|
|
|
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
|
|
|
//两点通视分析时,隐藏了pSeries3,航线通视分析时需要显示
|
|
|
pChart->ShowSeries(TRUE, 2);
|
|
|
|
|
|
//设置曲线3类型为曲线
|
|
|
BCGPChartFormatSeries style = pSeries3->GetSeriesFormat();
|
|
|
style.m_curveType = BCGPChartFormatSeries::CCT_LINE;
|
|
|
pSeries3->SetSeriesFormat(style);
|
|
|
|
|
|
pSeries3->m_strSeriesName = _T("Pt Alt");
|
|
|
|
|
|
pSeries3->ShowMarker(FALSE);
|
|
|
|
|
|
m_pLineTextIndicator->SetText(_T("正在分析!"));
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
|
|
|
//计算航线分析时总共需要分析的点数
|
|
|
g_iTotalInterNum = 0;
|
|
|
for (int i=0;i<ptNum;i++)
|
|
|
{
|
|
|
double _dis;
|
|
|
if (i != (ptNum-1))
|
|
|
{
|
|
|
CalculateTwoPtsDistance(_dis, pts[i].lon, pts[i].lat, pts[i+1].lon, pts[i+1].lat, 3);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CalculateTwoPtsDistance(_dis, pts[i].lon, pts[i].lat, pts[0].lon, pts[0].lat, 3);
|
|
|
}
|
|
|
|
|
|
g_iTotalInterNum += (int)(_dis/100) + 1;
|
|
|
}
|
|
|
|
|
|
if (g_ptrArraySeries1 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries1;
|
|
|
g_ptrArraySeries1 = nullptr;
|
|
|
}
|
|
|
|
|
|
g_ptrArraySeries1 = new double[g_iTotalInterNum];
|
|
|
memset(g_ptrArraySeries1,0,sizeof(double) * g_iTotalInterNum);
|
|
|
|
|
|
if (g_ptrArraySeries2 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries2;
|
|
|
g_ptrArraySeries2 = nullptr;
|
|
|
}
|
|
|
|
|
|
g_ptrArraySeries2 = new double[g_iTotalInterNum];
|
|
|
memset(g_ptrArraySeries2,0,sizeof(double) * g_iTotalInterNum);
|
|
|
|
|
|
if (g_ptrArraySeries3 != nullptr)
|
|
|
{
|
|
|
delete[] g_ptrArraySeries3;
|
|
|
g_ptrArraySeries3 = nullptr;
|
|
|
}
|
|
|
|
|
|
g_ptrArraySeries3 = new int[g_iWayPointNum];
|
|
|
memset(g_ptrArraySeries3,0,sizeof(int) * g_iWayPointNum);
|
|
|
|
|
|
//获取地面站位置
|
|
|
g_dRoute_GCSlon = m_dGroundLon; //地面站经度
|
|
|
g_dRoute_GCSlat = m_dGroundLat; //地面站纬度
|
|
|
|
|
|
//获取插值点的高程
|
|
|
if(!m_mapElevation2.getElevation(g_fRoute_GCSalt, g_dRoute_GCSlon, g_dRoute_GCSlat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("地面站处无高程信息!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
g_fRoute_GCSalt += (float)m_dCabinHgt;
|
|
|
|
|
|
//开启线程
|
|
|
hThreadRoute = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncAnalysisRoute, NULL, 0, &ThreadIDRoute);
|
|
|
|
|
|
m_bRunRoute = true;
|
|
|
}
|
|
|
else //空文件,航点数为0
|
|
|
{
|
|
|
BCGPMessageBox(_T( "空文件!" ));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//停止航线分析
|
|
|
void CDlgLightRegion::OnBnClickedButtonStopRoute()
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunRoute = false;
|
|
|
|
|
|
g_iInterNumSec = 0;
|
|
|
g_iWayPointNum = 0;
|
|
|
g_iCurWaypoint = 0;
|
|
|
g_iTotalInterNum = 0;
|
|
|
g_totalLinePtNum = 0;
|
|
|
|
|
|
m_pLineTextIndicator->SetText(_T(""));
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//保存航线通视分析结果
|
|
|
void CDlgLightRegion::OnBnClickedButtonSaveImage()
|
|
|
{
|
|
|
CFileDialog dlg (FALSE, _T("bmp"), _T(""), OFN_HIDEREADONLY,
|
|
|
_T("Bitmap Files (*.bmp)|*.bmp|Png Files (*.png)|*.png|All Files (*.*)|*.*||"), this);
|
|
|
if (dlg.DoModal () == IDOK)
|
|
|
{
|
|
|
m_wndChart.ExportToFile(dlg.GetPathName ());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//清除航线通视分析结果
|
|
|
void CDlgLightRegion::OnBnClickedButtonClearResult()
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunRoute = false;
|
|
|
|
|
|
g_iInterNumSec = 0;
|
|
|
g_iWayPointNum = 0;
|
|
|
g_iCurWaypoint = 0;
|
|
|
g_iTotalInterNum = 0;
|
|
|
g_totalLinePtNum = 0;
|
|
|
|
|
|
m_pLineTextIndicator->SetText(_T(""));
|
|
|
m_LineTextContainer.RedrawWindow();
|
|
|
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
|
|
|
//清除航线上的点的标绘图层
|
|
|
::SendMessage(g_mapHwnd, WM_DRAW_LINEPOINT, 0, 0);
|
|
|
}
|
|
|
|
|
|
LRESULT CDlgLightRegion::OnMouseDown(WPARAM /*wp*/, LPARAM lp)
|
|
|
{
|
|
|
BCGPChartHitInfo* pHitInfo = (BCGPChartHitInfo*)lp;
|
|
|
|
|
|
switch (pHitInfo->m_hitInfo)
|
|
|
{
|
|
|
case BCGPChartHitInfo::HIT_DIAGRAM:
|
|
|
CBCGPPoint pt = pHitInfo->m_ptHit;
|
|
|
|
|
|
double dblX = pXAxis->ValueFromPoint(pt);
|
|
|
double dblY = pYAxis->ValueFromPoint(pt);
|
|
|
|
|
|
if (g_ptrArraySeries3 != nullptr && g_iWayPointNum > 2)
|
|
|
{
|
|
|
for (int i=0;i<(g_iWayPointNum-1);i++)
|
|
|
{
|
|
|
if ((dblX >= g_ptrArraySeries3[i]) && (dblX < g_ptrArraySeries3[i+1]))
|
|
|
{
|
|
|
double azAngle = 0;
|
|
|
CalculateTwoPtsAzimuth(azAngle,pts[i].lon, pts[i].lat,pts[i+1].lon,pts[i+1].lat,3);
|
|
|
|
|
|
structPoint _structPoint;
|
|
|
CalculatePtCoordinate(_structPoint.lon, _structPoint.lat, pts[i].lon, pts[i].lat, azAngle, (dblX-g_ptrArraySeries3[i]) * 100, 3);
|
|
|
|
|
|
//发送到地图,标绘曲线上的点在地图上对应的点
|
|
|
::SendMessage(g_mapHwnd, WM_DRAW_LINEPOINT, (WPARAM)&_structPoint, 1);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:通视等高线
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//通视等高线分析
|
|
|
void CDlgLightRegion::OnBnClickedButtonContourline()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
//获取地面站高程信息
|
|
|
if(!m_mapElevation2.getElevation(m_fGroudAlt, m_dGroundLon, m_dGroundLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("地面站处无高程信息!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
m_fGroudAlt += (float)m_dCabinHgt;
|
|
|
}
|
|
|
|
|
|
g_dGroundLonCountour = m_dGroundLon;
|
|
|
g_dGroundLatCountour = m_dGroundLat;
|
|
|
g_fGroundAltCountour = m_fGroudAlt;
|
|
|
|
|
|
if (m_iMaxLosAlt < m_fGroudAlt)
|
|
|
{
|
|
|
BCGPMessageBox(_T("最大高度不允许小于地面站高度!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (m_iMaxLosAlt > 10000)
|
|
|
{
|
|
|
BCGPMessageBox(_T("最大高度不允许超过10000!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
g_iMaxLosAlt = m_iMaxLosAlt;
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_CONTOURLINE)->EnableWindow(FALSE);
|
|
|
|
|
|
//清除通视等高线绘制图层
|
|
|
::SendMessage(g_mapHwnd,WM_DEL_LINELAYER,0,0);
|
|
|
|
|
|
//开启线程
|
|
|
hThreadContour = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFuncAnalysisContour, NULL, 0, &ThreadIDContour);
|
|
|
|
|
|
m_bRunContour = true;
|
|
|
}
|
|
|
|
|
|
//清除通视等高线
|
|
|
void CDlgLightRegion::OnBnClickedButtonContourDelete()
|
|
|
{
|
|
|
//关闭线程
|
|
|
m_bRunContour = false;
|
|
|
|
|
|
::SendMessage(g_mapHwnd,WM_DEL_LINELAYER,0,0);
|
|
|
|
|
|
GetDlgItem(IDC_BUTTON_CONTOURLINE)->EnableWindow(TRUE);
|
|
|
|
|
|
m_pContourTextIndicator->SetText(_T(""));
|
|
|
m_ContourTextContainer.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------------------------
|
|
|
说明:两点间的通视分析
|
|
|
-------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
//坐标输入分析,根据输入的经纬度获取高程及通视高度
|
|
|
void CDlgLightRegion::OnBnClickedButtonGetAltValue()
|
|
|
{
|
|
|
CString str;
|
|
|
double _ptLon = 0.0, _ptLat = 0.0;
|
|
|
|
|
|
//获取目标点的经度和纬度
|
|
|
GetDlgItem(IDC_EDIT_POINT_LON)->GetWindowText(str);
|
|
|
_ptLon = atof(str);
|
|
|
|
|
|
GetDlgItem(IDC_EDIT_POINT_LAT)->GetWindowText(str);
|
|
|
_ptLat = atof(str);
|
|
|
|
|
|
if ((_ptLon == 0) || (_ptLat == 0) || (_ptLon > 180) || (_ptLon < -180) || (_ptLat > 90) || (_ptLat < -90))
|
|
|
{
|
|
|
BCGPMessageBox(_T("坐标无效!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//获取高程
|
|
|
float ptAlt = 0.0f;
|
|
|
if(!m_mapElevation2.getElevation(ptAlt, _ptLon, _ptLat))
|
|
|
{
|
|
|
ptAlt = 0.0f;
|
|
|
}
|
|
|
|
|
|
str.Format(_T("%.1f"),ptAlt);
|
|
|
GetDlgItem(IDC_EDIT_POINT_ALT)->SetWindowText(str);
|
|
|
|
|
|
structPoint _tempPoint;
|
|
|
_tempPoint.lon = _ptLon;
|
|
|
_tempPoint.lat = _ptLat;
|
|
|
|
|
|
//发送到地图,完成标绘
|
|
|
::SendMessage(g_mapHwnd,WM_SEND_REGIONTOGIS,(WPARAM)3,(LPARAM)&_tempPoint);
|
|
|
|
|
|
//通视分析
|
|
|
LosBetweenTwoPoints();
|
|
|
}
|
|
|
|
|
|
//在地图上选点,获取高程并进行通视分析
|
|
|
void CDlgLightRegion::OnBnClickedButtonSelectPtInMap()
|
|
|
{
|
|
|
::SendMessage(g_mapHwnd,WM_SEND_REGIONTOGIS,(WPARAM)1,0);
|
|
|
}
|
|
|
|
|
|
//在对话框里显示选择点的坐标和高程
|
|
|
void CDlgLightRegion::ShowPointPosition(double ptLon, double ptLat)
|
|
|
{
|
|
|
CString str;
|
|
|
|
|
|
str.Format(_T("%.7f"),ptLon);
|
|
|
GetDlgItem(IDC_EDIT_POINT_LON)->SetWindowText(str);
|
|
|
|
|
|
str.Format(_T("%.7f"),ptLat);
|
|
|
GetDlgItem(IDC_EDIT_POINT_LAT)->SetWindowText(str);
|
|
|
|
|
|
//获取高程
|
|
|
float ptAlt = 0.0f;
|
|
|
if(!m_mapElevation2.getElevation(ptAlt, ptLon, ptLat))
|
|
|
{
|
|
|
ptAlt = 0.0f;
|
|
|
}
|
|
|
|
|
|
str.Format(_T("%.1f"),ptAlt);
|
|
|
GetDlgItem(IDC_EDIT_POINT_ALT)->SetWindowText(str);
|
|
|
}
|
|
|
|
|
|
//两点间通视分析
|
|
|
void CDlgLightRegion::LosBetweenTwoPoints()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
//获取地面站的高程
|
|
|
float _fGroundAlt = 0.0f;
|
|
|
if(!m_mapElevation2.getElevation(_fGroundAlt, m_dGroundLon, m_dGroundLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
_fGroundAlt += (float)m_dCabinHgt;
|
|
|
|
|
|
pChart->ShowSeries(FALSE,2);
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
|
|
|
CString str;
|
|
|
double _ptLon = 0.0, _ptLat = 0.0;
|
|
|
|
|
|
//获取目标点的经度和纬度
|
|
|
GetDlgItem(IDC_EDIT_POINT_LON)->GetWindowText(str);
|
|
|
_ptLon = atof(str);
|
|
|
|
|
|
GetDlgItem(IDC_EDIT_POINT_LAT)->GetWindowText(str);
|
|
|
_ptLat = atof(str);
|
|
|
|
|
|
//计算地面站和目标点的距离和方位
|
|
|
double dis = 0.0,angle = 0.0;
|
|
|
CalculateTwoPtsDistanceAzimuth(dis, angle, m_dGroundLon, m_dGroundLat, _ptLon, _ptLat, 3);
|
|
|
|
|
|
double _dTanMaxSlope = -1000.0; //最大斜率
|
|
|
double _fMinLOSAlt = 0.0; //最小通视高度
|
|
|
double _tempSlope = 0.0; //当前点与地面站的连线的斜率
|
|
|
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//以30为采样间距,计算插值个数
|
|
|
int interPolDis = 30;
|
|
|
int interPolNum = (int)(dis/interPolDis);
|
|
|
|
|
|
for(int i = 0; i <= interPolNum; i++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, m_dGroundLon, m_dGroundLat, angle, i*interPolDis, 3);
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//计算该点与地面站连线的斜率
|
|
|
_tempSlope = CalSlopeBetweenTwoPoint(m_dGroundLon, m_dGroundLat, _fGroundAlt, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
//与前面所有点的最大斜率比较,取最大值
|
|
|
_dTanMaxSlope = max(_tempSlope,_dTanMaxSlope);
|
|
|
|
|
|
//计算该点的最小通视高度
|
|
|
_fMinLOSAlt = (float)CalAltFromSlope(m_dGroundLon, m_dGroundLat, _fGroundAlt, interPolLon, interPolLat, _dTanMaxSlope);
|
|
|
|
|
|
pSeries1->AddDataPoint(interPolHight,i*interPolDis);
|
|
|
pSeries2->AddDataPoint(_fMinLOSAlt,i*interPolDis);
|
|
|
}
|
|
|
|
|
|
pChart->SetAutoDisplayRange(TRUE, TRUE);
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
|
|
|
//显示最小通视高度
|
|
|
str.Format(_T("%.1f"),_fMinLOSAlt);
|
|
|
GetDlgItem(IDC_EDIT_POINT_LOS)->SetWindowText(str);
|
|
|
}
|
|
|
|
|
|
//清除地面站与目标点连线,以及分析结果
|
|
|
void CDlgLightRegion::OnBnClickedButtonClearLineLayer()
|
|
|
{
|
|
|
//清除目标点和连线图层
|
|
|
::SendMessage(g_mapHwnd,WM_SEND_REGIONTOGIS,(WPARAM)2,0);
|
|
|
|
|
|
//清除分析结果图标
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
pSeries3->RemoveAllDataPoints();
|
|
|
m_wndChart.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//反向通视分析
|
|
|
void CDlgLightRegion::OnBnClickedButtonReverse()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
CString str;
|
|
|
double _ptLon = 0.0, _ptLat = 0.0;
|
|
|
|
|
|
//获取目标点的经度和纬度
|
|
|
GetDlgItem(IDC_EDIT_POINT_LON)->GetWindowText(str);
|
|
|
_ptLon = atof(str);
|
|
|
|
|
|
GetDlgItem(IDC_EDIT_POINT_LAT)->GetWindowText(str);
|
|
|
_ptLat = atof(str);
|
|
|
|
|
|
//获取地面站的高程
|
|
|
float _fGroundAlt = 0.0f;
|
|
|
if(!m_mapElevation2.getElevation(_fGroundAlt, _ptLon, _ptLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
//地面站位置的高度在地面站高程的基础上加上方舱高度
|
|
|
_fGroundAlt += (float)m_dCabinHgt;
|
|
|
|
|
|
pChart->ShowSeries(FALSE,2);
|
|
|
pSeries1->RemoveAllDataPoints();
|
|
|
pSeries2->RemoveAllDataPoints();
|
|
|
|
|
|
//计算地面站和目标点的距离和方位
|
|
|
double dis = 0.0,angle = 0.0;
|
|
|
CalculateTwoPtsDistanceAzimuth(dis, angle, _ptLon, _ptLat, m_dGroundLon, m_dGroundLat, 3);
|
|
|
|
|
|
double _dTanMaxSlope = -1000.0; //最大斜率
|
|
|
double _fMinLOSAlt = 0.0; //最小通视高度
|
|
|
double _tempSlope = 0.0; //当前点与地面站的连线的斜率
|
|
|
|
|
|
//采样点位置
|
|
|
double interPolLon = 0.0, interPolLat = 0.0;
|
|
|
float interPolHight = 0.0;
|
|
|
|
|
|
//以30为采样间距,计算插值个数
|
|
|
int interPolDis = 30;
|
|
|
int interPolNum = (int)(dis/interPolDis);
|
|
|
|
|
|
for(int i = 0; i <= interPolNum; i++)
|
|
|
{
|
|
|
CalculatePtCoordinate(interPolLon, interPolLat, _ptLon, _ptLat, angle, i*interPolDis, 3);
|
|
|
|
|
|
//获取采样点的高程
|
|
|
if(!m_mapElevation2.getElevation(interPolHight, interPolLon, interPolLat))
|
|
|
{
|
|
|
//未获取到高程值
|
|
|
BCGPMessageBox(_T("高程信息不全!"));
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//计算该点与地面站连线的斜率
|
|
|
_tempSlope = CalSlopeBetweenTwoPoint(_ptLon, _ptLat, _fGroundAlt, interPolLon, interPolLat, interPolHight);
|
|
|
|
|
|
//与前面所有点的最大斜率比较,取最大值
|
|
|
_dTanMaxSlope = max(_tempSlope,_dTanMaxSlope);
|
|
|
|
|
|
//计算该点的最小通视高度
|
|
|
_fMinLOSAlt = (float)CalAltFromSlope(_ptLon, _ptLat, _fGroundAlt, interPolLon, interPolLat, _dTanMaxSlope);
|
|
|
|
|
|
pSeries1->AddDataPoint(interPolHight,i*interPolDis);
|
|
|
pSeries2->AddDataPoint(_fMinLOSAlt,i*interPolDis);
|
|
|
}
|
|
|
|
|
|
pChart->SetAutoDisplayRange(TRUE, TRUE);
|
|
|
pChart->SetDirty(TRUE, TRUE);
|
|
|
m_wndChart.RedrawWindow();
|
|
|
}
|
|
|
|
|
|
//标绘作战范围
|
|
|
void CDlgLightRegion::OnBnClickedButtonDrawFight()
|
|
|
{
|
|
|
UpdateData(TRUE);
|
|
|
|
|
|
structPoint _structPoint;
|
|
|
|
|
|
_structPoint.lon = m_dGroundLon;
|
|
|
_structPoint.lat = m_dGroundLat;
|
|
|
|
|
|
//发送到地图,绘制作战范围
|
|
|
::SendMessage(g_mapHwnd, WM_SEND_DRAWFIGHT, WPARAM(&_structPoint), LPARAM(m_iFightRegion*1000));
|
|
|
}
|
|
|
|
|
|
//清除作战范围
|
|
|
void CDlgLightRegion::OnBnClickedButtonDeleteFight()
|
|
|
{
|
|
|
::SendMessage(g_mapHwnd, WM_SEND_DRAWFIGHT, 0, 0);
|
|
|
}
|
|
|
|
|
|
//标绘高程数据区域
|
|
|
void CDlgLightRegion::OnBnClickedButtonGetDemRegion()
|
|
|
{
|
|
|
CString _DEMpath = GetSoftwareCurrentDirectory() + _T("\\ElevationData");
|
|
|
|
|
|
//文件句柄
|
|
|
long hFile = 0;
|
|
|
//文件信息
|
|
|
struct _finddata_t fileinfo;
|
|
|
string p;
|
|
|
if((hFile = _findfirst(p.assign(_DEMpath.GetBuffer()).append("\\*").c_str(),&fileinfo)) != -1)
|
|
|
{
|
|
|
int _fileNum = 0;
|
|
|
char fileName[3];
|
|
|
structPoint _structPoint;
|
|
|
|
|
|
char _flag;
|
|
|
|
|
|
do
|
|
|
{
|
|
|
if((fileinfo.attrib & _A_SUBDIR))
|
|
|
{
|
|
|
;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//处理遍历到的文件名
|
|
|
memset(fileName,0,3);
|
|
|
memset(&_structPoint,0,sizeof(structPoint));
|
|
|
|
|
|
//纬度
|
|
|
memcpy(fileName, fileinfo.name+8, 2);
|
|
|
_structPoint.lat = atof(fileName);
|
|
|
|
|
|
memcpy(&_flag, fileinfo.name+7, 1);
|
|
|
if ('S' == _flag)
|
|
|
{
|
|
|
_structPoint.lat = 0 - _structPoint.lat;
|
|
|
}
|
|
|
|
|
|
//经度
|
|
|
memcpy(fileName, fileinfo.name+11, 3);
|
|
|
_structPoint.lon = atof(fileName);
|
|
|
|
|
|
memcpy(&_flag, fileinfo.name+10, 1);
|
|
|
if ('W' == _flag)
|
|
|
{
|
|
|
_structPoint.lon = 0 - _structPoint.lon;
|
|
|
}
|
|
|
|
|
|
_fileNum++;
|
|
|
::SendMessage(g_mapHwnd, WM_SEND_DRAWDEMREGION, WPARAM(&_structPoint), LPARAM(_fileNum));
|
|
|
}
|
|
|
}while(_findnext(hFile, &fileinfo) == 0);
|
|
|
_findclose(hFile);
|
|
|
}
|
|
|
|
|
|
_DEMpath.ReleaseBuffer();
|
|
|
} |