// DlgLightRegion.cpp : 实现文件 // #include "stdafx.h" #include "DlgLightRegion.h" #include "afxdialogex.h" #include "MapElevation.h" #include 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;iAddDataPoint(g_ptrArraySeries1[i],i); pSeries2->AddDataPoint(g_ptrArraySeries2[i],i); } //航点的高程 for (int i=0;iAddDataPoint(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; i255) || (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; iRemoveAllDataPoints(); 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;iSetText(_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(); }