// designsurveylinedlg.cpp : 实现文件 // #include "stdafx.h" #include "designsurveylinedlg.h" #include "afxdialogex.h" // DesignSurveyLineDlg 对话框 IMPLEMENT_DYNAMIC(DesignSurveyLineDlg, CBCGPDialog) DesignSurveyLineDlg::DesignSurveyLineDlg(CWnd* pParent /*=NULL*/) : CBCGPDialog(DesignSurveyLineDlg::IDD, pParent) { EnableVisualManagerStyle(TRUE, TRUE); bDrawRegion = false; lineID = 1;//测绘航线号 } DesignSurveyLineDlg::~DesignSurveyLineDlg() { } void DesignSurveyLineDlg::DoDataExchange(CDataExchange* pDX) { CBCGPDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_BTN_SAVEREGION, m_btnSaveRegion); } BEGIN_MESSAGE_MAP(DesignSurveyLineDlg, CBCGPDialog) ON_BN_CLICKED(IDC_BTN_INPUTREGION, &DesignSurveyLineDlg::OnBnClickedBtnInputregion) ON_BN_CLICKED(IDC_BTN_DRAWREGION, &DesignSurveyLineDlg::OnBnClickedBtnDrawregion) ON_BN_CLICKED(IDC_BTN_SAVEREGION, &DesignSurveyLineDlg::OnBnClickedBtnSaveregion) ON_BN_CLICKED(IDC_BTN_BINDLINE, &DesignSurveyLineDlg::OnBnClickedBtnBindline) ON_BN_CLICKED(IDC_BTN_CALCULATELINE, &DesignSurveyLineDlg::OnBnClickedBtnCalculateline) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BTN_CALCULATETIME, &DesignSurveyLineDlg::OnBnClickedBtnCalculatetime) END_MESSAGE_MAP() BOOL DesignSurveyLineDlg::OnInitDialog() { CBCGPDialog::OnInitDialog(); CenterWindow(); GetDlgItem( IDC_BTN_CALCULATELINE )->EnableWindow( false ); GetDlgItem( IDC_BTN_CALCULATETIME )->EnableWindow( false ); SetDlgItemText(IDC_EDIT_FLYSPEED,"10"); SetDlgItemText(IDC_EDIT_EXTERNALLENGTH,"0"); return TRUE; } //提取没有后缀名的文件名 CString DesignSurveyLineDlg::extractFileName(CString fileName) { // 查找最后一个点的位置 int dotIndex = fileName.ReverseFind(_T('.')); // 如果找到了点,并且点不是第一个字符 if (dotIndex != -1) { // 提取文件名,不包括后缀 CString fileNameWithoutExtension = fileName.Left(dotIndex); return fileNameWithoutExtension; } else { // 如果没有找到点,说明没有后缀,直接显示文件名 return fileName; } } //设置航测区域 void DesignSurveyLineDlg::SetSurveyRegion(const vector<double>& lons,const vector<double>& lats) { surveyRegionLons.clear(); surveyRegionLats.clear(); for (int i=0;i<lons.size();++i) { surveyRegionLons.push_back(lons[i]); surveyRegionLats.push_back(lats[i]); } GetDlgItem( IDC_BTN_CALCULATELINE )->EnableWindow( true ); } //计算测绘航线 void DesignSurveyLineDlg::calculateSurveyLine(double lineInterval,vector<double>&surveyLineLons,vector<double>& surveyLineLats,double outLength) { vector<double> recLons; vector<double> recLats; TopologicalAnalysis analysis; GeoCompute geocompute; //计算外包矩形 //analysis.GetBoundingBoxVertices(surveyRegionLons,surveyRegionLats,recLons,recLats); int startPt1 = analysis.getLineWithPolygonMinWidth(surveyRegionLons,surveyRegionLats); recLons.push_back(surveyRegionLons[startPt1]); recLons.push_back(surveyRegionLons[startPt1+1]); recLats.push_back(surveyRegionLats[startPt1]); recLats.push_back(surveyRegionLats[startPt1+1]); double flyAngle;//飞行航向 CalculateTwoPtsAzimuth(flyAngle,surveyRegionLons[startPt1],surveyRegionLats[startPt1],surveyRegionLons[startPt1+1],surveyRegionLats[startPt1+1],3); //计算偏移航向 Line2D line; line.p1.x = surveyRegionLons[startPt1]; line.p1.y = surveyRegionLats[startPt1]; line.p2.x = surveyRegionLons[startPt1 + 1]; line.p2.y = surveyRegionLats[startPt1 + 1]; Point2D p; //直线的下一个顶点 if (startPt1+1 == (surveyRegionLons.size()-1)) //直线为多边形最后一条边 { p.x = surveyRegionLons[1]; p.y = surveyRegionLats[1]; } else { p.x = surveyRegionLons[startPt1 + 2]; p.y = surveyRegionLats[startPt1 + 2]; } int ptPos = analysis.pointPosition(p,line); if (ptPos == 1) //左侧 { int i = (flyAngle + 270)/360; flyAngle = (flyAngle + 270) - 360*i; } else if(ptPos == -1) //右侧 { int i = (flyAngle + 90)/360; flyAngle = (flyAngle + 90) - 360*i; } double lon1,lat1,lon2,lat2; //第一条切割线为航线间隔一半 geocompute.computeOffsetGeoPosition(recLons[0],recLats[0],flyAngle,lineInterval/2000,lon1,lat1); geocompute.computeOffsetGeoPosition(recLons[1],recLats[1],flyAngle,lineInterval/2000,lon2,lat2); Point2D pt1,pt2; pt1.x = lon1; pt1.y = lat1; pt2.x = lon2; pt2.y = lat2; vector<Point2D> result; //交点个数 int nCrossPt = analysis.linePolygonIntersections(pt1,pt2,surveyRegionLons,surveyRegionLats,result); while(nCrossPt>1){ //平移切割线 geocompute.computeOffsetGeoPosition(lon1,lat1,flyAngle,lineInterval/1000,lon1,lat1); geocompute.computeOffsetGeoPosition(lon2,lat2,flyAngle,lineInterval/1000,lon2,lat2); pt1.x = lon1; pt1.y = lat1; pt2.x = lon2; pt2.y = lat2; //计算交点 nCrossPt = analysis.linePolygonIntersections(pt1,pt2,surveyRegionLons,surveyRegionLats,result); } int nlinePts = result.size(); if (nlinePts%2!=0) { nlinePts--; } //计算外扩航点 if (nlinePts>1 && outLength>0) { double angle; CalculateTwoPtsAzimuth(angle,result[0].x,result[0].y,result[1].x,result[1].y,3); //计算外扩航向 double outAngle1,outAngle2; outAngle2 = angle; int n = (angle + 180)/360; outAngle1 = (angle + 180) - 360*n; geocompute.computeOffsetGeoPosition(result[1].x,result[1].y,outAngle2,outLength/1000,lon2,lat2); result[1].x = lon2; result[1].y = lat2; for (int i=2;i<nlinePts;i+=2) { geocompute.computeOffsetGeoPosition(result[i].x,result[i].y,outAngle1,outLength/1000,lon1,lat1); geocompute.computeOffsetGeoPosition(result[i+1].x,result[i+1].y,outAngle2,outLength/1000,lon2,lat2); result[i].x = lon1; result[i].y = lat1; result[i+1].x = lon2; result[i+1].y = lat2; } } //串联交点 int j = 0; for (int i=0;i<nlinePts;i+=2) { if (j == 1) { surveyLineLons.push_back(result[i+1].x); surveyLineLons.push_back(result[i].x); surveyLineLats.push_back(result[i+1].y); surveyLineLats.push_back(result[i].y); j = 0; continue; } else if (j==0) { surveyLineLons.push_back(result[i].x); surveyLineLons.push_back(result[i+1].x); surveyLineLats.push_back(result[i].y); surveyLineLats.push_back(result[i+1].y); j=1; continue; } } } //保存测绘航线 void DesignSurveyLineDlg::saveSurveyLine(const vector<double>&surveyLineLons,const vector<double>& surveyLineLats,double height) { //写航线 CString filename; CString strRouteFileDir = GetSoftwareCurrentDirectory() + _T("\\Route\\") + _T("测绘航线\\"); //测绘航线文件夹不存在则创建 if (!SearchDirectory(strRouteFileDir)) { CreateDirectory(strRouteFileDir); } TCHAR s[10000]; s[0]=0; CString defaultName = g_regionFileName + "-测绘航线.txt"; CFileDialog dlg(FALSE, _T(".txt"), defaultName); dlg.m_ofn.lpstrTitle=_T("保存测绘航线文件"); /* dlg.m_ofn.lpstrFile=s; dlg.m_ofn.nMaxFile=sizeof(s)/sizeof(TCHAR);*/ TCHAR filter[500]=_T("测绘航线文件(*.txt)\0*.txt\0"); dlg.m_ofn.lpstrFilter=filter; dlg.m_ofn.Flags|=OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_CREATEPROMPT; dlg.m_ofn.lpstrInitialDir = strRouteFileDir; if (IDOK == dlg.DoModal()) { filename = dlg.GetPathName(); g_linePathName = filename; g_lineFileName = extractFileName(dlg.GetFileName()); FILE* fp = fopen(filename,"w"); int iLineNum = lineID; fprintf(fp,"%d, 0, %.7f, %.7f, %.2f, 0, 00, 03\n", iLineNum, 0.0, 0.0, 0.0); int i = 0; for (i;i<surveyLineLons.size()-1;++i) { fprintf(fp,"%d, %d, %.7f, %.7f, %.2f, 0, 00, 03\n", iLineNum,i+1, surveyLineLons[i], surveyLineLats[i], height); } fprintf(fp,"%d, %d, %.7f, %.7f, %.2f, 0, 02, 01\n", iLineNum,i+1, surveyLineLons[i], surveyLineLats[i], height); fclose(fp); }else { return; } } //保存航测区域 bool DesignSurveyLineDlg::saveSurveyRegion(const vector<double>&surveyRegionLons,const vector<double>& surveyRegionLats) { //写航线 CString filename; CString strRouteFileDir = GetSoftwareCurrentDirectory() + _T("\\Route\\") + _T("测绘航线\\"); //测绘航线文件夹不存在则创建 if (!SearchDirectory(strRouteFileDir)) { CreateDirectory(strRouteFileDir); } TCHAR s[10000]; s[0]=0; CFileDialog dlg(FALSE, _T(".route"), _T("测绘区域1.route")); dlg.m_ofn.lpstrTitle=_T("保存测绘区域文件"); /* dlg.m_ofn.lpstrFile=s; dlg.m_ofn.nMaxFile=sizeof(s)/sizeof(TCHAR);*/ TCHAR filter[500]=_T("测绘区域文件(*.route)\0*.route\0"); dlg.m_ofn.lpstrFilter=filter; dlg.m_ofn.Flags|=OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_CREATEPROMPT; dlg.m_ofn.lpstrInitialDir = strRouteFileDir; if (IDOK == dlg.DoModal()) { filename = dlg.GetPathName(); g_regionPathName = filename; g_regionFileName = extractFileName(dlg.GetFileName()); FILE* fp = fopen(filename,"w"); int iLineNum = lineID; fprintf(fp,"%d, 0, %.7f, %.7f, %.2f, 0, 00, 03\n", iLineNum, 0.0, 0.0, 0.0); int i = 0; for (i;i<surveyRegionLons.size()-2;++i) { fprintf(fp,"%d, %d, %.7f, %.7f, %.2f, 0, 00, 03\n", iLineNum,i+1, surveyRegionLons[i], surveyRegionLats[i], 0.0); } fprintf(fp,"%d, %d, %.7f, %.7f, %.2f, 0, 03, 01\n", iLineNum,i+1, surveyRegionLons[i], surveyRegionLats[i], 0.0); fclose(fp); return true; }else { return false; } } // DesignSurveyLineDlg 消息处理程序 //导入航测区 void DesignSurveyLineDlg::OnBnClickedBtnInputregion() { //写航线 CString filename; CString strRouteFileDir = GetSoftwareCurrentDirectory() + _T("\\Route\\") + _T("测绘航线\\"); TCHAR s[10000]; s[0]=0; CFileDialog dlg(TRUE); dlg.m_ofn.lpstrTitle=_T("打开航测区域文件"); dlg.m_ofn.lpstrFile=s; dlg.m_ofn.nMaxFile=sizeof(s)/sizeof(TCHAR); TCHAR filter[500]=_T("航测区域文件(*.txt)\0*.txt\0所有文件(*.*)\0*.*\0"); dlg.m_ofn.lpstrFilter=filter; dlg.m_ofn.Flags|=OFN_HIDEREADONLY; dlg.m_ofn.lpstrInitialDir = strRouteFileDir; // 显示对话框并获取用户的选择 if (dlg.DoModal() == IDOK) { // 获取选择的文件路径 CString filePath = dlg.GetPathName(); g_regionPathName = filePath; g_regionFileName = extractFileName(dlg.GetFileName()); char* path = filePath.GetBuffer(); //发送消息到主程序,进行显示 if (g_mapHwnd != NULL) { ::SendMessage(g_mapHwnd, WM_SEND_SHOWSURVEYREGION, (WPARAM)path, 0); } GetDlgItem( IDC_BTN_CALCULATELINE )->EnableWindow( true ); } else { return; } } //绘制航测区 void DesignSurveyLineDlg::OnBnClickedBtnDrawregion() { bDrawRegion = true; } //保存航测区 void DesignSurveyLineDlg::OnBnClickedBtnSaveregion() { m_btnSaveRegion.EnableWindow(false); if (saveSurveyRegion(surveyRegionLons,surveyRegionLats)) { char* path = g_regionPathName.GetBuffer(); //发送消息到主程序,进行标绘 if (g_mapHwnd != NULL) { ::SendMessage(g_mapHwnd, WM_SEND_SHOWSURVEYREGION, (WPARAM)path, 0); } } m_btnSaveRegion.EnableWindow(true); } //装订测绘航线 void DesignSurveyLineDlg::OnBnClickedBtnBindline() { //发送消息到主程序,进行标绘 if (g_mapHwnd != NULL) { ::SendMessage(g_mapHwnd, WM_BIND_SURVEYLINE, (WPARAM)lineID, 0); } } //生成航测航线 void DesignSurveyLineDlg::OnBnClickedBtnCalculateline() { if (surveyRegionLats.size()<3) { BCGPMessageBox("航测区域无效或缺少航测区域!"); return; } CString cstr; GetDlgItemText(IDC_EDIT_HEIGHT,cstr); double height = _ttof(cstr); if (height<=0||height>500) { BCGPMessageBox("航高范围为(0,500]m!"); return; } GetDlgItemText(IDC_EDIT_LINEINTERVAL,cstr); double lineInterval = _ttof(cstr); if (lineInterval < 1 ) { BCGPMessageBox("航线间隔必须大于1m"); return; } GetDlgItemText(IDC_EDIT_EXTERNALLENGTH,cstr); double outLength = _ttof(cstr); if (outLength < 0 ) { BCGPMessageBox("外扩长度必须大于0m"); return; } g_Height = height; //测绘航线坐标 vector<double> surveyLineLons; vector<double> surveyLineLats; //计算航测航线 calculateSurveyLine(lineInterval,surveyLineLons,surveyLineLats,outLength); //保存航测航线 saveSurveyLine(surveyLineLons,surveyLineLats,height); //发送消息到主程序,进行标绘 if (g_mapHwnd != NULL) { char* path = g_linePathName.GetBuffer(); ::SendMessage(g_mapHwnd, WM_SEND_SHOWSURVEYLINE, (WPARAM)path, 0); } //计算航程 g_RouteLength = calculateRouteLength(surveyLineLons,surveyLineLats); cstr.Format("%d",int(g_RouteLength)); cstr += "m"; ((CStatic*)GetDlgItem(IDC_TXT_ROUTELENGTH))->SetWindowTextA(cstr); GetDlgItem( IDC_BTN_CALCULATETIME )->EnableWindow( true ); } void DesignSurveyLineDlg::OnClose() { CBCGPDialog::OnClose(); //发送消息到主程序,进行显示 if (g_mapHwnd != NULL) { ::SendMessage(g_mapHwnd, WM_CLEAR_TMPSURVEYFEATURE, 0, 0); } } //计算航程(m) double DesignSurveyLineDlg::calculateRouteLength(const vector<double>&surveyLineLons,const vector<double>& surveyLineLats) { double sum = 0; for (int i=0;i<surveyLineLons.size()-1;++i) { double dist; CalculateTwoPtsDistance(dist,surveyLineLons[i],surveyLineLats[i],surveyLineLons[i+1],surveyLineLats[i+1],3); sum += dist; } return sum; } //航时计算 void DesignSurveyLineDlg::OnBnClickedBtnCalculatetime() { CString cstr; GetDlgItemText(IDC_EDIT_FLYSPEED,cstr); double speed = _ttof(cstr); if (speed<1||speed>15) { BCGPMessageBox("飞行速度为[1,15]m/s!"); return; } int flyTime = g_RouteLength / speed; int hours = flyTime/3600; flyTime %= 3600; // 剩余秒数 int minutes = flyTime / 60; // 剩余秒数除以60得到分钟数 int seconds = flyTime % 60; // 最后剩余的秒数 cstr.Format("%d时%d分%d秒",hours,minutes,seconds); ((CStatic*)GetDlgItem(IDC_TXT_FLYTIME))->SetWindowTextA(cstr); }