diff --git a/GISControlDlg.rc b/GISControlDlg.rc index b7dd7e1..ff9385f 100644 --- a/GISControlDlg.rc +++ b/GISControlDlg.rc @@ -396,6 +396,22 @@ BEGIN COMBOBOX IDC_COMBO_DIRECTION,67,49,73,63,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP END +IDD_DLG_DESIGNSURVEYLINE DIALOGEX 0, 0, 195, 106 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "航测航线设计" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "航线高度(m):",IDC_STATIC,16,13,53,10 + EDITTEXT IDC_EDIT_HEIGHT,69,11,73,15,ES_AUTOHSCROLL,WS_EX_RIGHT + LTEXT "航线间隔(m):",IDC_STATIC,16,32,57,10 + EDITTEXT IDC_EDIT_LINEINTERVAL,69,29,73,15,ES_AUTOHSCROLL,WS_EX_RIGHT + PUSHBUTTON "导入航测区",IDC_BTN_INPUTREGION,10,55,55,18 + PUSHBUTTON "绘制航测区",IDC_BTN_DRAWREGION,69,55,55,18 + PUSHBUTTON "保存航测区",IDC_BTN_SAVEREGION,128,55,55,18 + PUSHBUTTON "装订航线",IDC_BTN_BINDLINE,10,77,55,18 + PUSHBUTTON "生成航线",IDC_BTN_CALCULATELINE,69,77,55,18 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -527,6 +543,14 @@ BEGIN TOPMARGIN, 2 BOTTOMMARGIN, 89 END + + IDD_DLG_DESIGNSURVEYLINE, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 191 + TOPMARGIN, 3 + BOTTOMMARGIN, 101 + END END #endif // APSTUDIO_INVOKED diff --git a/GISControlDlg.vcxproj b/GISControlDlg.vcxproj index ea0b5c2..4274d80 100644 --- a/GISControlDlg.vcxproj +++ b/GISControlDlg.vcxproj @@ -190,6 +190,7 @@ %(PreprocessorDefinitions) + @@ -209,6 +210,7 @@ %(PreprocessorDefinitions) %(PreprocessorDefinitions) + %(PreprocessorDefinitions) %(PreprocessorDefinitions) @@ -378,6 +380,7 @@ + @@ -385,6 +388,7 @@ + diff --git a/GISControlDlg.vcxproj.filters b/GISControlDlg.vcxproj.filters index 2149382..2e5444f 100644 --- a/GISControlDlg.vcxproj.filters +++ b/GISControlDlg.vcxproj.filters @@ -186,6 +186,12 @@ Source Files + + Source Files + + + Source Files + @@ -436,5 +442,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/GISDlg.cpp b/GISDlg.cpp index 1af8e90..80b836c 100644 --- a/GISDlg.cpp +++ b/GISDlg.cpp @@ -187,6 +187,11 @@ CGISDlg::CGISDlg(CWnd* pParent /*=NULL*/) m_designLinePointNum = 0; //当前航点个数 m_CircleGuideLayer = -1; //盘旋引导图层 + + /*******************************测绘航线********************************/ + surveyRegionLayerID = -1; + tmpSurveyRegionLayerID = -1; + tmpSurveyLineLayerID = -1; /*******************************新增限制区********************************/ //绘制禁飞区、限飞区 std::fill(noFlyZoneLayersID, noFlyZoneLayersID + 5, -1);//禁飞区 @@ -434,6 +439,12 @@ CGISDlg::~CGISDlg() m_gisManager->DestroyObject(); m_gisManager = NULL; } + + if (designSurveyLineDlg != nullptr) + { + delete designSurveyLineDlg; + designSurveyLineDlg = nullptr; + } } @@ -611,6 +622,10 @@ BEGIN_MESSAGE_MAP(CGISDlg, CBCGPDialog) ON_COMMAND(IDM_BIND_ZONE,OnBindZone) + /*****************************测绘航线*******************************/ + ON_MESSAGE(WM_SEND_SHOWSURVEYREGION, &CGISDlg::OnShowSurveyRegion) //显示测绘区域 + ON_MESSAGE(WM_SEND_SHOWSURVEYLINE, &CGISDlg::OnShowSurveyRegion) //显示测绘航线 + ON_MESSAGE(WM_CLEAR_TMPSURVEYFEATURE, &CGISDlg::OnClearTmpSurveyFeature) //显示测绘航线 END_MESSAGE_MAP() @@ -667,6 +682,10 @@ BOOL CGISDlg::OnInitDialog() m_dlgMarker.Create(IDD_DIALOG_MARKER,this); m_dlgMarker.MoveToGivenArea(m_gisAreaInScreen); + //创建航线航测对话框 + designSurveyLineDlg = new DesignSurveyLineDlg(); + designSurveyLineDlg->Create(IDD_DLG_DESIGNSURVEYLINE); + //地图显示区宽度、高度倒数 m_onePerWidth = 1.0/m_rcGISArea.Width(); m_onePerHeight = 1.0/m_rcGISArea.Height(); @@ -990,6 +1009,13 @@ void CGISDlg::OnMapFullScreen() m_bLDSetPoint = FALSE; m_bSelectFeatureFlag = false; + +/* + if (designSurveyLineDlg==nullptr) + { + designSurveyLineDlg = new DesignSurveyLineDlg(); + } + designSurveyLineDlg->ShowWindow(true);*/ } @@ -1904,6 +1930,16 @@ void CGISDlg::MouseDownMap1(short Button, short Shift, long x, long y) //TRACE(g_bSelectMarker); // return; } + + //绘制航测区域 + if (designSurveyLineDlg != nullptr && designSurveyLineDlg->bDrawRegion && (Button == 1)) + { + //像素坐标转换地理坐标 + m_map.PixelToProj(x,y, &dX, &dY); + + surveyRegionLons.push_back(dX); + surveyRegionLats.push_back(dY); + } if (m_bHaveShowDistanceDlg && (Button == 1)) { @@ -2695,6 +2731,28 @@ void CGISDlg::MouseDblClickMap1() } } + //结束绘制航测区 + if (designSurveyLineDlg != nullptr && designSurveyLineDlg->bDrawRegion) + { + designSurveyLineDlg->bDrawRegion = false; + if (surveyRegionLons.size()<3) //多边形无效 + { + surveyRegionLons.clear(); + surveyRegionLats.clear(); + return; + } + //添加原点闭合 + surveyRegionLons.push_back(surveyRegionLons[0]); + surveyRegionLats.push_back(surveyRegionLats[0]); + //显示测绘区域 + ShowSurveyRegion(tmpSurveyRegionLayerID,surveyRegionLons,surveyRegionLats); + m_map.Redraw(); + designSurveyLineDlg->SetSurveyRegion(surveyRegionLons,surveyRegionLats); + + surveyRegionLons.clear(); + surveyRegionLats.clear(); + } + } void CGISDlg::MouseMoveMap1(short Button, short Shift, long x, long y) @@ -2704,6 +2762,49 @@ void CGISDlg::MouseMoveMap1(short Button, short Shift, long x, long y) return; } + //绘制航测区域 + if (designSurveyLineDlg!= nullptr && designSurveyLineDlg->bDrawRegion) + { + double dX = 0; + double dY = 0; + m_map.PixelToProj(x,y, &dX, &dY); + + if ( 1 == surveyRegionLons.size()) //绘制直线 + { + if (m_tempLayerID!=-1) + { + m_map.ClearDrawing(m_tempLayerID); + m_tempLayerID = -1; + } + + m_tempLayerID = m_map.NewDrawing(1); + m_map.DrawLineEx(m_tempLayerID,surveyRegionLons[0],surveyRegionLats[0],dX,dY,2,RGB(255,0,0)); + m_map.Redraw(); + } + if (2 <= surveyRegionLons.size()) //绘制多边形 + { +/* + if ( 2 == surveyRegionLons.size()) + { + //添加实时点绘制多边形 + surveyRegionLons.push_back(dX); + surveyRegionLats.push_back(dY); + }*/ + if (m_tempLayerID!=-1) + { + m_map.ClearDrawing(m_tempLayerID); + m_tempLayerID = -1; + } + surveyRegionLons.push_back(dX); + surveyRegionLats.push_back(dY); + ShowSurveyRegion(tmpSurveyRegionLayerID,surveyRegionLons,surveyRegionLats); + m_map.Redraw(); + + surveyRegionLons.pop_back(); + surveyRegionLats.pop_back(); + } + } + //显示经纬度坐标时(地图定位) if (m_bHaveShowLonLatDlg && m_pLonLatDlg ->GetAutoEditStatus()) { @@ -3046,10 +3147,11 @@ void CGISDlg::MouseMoveMap1(short Button, short Shift, long x, long y) void CGISDlg::AddTextToPointShapeLayer(long &drawLayerID, const double lon, const double lat, const CString strPtName, const CString strColor, unsigned long fontColor) { //判断点矢量图层是否已经存在,存在则删除 - if (drawLayerID > 0) + if (drawLayerID >= 0) { //清除标绘的点矢量图层 ClearPointShape(drawLayerID); + drawLayerID = -1; } /////////////////////新建点矢量图层标绘点目标/////////////////////////////////// @@ -4975,8 +5077,36 @@ void CGISDlg::OnShowGivenLine(const CString strLineFileName) BCGPMessageBox("航线号不正确!"); return; } - + int ch = lineDataGroup.linePts[lineDataGroup.pointNum-1].ch1; + /***************************测绘区域处理************************************/ + if (ch == 0x03) + { + if (tmpSurveyRegionLayerID!=-1) + { + m_map.RemoveLayer(tmpSurveyRegionLayerID); + tmpSurveyRegionLayerID = -1; + } + + vector regionLons; + vector regionLats; + for (int i = 0;iSetSurveyRegion(regionLons,regionLats); + } + ShowSurveyRegion(surveyRegionLayerID,regionLons,regionLats); + return; + } + + /***************************限制区处理************************************/ if (ch==0x0D) //限飞区 { //ClearZoneLayer(restrictedZoneLayersID[lineDataGroup.lineID-1]); @@ -8105,6 +8235,113 @@ void CGISDlg::OnBindZone() } +//显示航测区域 +void CGISDlg::ShowSurveyRegion(long& layerID,vector& xPoints,vector& yPoints) +{ + if (layerID!=-1) + { + m_map.RemoveLayer(layerID); + layerID = -1; + } + + mapWindow::IShapePtr shapePtr; + shapePtr.CreateInstance("MapWinGIS.Shape"); + //创建面矢量shapfile + shapePtr->Create(mapWindow::SHP_POLYGON); + CreateEmptyShapfile(layerID,2,RGB(255,0,0)); + int nPoints = xPoints.size(); + for (long i=0; ix = xPoints[i]; + //纬度 + pintPtr->y = yPoints[i]; + shapePtr->InsertPoint(pintPtr, &i); + + //插入面矢量 + (m_map.GetShapefile(layerID)).EditInsertShape(shapePtr, &i); + } + mapWindow::IShapeDrawingOptionsPtr pShapeDrawingOption; + pShapeDrawingOption.CreateInstance("MapWinGIS.ShapeDrawingOptions"); + pShapeDrawingOption->LineColor = RGB(66,102,244);//RGB(212,212,252); + pShapeDrawingOption->FillColor = RGB(117,176,247);//RGB(0,255,255);//RGB(244,206,199); + + pShapeDrawingOption->LineWidth = 2; + pShapeDrawingOption->FillTransparency = 40; //透明度 + (m_map.GetShapefile(layerID)).SetDefaultDrawingOptions(pShapeDrawingOption); +} + +//显示航测航线 +void CGISDlg::ShowPolyline(long& layerID,vector& xPoints,vector& yPoints) +{ + if (layerID!=-1) + { + m_map.RemoveLayer(layerID); + layerID = -1; + } + + mapWindow::IShapePtr shapePtr; + shapePtr.CreateInstance("MapWinGIS.Shape"); + //创建面矢量shapfile + shapePtr->Create(mapWindow::SHP_POLYLINE); + CreateEmptyShapfile(layerID,1,RGB(255,0,0)); + int nPoints = xPoints.size(); + for (long i=0; ix = xPoints[i]; + //纬度 + pintPtr->y = yPoints[i]; + shapePtr->InsertPoint(pintPtr, &i); + + //插入面矢量 + (m_map.GetShapefile(layerID)).EditInsertShape(shapePtr, &i); + } + mapWindow::IShapeDrawingOptionsPtr pShapeDrawingOption; + pShapeDrawingOption.CreateInstance("MapWinGIS.ShapeDrawingOptions"); + pShapeDrawingOption->LineColor = RGB(212,212,252); + + pShapeDrawingOption->LineWidth = 2; + (m_map.GetShapefile(layerID)).SetDefaultDrawingOptions(pShapeDrawingOption); +} + +//显示测绘区域 +afx_msg LRESULT CGISDlg::OnShowSurveyRegion(WPARAM wParam, LPARAM lParam) +{ + CString path = (char*)wParam; + OnShowGivenLine(path); + //ShowSurveyRegion(surveyRegionLayerID,designSurveyLineDlg->surveyRegionLons,designSurveyLineDlg->surveyRegionLats); + return 0; +} + +//显示测绘区域 +afx_msg LRESULT CGISDlg::OnShowSurveyLine(WPARAM wParam, LPARAM lParam) +{ + CString path = (char*)wParam; + OnShowGivenLine(path); + //ShowSurveyRegion(surveyRegionLayerID,designSurveyLineDlg->surveyRegionLons,designSurveyLineDlg->surveyRegionLats); + return 0; +} + +//显示测绘区域 +afx_msg LRESULT CGISDlg::OnClearTmpSurveyFeature(WPARAM wParam, LPARAM lParam) +{ + if (tmpSurveyRegionLayerID!=-1) + { + m_map.RemoveLayer(tmpSurveyRegionLayerID); + tmpSurveyRegionLayerID = -1; + } + m_map.Redraw(); + return 0; +} + + diff --git a/GISDlg.h b/GISDlg.h index 6287eae..77b4a51 100644 --- a/GISDlg.h +++ b/GISDlg.h @@ -38,6 +38,7 @@ #include "../Include/8BMapDLL_type.h" #include "SaveZoneDlg.h" #include "circleguidence.h" +#include "designsurveylinedlg.h" using namespace B8MapDLL; #define MESSAGE_B8MAP WM_USER+750 @@ -958,6 +959,23 @@ public: //显示盘旋引导装订对话框 void OnShowCircleGuidenceDlg(); + /******************************航测航线*******************************/ + DesignSurveyLineDlg* designSurveyLineDlg; + //航测区域图层 + long surveyRegionLayerID; + long tmpSurveyRegionLayerID; + long tmpSurveyLineLayerID; + //航测点 + vector surveyRegionLons; + vector surveyRegionLats; + //显示航测区域 + afx_msg LRESULT OnShowSurveyRegion(WPARAM wParam,LPARAM lParam); + afx_msg LRESULT OnShowSurveyLine(WPARAM wParam,LPARAM lParam); + afx_msg LRESULT OnClearTmpSurveyFeature(WPARAM wParam,LPARAM lParam); + void ShowSurveyRegion(long& layerID,vector& xPoints,vector& yPoints); + //显示航测航线 + void ShowPolyline(long& layerID,vector& xPoints,vector& yPoints); + }; //{{AFX_INSERT_LOCATION}} diff --git a/Globe.h b/Globe.h index cc2e9de..e4fbdc7 100644 --- a/Globe.h +++ b/Globe.h @@ -57,6 +57,14 @@ const UINT WM_SEND_MAPLOCATION = WM_USER+1088; // const UINT WM_SEND_MAPCURSORMODE = WM_USER+1089; //设置Map CursorMode +const UINT WM_SEND_SHOWSURVEYLINE = WM_USER+1090; //显示测绘航线 + +const UINT WM_SEND_SHOWSURVEYREGION = WM_USER+1091; //显示测绘区域 + +const UINT WM_BIND_SURVEYLINE = WM_USER+1092; //装订测绘航线 + +const UINT WM_CLEAR_TMPSURVEYFEATURE = WM_USER+1093; //清除临时测绘要素 + /////////////////////////////////////////////////////////消息定义//////////////////////////////////////////////////////////// diff --git a/TopologicalAnalysis.cpp b/TopologicalAnalysis.cpp index d42d155..59da569 100644 --- a/TopologicalAnalysis.cpp +++ b/TopologicalAnalysis.cpp @@ -231,3 +231,108 @@ bool TopologicalAnalysis::isLineIntersect(CPoint1 line1Start, CPoint1 line1End, } return true; } + + +bool TopologicalAnalysis::GetBoundingBoxVertices(const vector& polygonX,const vector& polygonY,vector& rectangleX,vector& rectangleY) +{ + if (polygonX.size()<3 || polygonY.size()<3) return false; + + //计算最大最小x和y + double minX = polygonX[0]; + double minY = polygonY[0]; + double maxX = polygonX[0]; + double maxY = polygonY[0]; + + for (int i=0;i maxX) maxX = polygonX[i]; + if (polygonY[i] > maxY) maxY = polygonY[i]; + } + + rectangleX.push_back(minX); + rectangleX.push_back(maxX); + rectangleX.push_back(maxX); + rectangleX.push_back(minX); + + rectangleY.push_back(maxY); + rectangleY.push_back(maxY); + rectangleY.push_back(minY); + rectangleY.push_back(minY); +} + +//计算直线与多边形的交点 +void TopologicalAnalysis::linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector& polygonX,const vector& polygonY, vector& result) +{ + Line2D line1; + line1.p1 = linePt1; + line1.p2 = linePt2; + Point2D intersectionPt; + vector resPoints; + for (int i=0;i0) + { + //获取最左或者最右的两个点,忽略凹多边形中间交点 + double minX = resPoints[0].x; + double maxX = resPoints[0].x; + int minIndex = 0; + int maxIndex = 0; + + for (int i=0;i maxX) maxIndex = i; + } + result.push_back(resPoints[minIndex]); + result.push_back(resPoints[maxIndex]); + } + +} + +// 判断两条线段是否相交 +int TopologicalAnalysis::isLineIntersecting(const Line2D& l1, const Line2D& l2, Point2D& intersection) { + float numera = (l2.p2.x-l2.p1.x) * (l1.p1.y-l2.p1.y) - (l2.p2.y-l2.p1.y) * (l1.p1.x-l2.p1.x); + float numerb = (l1.p2.x-l1.p1.x) * (l1.p1.y-l2.p1.y) - (l1.p2.y-l1.p1.y) * (l1.p1.x-l2.p1.x); + + float denom = (l2.p2.y-l2.p1.y) * (l1.p2.x-l1.p1.x) - (l2.p2.x-l2.p1.x) * (l1.p2.y-l1.p1.y); + + if(denom == 0.0f) + { + if(numera == 0.0f && numerb == 0.0f) + { + intersection.x = l2.p2.x; + intersection.y = l2.p2.y; + return 2; //重合 + } + return 3; //平行 + } + + float ua = numera / denom; + float ub = numerb / denom; + + if(ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) + { + intersection.x = l1.p1.x + ua*(l1.p2.x - l1.p1.x); + intersection.y = l1.p1.y + ua*(l1.p2.y - l1.p1.y); + + return 1; //相交 + } + + return 0; //不相交 +} diff --git a/TopologicalAnalysis.h b/TopologicalAnalysis.h index 79acd10..1f06709 100644 --- a/TopologicalAnalysis.h +++ b/TopologicalAnalysis.h @@ -1,8 +1,29 @@ #pragma once #include #include "point.h" +#include +#include +#include +#include "geocompute.h" using namespace std; +struct Point2D { + double x, y; +}; + +struct Line2D { + Point2D p1, p2; +}; + +struct Rectangle2D { + Point2D vertices[4]; + double area() const { + double width = std::sqrt(std::pow(vertices[1].x - vertices[0].x, 2) + std::pow(vertices[1].y - vertices[0].y, 2)); + double height = std::sqrt(std::pow(vertices[2].x - vertices[1].x, 2) + std::pow(vertices[2].y - vertices[1].y, 2)); + return width * height; + } +}; + class TopologicalAnalysis { public: @@ -29,4 +50,16 @@ public: //计算一组CPoint1的最大X double getMaxX(vector points); + + //获取多边形外包矩形 + bool GetBoundingBoxVertices(const vector& polygonX,const vector& polygonY,vector& rectangleX,vector& rectangleY); + + //计算直线与多边形的交点 + void linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector& polygonX,const std::vector& polygonY,std::vector& result); + +private: + // 判断两条线段是否相交 + int isLineIntersecting(const Line2D& l1, const Line2D& l2, Point2D& intersection); }; + + diff --git a/designsurveylinedlg.cpp b/designsurveylinedlg.cpp new file mode 100644 index 0000000..ca1df9f --- /dev/null +++ b/designsurveylinedlg.cpp @@ -0,0 +1,354 @@ +// 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; +} + +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() +END_MESSAGE_MAP() + +BOOL DesignSurveyLineDlg::OnInitDialog() +{ + CBCGPDialog::OnInitDialog(); + CenterWindow(); + GetDlgItem( IDC_BTN_CALCULATELINE )->EnableWindow( false ); + + 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& lons,const vector& lats) +{ + for (int i=0;iEnableWindow( true ); +} + +//计算测绘航线 +void DesignSurveyLineDlg::calculateSurveyLine(double lineInterval,vector&surveyLineLons,vector& surveyLineLats) +{ + vector recLons; + vector recLats; + TopologicalAnalysis analysis; + GeoCompute geocompute; + analysis.GetBoundingBoxVertices(surveyRegionLons,surveyRegionLats,recLons,recLats); + double lon1,lat1,lon2,lat2; + //第一条切割线为航线间隔一半 + geocompute.computeOffsetGeoPosition(recLons[0],recLats[0],180,lineInterval/2000,lon1,lat1); + geocompute.computeOffsetGeoPosition(recLons[1],recLats[1],180,lineInterval/2000,lon2,lat2); + Point2D pt1,pt2; + pt1.x = lon1; + pt1.y = lat1; + pt2.x = lon2; + pt2.y = lat2; + vector result; + analysis.linePolygonIntersections(pt1,pt2,surveyRegionLons,surveyRegionLats,result); + + while(lat1>recLats[2]){ + //平移切割线 + geocompute.computeOffsetGeoPosition(lon1,lat1,180,lineInterval/1000,lon1,lat1); + geocompute.computeOffsetGeoPosition(lon2,lat2,180,lineInterval/1000,lon2,lat2); + pt1.x = lon1; + pt1.y = lat1; + pt2.x = lon2; + pt2.y = lat2; + //计算交点 + analysis.linePolygonIntersections(pt1,pt2,surveyRegionLons,surveyRegionLats,result); + } + //串联交点 + int j = 1; + for (int i=0;i&surveyLineLons,const vector& 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 + "-测绘航线.route"; + CFileDialog dlg(FALSE, _T(".route"), defaultName); + 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_linePathName = filename; + g_lineFileName = extractFileName(dlg.GetFileName()); + + FILE* fp = fopen(filename,"w"); + int iLineNum = 5; + 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,const vector& surveyRegionLats) +{ + //写航线 + CString filename; + CString strRouteFileDir = GetSoftwareCurrentDirectory() + _T("\\Route\\") + _T("测绘航线\\"); + //测绘航线文件夹不存在则创建 + if (!SearchDirectory(strRouteFileDir)) + { + CreateDirectory(strRouteFileDir); + } + + TCHAR s[10000]; + s[0]=0; + CFileDialog dlg(FALSE, _T(".txt"), _T("测绘区域1.txt")); + 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_regionPathName = filename; + g_regionFileName = extractFileName(dlg.GetFileName()); + + FILE* fp = fopen(filename,"w"); + int iLineNum = 5; + fprintf(fp,"%d, 0, %.7f, %.7f, %.2f, 0, 00, 03\n", iLineNum, 0.0, 0.0, 0.0); + int i = 0; + for (i;iEnableWindow( 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() +{ + // TODO: 在此添加控件通知处理程序代码 +} + +//生成航测航线 +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; + } + + g_Height = height; + //测绘航线坐标 + vector surveyLineLons; + vector surveyLineLats; + //计算航测航线 + calculateSurveyLine(lineInterval,surveyLineLons,surveyLineLats); + //保存航测航线 + saveSurveyLine(surveyLineLons,surveyLineLats,height); + //发送消息到主程序,进行标绘 + if (g_mapHwnd != NULL) + { + char* path = g_linePathName.GetBuffer(); + ::SendMessage(g_mapHwnd, WM_SEND_SHOWSURVEYLINE, (WPARAM)path, 0); + } +} + +void DesignSurveyLineDlg::OnClose() +{ + CBCGPDialog::OnClose(); + + //发送消息到主程序,进行显示 + if (g_mapHwnd != NULL) + { + ::SendMessage(g_mapHwnd, WM_CLEAR_TMPSURVEYFEATURE, 0, 0); + } +} diff --git a/designsurveylinedlg.h b/designsurveylinedlg.h new file mode 100644 index 0000000..d3828b3 --- /dev/null +++ b/designsurveylinedlg.h @@ -0,0 +1,58 @@ +#pragma once +#include "Resource.h" +#include +#include "topologicalanalysis.h" +#include "geocompute.h" +#include "Globe.h" +#include "afxwin.h" + +// DesignSurveyLineDlg 对话框 + +// DesignSurveyLineDlg 对话框 +class DesignSurveyLineDlg : public CBCGPDialog +{ + DECLARE_DYNAMIC(DesignSurveyLineDlg) + +public: + DesignSurveyLineDlg(CWnd* pParent = NULL); // 标准构造函数 + virtual ~DesignSurveyLineDlg(); + + bool bDrawRegion; + void SetSurveyRegion(const vector& lons,const vector& lats); + //测绘区域坐标 + vector surveyRegionLons; + vector surveyRegionLats; + + // 对话框数据 + enum { IDD = IDD_DLG_DESIGNSURVEYLINE }; + +private: + void calculateSurveyLine(double lineInterval,vector&surveyLineLons,vector& surveyLineLats);//计算测绘航线 + void saveSurveyLine(const vector&surveyLineLons,const vector& surveyLineLats,double height); //保存测绘航线 + bool saveSurveyRegion(const vector&surveyRegionLons,const vector& surveyRegionLats); //保存航测区域 + //测绘航线坐标 + vector surveyLineLons; + vector surveyLineLats; + double g_Height; + + // 测绘区域文件路径 + CString g_regionPathName; + CString g_regionFileName; + CString g_linePathName; + CString g_lineFileName; + + CString extractFileName(CString fileName); //提取没有后缀名的文件名 +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + afx_msg void OnBnClickedBtnInputregion(); + afx_msg void OnBnClickedBtnDrawregion(); + afx_msg void OnBnClickedBtnSaveregion(); + afx_msg void OnBnClickedBtnBindline(); + afx_msg void OnBnClickedBtnCalculateline(); + afx_msg void OnClose(); + CBCGPButton m_btnSaveRegion; +}; diff --git a/geocompute.cpp b/geocompute.cpp new file mode 100644 index 0000000..ee54370 --- /dev/null +++ b/geocompute.cpp @@ -0,0 +1,12 @@ +#include "stdafx.h" +#include "geocompute.h" + + +GeoCompute::GeoCompute(void) +{ +} + + +GeoCompute::~GeoCompute(void) +{ +} diff --git a/geocompute.h b/geocompute.h new file mode 100644 index 0000000..758f9f0 --- /dev/null +++ b/geocompute.h @@ -0,0 +1,74 @@ +#pragma once +#include +#include +using namespace std; +#define PI 3.14159265358979323846 +class GeoCompute +{ +public: + GeoCompute(void); + ~GeoCompute(void); + + /*@brief 根据起点坐标、方位角、距离,计算另一点坐标。 + * 使用Vincenty's公式求解,使用WGS-84椭球 + * startPoint:起始点地理坐标点(lat(-90到90),lon(-180,180)) + * bearing:方位角(度) + * dist:两点之间距离(km) + */ + void GeoCompute::computeOffsetGeoPosition(double lon1, double lat1, double bearing, double dist,double& targetLon,double& targetLat) + { + //角度转化为弧度 + // qreal lon1 = (fmod(startPoint.x()+540,360)-180.0)*PI/180; + lon1 = lon1*PI/180.0; + lat1 = lat1*PI/180.0; + bearing = bearing*PI/180.0; + dist = dist*1000; + + //WGS-84椭球参数 + double flat = 298.257223563; + double a = 6378137.0; + double b = 6356752.314245; + //开始求解坐标 + double f = 1/flat; + double sb = sin(bearing); + double cb = cos(bearing); + double tu1 = (1-f)*tan(lat1); + double cu1 = 1/sqrt((1+tu1*tu1)); + double su1 = tu1*cu1; + double s2 = atan2(tu1, cb); + double sa = cu1*sb; + double csa = 1-sa*sa; + double us = csa*(a*a - b*b)/(b*b); + double A = 1+us/16384*(4096+us*(-768+us*(320-175*us))); + double B = us/1024*(256+us*(-128+us*(74-47*us))); + double s1 = dist/(b*A); + double s1p = 2*PI; + + + double cs1m = 0.0; + double ss1 = 0.0; + double cs1 = 0.0; + double ds1 = 0.0; + + while (abs(s1-s1p) > 1e-12) + { + cs1m = cos(2*s2+s1); + ss1 = sin(s1); + cs1 = cos(s1); + ds1 = B*ss1*(cs1m+B/4*(cs1*(-1+2*cs1m*cs1m)- B/6*cs1m*(-3+4*ss1*ss1)*(-3+4*cs1m*cs1m))); + s1p = s1; + s1 = dist/(b*A)+ds1; + } + + double t = su1*ss1-cu1*cs1*cb; + double lat2 = atan2(su1*cs1+cu1*ss1*cb, (1-f)*sqrt(sa*sa + t*t)); + double l2 = atan2(ss1*sb, cu1*cs1-su1*ss1*cb); + double c = f/16*csa*(4+f*(4-3*csa)); + double l = l2-(1-c)*f*sa* (s1+c*ss1*(cs1m+c*cs1*(-1+2*cs1m*cs1m))); + double lon2 = lon1+l; + + targetLon = lon2*180/PI; + targetLat = lat2*180/PI; + } +}; + diff --git a/resource.h b/resource.h index deee5a5..aa693df 100644 --- a/resource.h +++ b/resource.h @@ -42,16 +42,21 @@ #define IDC_BUTTON_ADD_TARGET2 1002 #define IDC_BUTTON_SELECT_TARGET 1002 #define IDC_BUTTON_ADDMARKER 1002 +#define IDC_BTN_DRAWREGION 1002 #define IDC_ADD_FLYLINE 1003 #define IDB_BITMAP_ZOOMIN 1003 #define IDC_BTN_DELETE_POINT 1003 +#define IDC_BTN_SAVEREGION 1003 #define IDC_LAYER_MANAGE 1004 #define IDB_BITMAP_ADD_FLYLINE 1004 #define IDC_BUTTON_DELETEMARKER 1004 +#define IDC_BTN_BINDLINE 1004 #define IDC_REMOVE_LAYERS 1005 #define IDB_BITMAP_ADD_SHPFILE 1005 +#define IDC_BTN_CALCULATELINE 1005 #define IDC_SELECT_ITEM 1006 #define IDB_BITMAP_ADD_IMGFILE 1006 +#define IDC_BTN_SAVELINE2 1006 #define IDC_ZOOM_IN 1007 #define IDB_BITMAP_RULER 1007 #define IDC_EDIT_LAT 1007 @@ -150,6 +155,7 @@ #define IDC_COMBO_ZONETYPE 1051 #define IDC_EDIT_RADIUS 1052 #define IDC_COMBO_DIRECTION 1053 +#define IDC_EDIT_LINEINTERVAL 1054 #define IDC_EDIT_MARKER_LON 1055 #define IDR_TOOLBAR3 1056 #define IDC_EDIT_MARKER_LAT 1056 @@ -230,6 +236,8 @@ #define IDB_BITMAP41 1154 #define IDD_DIALOG_ZONESETTING 1169 #define IDD_DLG_CIRCLEGUIDENCE 1170 +#define IDC_BTN_INPUTREGION 1172 +#define IDD_DLG_DESIGNSURVEYLINE 1172 #define IDT_GIS_CTRL_BUTTON1 1231 #define IDT_GIS_CTRL_BUTTON2 1232 #define IDT_GIS_CTRL_BUTTON3 1233 @@ -410,9 +418,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 1172 +#define _APS_NEXT_RESOURCE_VALUE 1173 #define _APS_NEXT_COMMAND_VALUE 32940 -#define _APS_NEXT_CONTROL_VALUE 1054 +#define _APS_NEXT_CONTROL_VALUE 1055 #define _APS_NEXT_SYMED_VALUE 1000 #endif #endif