DlgCreateContour.cpp
上传用户:juying163
上传日期:2014-09-24
资源大小:5867k
文件大小:13k
源码类别:

GIS编程

开发平台:

Visual C++

  1. // DlgCreateContour.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "3D0214.h"
  5. #include "DlgCreateContour.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CDlgCreateContour dialog
  13. CDlgCreateContour::CDlgCreateContour(CWnd* pParent /*=NULL*/)
  14. : CDialog(CDlgCreateContour::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CDlgCreateContour)
  17. m_edit_Contour_SurfaceInput = _T("");
  18. m_edit_ContourFeatureOutput = _T("");
  19. m_edit_Contour_MaxContour = 0.0;
  20. m_edit_Contour_MinContour = 0.0;
  21. m_edit_ContourZMax_in = 0.0;
  22. m_edit_ContourZMin_in = 0.0;
  23. m_edit_ContourTotalNumContour = 0;
  24. //}}AFX_DATA_INIT
  25. }
  26. void CDlgCreateContour::DoDataExchange(CDataExchange* pDX)
  27. {
  28. CDialog::DoDataExchange(pDX);
  29. //{{AFX_DATA_MAP(CDlgCreateContour)
  30. DDX_Control(pDX, IDC_EDIT_CONTOUR_CONTOURINTERVAL, m_edit_Contour_ContourInterval);
  31. DDX_Control(pDX, IDC_EDIT_CONTOUR_BASECONTOUR, m_edit_ContourBaseContour);
  32. DDX_Text(pDX, IDC_EDIT_CONTOUR_SURFACE_INPUT, m_edit_Contour_SurfaceInput);
  33. DDX_Text(pDX, IDC_EDIT_CONTOUR_FEATURE_OUTPUT, m_edit_ContourFeatureOutput);
  34. DDX_Text(pDX, IDC_EDIT_CONTOUR_MAXCONTOUR, m_edit_Contour_MaxContour);
  35. DDX_Text(pDX, IDC_EDIT_CONTOUR_MINCONTOUR, m_edit_Contour_MinContour);
  36. DDX_Text(pDX, IDC_EDIT_CONTOUR_ZMAX, m_edit_ContourZMax_in);
  37. DDX_Text(pDX, IDC_EDIT_CONTOUR_ZMIN, m_edit_ContourZMin_in);
  38. DDX_Text(pDX, IDC_EDIT_CONTOUR_TOTALNUMCONTOUR, m_edit_ContourTotalNumContour);
  39. //}}AFX_DATA_MAP
  40. }
  41. BEGIN_MESSAGE_MAP(CDlgCreateContour, CDialog)
  42. //{{AFX_MSG_MAP(CDlgCreateContour)
  43. ON_BN_CLICKED(IDC_BUTTON_CONTOUR_FEATURE_OUTPUT, OnButtonContourFeatureOutput)
  44. ON_BN_CLICKED(IDC_BUTTON_CONTOUR_SURFACE_INPUT, OnButtonContourSurfaceInput)
  45. ON_EN_CHANGE(IDC_EDIT_CONTOUR_BASECONTOUR, OnChangeEditContourBasecontour)
  46. ON_EN_CHANGE(IDC_EDIT_CONTOUR_CONTOURINTERVAL, OnChangeEditContourContourinterval)
  47. //}}AFX_MSG_MAP
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CDlgCreateContour message handlers
  51. void CDlgCreateContour::OnButtonContourFeatureOutput() 
  52. {
  53. // TODO: Add your control notification handler code here
  54. IGxDialogPtr ipGxDialog( CLSID_GxDialog);
  55. //FeatureClasses
  56. IGxObjectFilterPtr ipGxObjectFilter(CLSID_GxFilterFeatureClasses);
  57. HRESULT hr=ipGxDialog->putref_ObjectFilter( ipGxObjectFilter);
  58. if(FAILED(hr)) return;
  59. hr = ipGxDialog->put_Title(CComBSTR("保存等高线"));
  60. if(FAILED(hr)) return;
  61. VARIANT_BOOL bResult;
  62.     IEnumGxObjectPtr ipEnumGxObject;
  63. OLE_HANDLE hwnd=(OLE_HANDLE)this->GetSafeHwnd();
  64. hr=ipGxDialog->DoModalOpen(0,&ipEnumGxObject,&bResult);
  65. if(FAILED(hr)) return;
  66. if(bResult==VARIANT_FALSE)return;
  67. IGxObjectPtr ipGxObject;
  68. ipGxDialog->get_FinalLocation(&ipGxObject); 
  69. CComBSTR path;
  70. ipGxObject->get_FullName(&path);
  71. m_OutputFeatureDir=CString(path);
  72. CComBSTR name;
  73. ipGxDialog->get_Name(&name);
  74. m_OutputFeatureName=CString(name);
  75. //    m_edit_ContourFeatureOutput;
  76. // m_OutputFeatureDir+"\"+m_OutputFeatureName;
  77. UpdateData(FALSE);
  78. }
  79. void CDlgCreateContour::OnButtonContourSurfaceInput() 
  80. {
  81. // TODO: Add your control notification handler code here
  82. IGxDialogPtr ipGxDialog( CLSID_GxDialog);
  83. IGxObjectFilterPtr ipGxObjectFilter( CLSID_GxFilterSurfaceDatasets);
  84. HRESULT hr=ipGxDialog->putref_ObjectFilter(ipGxObjectFilter);
  85. if(FAILED(hr)) return;
  86. hr=ipGxDialog->put_Title(CComBSTR ("选择一个DEM表面数据"));
  87. if(FAILED( hr)) return;
  88. IEnumGxObjectPtr ipEnumGxObject;
  89. VARIANT_BOOL bResult;
  90. hr=ipGxDialog->DoModalOpen(0,&ipEnumGxObject,&bResult);
  91. if(FAILED(hr)) return;
  92. if(bResult==VARIANT_FALSE)return;
  93. hr=ipEnumGxObject->Reset();
  94. if(FAILED(hr)) return;
  95. IGxObjectPtr ipGxObject;
  96. ipGxDialog->get_FinalLocation(&ipGxObject);
  97. CComBSTR path;
  98. ipGxObject->get_FullName(&path);
  99. m_edit_Contour_SurfaceInput=CString(path);
  100. while(!ipEnumGxObject->Next(&ipGxObject))
  101. {
  102. IGxDatasetPtr ipGxDataset(ipGxObject);
  103. if(ipGxDataset!=0)
  104. {    
  105. IDatasetPtr ipDataset;    
  106. hr=ipGxDataset->get_Dataset(&ipDataset);    
  107. if(FAILED(hr)) return;
  108. IRasterDatasetPtr ipRasterDataset(ipDataset);
  109. if(ipRasterDataset!=NULL)
  110. {
  111. m_ipR=ipRasterDataset;
  112. CComBSTR bstrName;
  113. hr=ipRasterDataset->get_CompleteName(&bstrName);
  114. if(FAILED(hr)) return;
  115. m_edit_Contour_SurfaceInput= bstrName;
  116. }
  117.      ITinPtr ipTin(ipDataset);
  118.     ITinSurfacePtr ipTS(ipDataset);
  119.     if ( ipTin!=NULL)
  120. {
  121.     
  122. m_ipT=ipTin;    
  123. m_ipTS=ipTS;      
  124. CComBSTR bstrName;    
  125. hr=ipDataset->get_Name(&bstrName);    
  126. if(FAILED(hr )) return;    
  127. m_edit_Contour_SurfaceInput=CString(bstrName);
  128. }
  129.    UpdateData(FALSE);
  130.    if(ipRasterDataset!=NULL)  
  131.    {
  132.          ComputerHeightRange(ipRasterDataset);  
  133.    }
  134.   
  135.    if(ipTin!=NULL)  
  136.    {
  137.        ComputerHeightRange(ipTin);
  138.    }
  139. }
  140. }
  141. }
  142. void CDlgCreateContour::OnOK() 
  143. {
  144. // TODO: Add extra validation here
  145. UpdateData(TRUE);
  146. if(m_ipR!=NULL)
  147. {
  148. CreateContour(m_ipR);
  149. }
  150. if(m_ipT!=NULL)
  151. {
  152. CreateContour();
  153. }
  154. CDialog::OnOK();
  155. }
  156. void CDlgCreateContour::OnChangeEditContourBasecontour() 
  157. {
  158. // TODO: If this is a RICHEDIT control, the control will not
  159. // send this notification unless you override the CDialog::OnInitDialog()
  160. // function and call CRichEditCtrl().SetEventMask()
  161. // with the ENM_CHANGE flag ORed into the mask.
  162. // TODO: Add your control notification handler code here
  163. if(m_ipT!=NULL || m_ipR!=NULL)
  164.  
  165. {    
  166. CString str;    
  167. m_edit_Contour_ContourInterval.GetWindowText(str);    
  168. double interval=atof(str);
  169. m_edit_ContourBaseContour.GetWindowText(str);
  170. double base=atof ( str );
  171. ComputerOutputInfo(m_edit_ContourZMax_in,
  172.                           m_edit_ContourZMin_in,
  173.                           interval,
  174.                            base);
  175. }
  176. }
  177. void CDlgCreateContour::OnChangeEditContourContourinterval() 
  178. {
  179. // TODO: If this is a RICHEDIT control, the control will not
  180. // send this notification unless you override the CDialog::OnInitDialog()
  181. // function and call CRichEditCtrl().SetEventMask()
  182. // with the ENM_CHANGE flag ORed into the mask.
  183. // TODO: Add your control notification handler code here
  184. if(m_ipT!=NULL || m_ipR!=NULL)
  185. {
  186.         CString str;
  187.         m_edit_Contour_ContourInterval.GetWindowText(str);
  188.         double interval=atof (str);
  189.         m_edit_ContourBaseContour.GetWindowText(str);
  190.         double base=atof ( str);
  191.         ComputerOutputInfo(m_edit_ContourZMax_in,
  192.                             m_edit_ContourZMin_in,
  193.                            interval,
  194.                            base);
  195. }
  196. }
  197. void CDlgCreateContour::ComputerHeightRange(IRasterDataset * pRasterDataset)
  198. {   //如何计算RasterDataset 的统计信息
  199. HRESULT hr;
  200. IRasterBandCollectionPtr pRasterBC(pRasterDataset);
  201. IRasterBandPtr pRasterB;
  202. hr=pRasterBC->Item(0,&pRasterB);
  203. IRasterStatisticsPtr pRasterS;
  204. hr=pRasterB->get_Statistics(&pRasterS);
  205. hr=pRasterS->get_Maximum(&m_edit_ContourZMax_in);
  206. if(FAILED(hr )) return;
  207. hr=pRasterS->get_Minimum(&m_edit_ContourZMin_in);
  208.     UpdateData(FALSE);
  209. }
  210. void CDlgCreateContour::ComputerHeightRange(ITin *ipT)
  211. {   //如何计算Tin的空间范围统计信息
  212.    HRESULT hr;
  213.     IEnvelopePtr ipEnv;
  214.     m_ipT->get_Extent(&ipEnv); 
  215. hr= ipEnv->get_ZMin(&m_edit_ContourZMax_in);
  216. if(FAILED(hr ))return; 
  217. hr=ipEnv->get_ZMax(&m_edit_ContourZMax_in); 
  218. UpdateData(FALSE);
  219. }
  220. void CDlgCreateContour::ComputerOutputInfo(double Zmax,double Zmin,double interval,double base)
  221. {
  222.    if(interval==0)
  223.     {
  224.         AfxMessageBox("请不要把间隔设置为0");
  225.         return;
  226.     }
  227.     if(base>Zmin)
  228.     {
  229.           int  N=1;
  230.         for( int i=0;i<N;i++)
  231.         {
  232.             double temp= base-i *interval-Zmin;
  233.             if(temp<=interval&&temp>=0)
  234.               {
  235.                   N=1;
  236.                   m_edit_Contour_MinContour=base-i*interval;
  237.               }
  238. else{
  239. N=i+2;}
  240. }
  241. }
  242.     else
  243. {
  244. int N = 1;
  245. for( int i=0;i<N;i++)
  246. {
  247. double temp =base+i*interval-Zmin;
  248. if(temp<=interval&&temp>=0)
  249. {
  250. N=i;
  251. m_edit_Contour_MinContour=base+i*interval;
  252. }
  253.     else
  254. {
  255. N=i+2;
  256. }
  257. }
  258. }
  259. if(base>Zmax)
  260. {
  261. int N=1;
  262. for( int i=0;i<N;i++)
  263. {
  264. double temp=Zmax-(base-i*interval);
  265. if(temp<=interval&&temp>=0)
  266. {
  267. N=i;
  268. m_edit_Contour_MaxContour=base-i*interval;
  269. }        
  270. else
  271. {              
  272. N=i+2;
  273. }
  274. }
  275. }
  276. else
  277. {
  278. int N=1;
  279. for( int i=0;i<N;i++)
  280. {
  281.     
  282. double temp= Zmax-(base+i*interval);
  283.     
  284. if(temp<= interval&&temp>=0)
  285.     
  286. {
  287.           
  288. N=3;
  289.           
  290. m_edit_Contour_MaxContour = base+i*interval;
  291.       
  292. }
  293.       
  294. else
  295. {
  296. N=i+2; 
  297. }
  298.           
  299. m_edit_ContourTotalNumContour=
  300. (m_edit_Contour_MaxContour-m_edit_Contour_MinContour)/interval+1;
  301. UpdateData(FALSE);
  302. }
  303. }
  304. }
  305. void CDlgCreateContour::CreateContour()
  306. {
  307. //先创建featureclass对象,用于等高线的输出
  308. HRESULT hr;
  309. CString strShapeFieldName="Shape";
  310. //打开一个存在的文件夹作为工作区Workspace
  311. IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_ShapefileWorkspaceFactory);
  312. IWorkspacePtr ipWorkspace;
  313. hr=ipWorkspaceFactory->OpenFromFile((CComBSTR)m_OutputFeatureDir,0,&ipWorkspace);
  314. if( FAILED(hr)) return;
  315. IFeatureWorkspacePtr ipFeatWorkspace(ipWorkspace);
  316. //创建Fields对象集
  317. IFieldsPtr ipFields(CLSID_Fields);
  318. IFieldsEditPtr ipFieldsEdit(ipFields);
  319. //创建Shape字段
  320. //it will need a geometry definition,with a spatial reference
  321. IFieldPtr ipField(CLSID_Field);
  322. IFieldEditPtr ipFieldEdit( ipField);
  323. hr=ipFieldEdit->put_Name((CComBSTR)strShapeFieldName);
  324. if ( FAILED(hr)) return;
  325. hr=ipFieldEdit->put_Type(esriFieldTypeGeometry);
  326. if( FAILED(hr)) return;
  327. IGeometryDefPtr ipGeomDef ( CLSID_GeometryDef );
  328. IGeometryDefEditPtr ipGeomDefEdit(ipGeomDef );
  329. ISpatialReferencePtr ipSpatialRef( CLSID_UnknownCoordinateSystem);
  330. hr=ipGeomDefEdit->put_GeometryType(esriGeometryPolyline);
  331. if ( FAILED(hr)) return;
  332. hr=ipGeomDefEdit->putref_SpatialReference( ipSpatialRef );
  333. if ( FAILED(hr)) return;
  334. hr=ipFieldEdit->putref_GeometryDef( ipGeomDef );
  335. if ( FAILED(hr )) return;
  336. hr=ipFieldsEdit->AddField(ipField);
  337. if ( FAILED(hr)) return;
  338. //创建Shapefile(一些参数默认为NULL)
  339. IFeatureClassPtr   ipFeatureClass;
  340. hr=ipFeatWorkspace->CreateFeatureClass((CComBSTR)m_OutputFeatureName,
  341.                                     ipFields,
  342.                                                     NULL,
  343.                                                     NULL,
  344.                                                     esriFTSimple,
  345.                                                     (CComBSTR)strShapeFieldName,
  346.                                                     (CComBSTR)"",
  347.                                                     &ipFeatureClass);
  348. if ( FAILED(hr )) return;
  349. if ( ipFeatureClass==NULL)return;
  350. CString str;
  351. m_edit_Contour_ContourInterval.GetWindowText(str);
  352. double interval=atof ( str );
  353. m_edit_ContourBaseContour. GetWindowText(str);
  354. double base=atof(str);
  355. hr=m_ipTS->Contour(base,interval,ipFeatureClass,CComBSTR("Contour"),0);
  356. if(FAILED(hr))
  357. {
  358. if(hr==-2147467259)
  359. {
  360. AfxMessageBox("等高线恢复无法进行,请更换表面数据!");
  361. }
  362. return;
  363. }
  364. AfxMessageBox ("成功!");
  365. }
  366. void CDlgCreateContour::CreateContour( IRasterDataset*ipR)
  367. {
  368. HRESULT hr;
  369. ISurfaceOpPtr pSurfaceOp(CLSID_RasterSurface);
  370. IGeoDatasetPtr plnputDataset(ipR);
  371. //声明输出对象
  372. IGeoDatasetPtr pOutput;
  373. //设置输出工作区
  374. IWorkspacePtr pWo;
  375. IWorkspaceFactoryPtr pWSF(CLSID_ShapefileWorkspaceFactory);
  376. hr=pWSF->OpenFromFile((CComBSTR)m_OutputFeatureDir,NULL,&pWo);
  377. if(FAILED(hr))
  378. {
  379. AfxMessageBox( "输出路径不存在!");
  380. return;
  381. }
  382. IRasterAnalysisEnvironmentPtr pEnv(pSurfaceOp);
  383. hr = pEnv->putref_OutWorkspace(pWo);
  384. if(FAILED(hr))
  385. {
  386. AfxMessageBox("输出路径设置失败!");
  387. return;
  388. }
  389. //Contour
  390. CString str;
  391. m_edit_Contour_ContourInterval.GetWindowText(str);
  392. double interval=atof ( str );
  393. m_edit_ContourBaseContour. GetWindowText(str );
  394. double base= atof(str);
  395. VARIANT BASE;
  396. BASE.vt =VT_R8;
  397. BASE.dblVal=base;
  398. hr=pSurfaceOp->Contour(plnputDataset,interval,&BASE,&pOutput);
  399. if(FAILED(hr ))
  400. if(hr==-2147467259)
  401. {
  402. AfxMessageBox("等高线恢复无法进行,请更换表面数据!");
  403. return;
  404. }
  405. //重命名:因为Contour后的文件名为默认的,不符合要求
  406. IDatasetPtr pda(pOutput);
  407. VARIANT_BOOL CanRename;
  408. hr = pda->CanRename(&CanRename);
  409. if(FAILED(hr ))
  410. {
  411.         return;
  412. }
  413. if( CanRename == VARIANT_TRUE)
  414. {
  415. hr=pda->Rename((CComBSTR)m_OutputFeatureName);
  416. return;
  417. AfxMessageBox("成功!");
  418. }
  419. }