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

GIS编程

开发平台:

Visual C++

  1. // DlgViewshed.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "3D0214.h"
  5. #include "DlgViewshed.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CDlgViewshed dialog
  13. CDlgViewshed::CDlgViewshed(CWnd* pParent /*=NULL*/)
  14. : CDialog(CDlgViewshed::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CDlgViewshed)
  17. m_edit_viewshedSurfaceinput = _T("");
  18. m_edit_viewshedRasteroutput = _T("");
  19. m_edit_viewshedCellsize = 0.0;
  20. m_edit_viewshedobserverpoints = _T("");
  21. //}}AFX_DATA_INIT
  22. }
  23. void CDlgViewshed::DoDataExchange(CDataExchange* pDX)
  24. {
  25. CDialog::DoDataExchange(pDX);
  26. //{{AFX_DATA_MAP(CDlgViewshed)
  27. DDX_Text(pDX, IDC_EDIT_VIEWSHED_SURFACEINPUT, m_edit_viewshedSurfaceinput);
  28. DDX_Text(pDX, IDC_EDIT_VIEWSHED_RASTEROUTPUT, m_edit_viewshedRasteroutput);
  29. DDX_Text(pDX, IDC_EDIT_VIEWSHED_CELLSIZE, m_edit_viewshedCellsize);
  30. DDX_Text(pDX, IDC_EDIT_VIEWSHED_OBSERVERPOINTS, m_edit_viewshedobserverpoints);
  31. //}}AFX_DATA_MAP
  32. }
  33. BEGIN_MESSAGE_MAP(CDlgViewshed, CDialog)
  34. //{{AFX_MSG_MAP(CDlgViewshed)
  35. ON_BN_CLICKED(IDC_BUTTON_VIEWSHED_OBSERVERPOINTS, OnButtonViewshedObserverpoints)
  36. ON_BN_CLICKED(IDC_BUTTON_VIEWSHED_RASTEROUTPUT, OnButtonViewshedRasteroutput)
  37. ON_BN_CLICKED(IDC_BUTTON_VIEWSHED_SURFACEINPUT, OnButtonViewshedSurfaceinput)
  38. //}}AFX_MSG_MAP
  39. END_MESSAGE_MAP()
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CDlgViewshed message handlers
  42. void CDlgViewshed::OnButtonViewshedObserverpoints() 
  43. {
  44. // TODO: Add your control notification handler code here
  45. //打开对话框         
  46. IGxDialogPtr ipGxDialog(CLSID_GxDialog);         
  47. IGxObjectFilterPtr ipGxObjectFiiter( CLSID_GxFilterPointFeatureClasses);
  48.     //注意:这里使用了GxFilterPointFeatureClasses ,
  49.     //可以过滤点特征集,满足功能只用点内插的需要          
  50. HRESULT hr=ipGxDialog->putref_ObjectFilter(ipGxObjectFiiter);            
  51. if(FAILED(hr)) return;
  52.     hr=ipGxDialog->put_Title(CComBSTR("选择一个点数据集"));
  53.     if(FAILED(hr))return;
  54. IEnumGxObjectPtr ipEnumGxObject;
  55. VARIANT_BOOL bResult;
  56. hr=ipGxDialog->DoModalOpen(0,&ipEnumGxObject,&bResult);
  57. if(FAILED(hr)) return;
  58. if(bResult==VARIANT_FALSE)return;
  59. hr=ipEnumGxObject->Reset();
  60. if(FAILED(hr)) return;
  61. IGxObjectPtr ipGxObject;
  62. while(!ipEnumGxObject->Next(&ipGxObject))
  63. {
  64. IGxDatasetPtr ipGxDataset(ipGxObject);
  65. if(ipGxDataset!=0)
  66. {   
  67. IDatasetPtr ipDataset;    
  68. hr=ipGxDataset->get_Dataset(&ipDataset);    
  69. if(FAILED(hr))return;    
  70. IFeatureClassPtr ipFeatureClass(ipDataset);    
  71. IFeatureLayerPtr ipFeatureLayer( CLSID_FeatureLayer);    
  72. hr=ipFeatureLayer->putref_FeatureClass(ipFeatureClass);    
  73. if(FAILED(hr)) return;
  74. m_ipfeat=ipFeatureClass;
  75. CComBSTR bstrName; //*} book获得输入点层的全名
  76. ipGxObject->get_FullName(&bstrName);
  77. CString str( bstrName);
  78. m_edit_viewshedobserverpoints=str;
  79. UpdateData(FALSE);
  80. }
  81. }
  82. }
  83. void CDlgViewshed::OnButtonViewshedRasteroutput() 
  84. {
  85. // TODO: Add your control notification handler code here
  86. IGxDialogPtr ipGxDialog(CLSID_GxDialog);
  87.     IGxObjectFilterPtr ipGxObjectFilter(CLSID_GxFilterRasterDatasets);
  88. HRESULT hr=ipGxDialog->putref_ObjectFilter(ipGxObjectFilter);
  89. if(FAILED(hr))return;
  90. hr=ipGxDialog->put_Title( CComBSTR("保存"));
  91. if(FAILED(hr)) return;
  92.      VARIANT_BOOL bResult;
  93. OLE_HANDLE hwnd=(OLE_HANDLE)this->GetSafeHwnd();
  94. hr=ipGxDialog->DoModalSave(hwnd,&bResult);
  95. if(FAILED(hr)) return;
  96. if(bResult==VARIANT_FALSE) return;
  97. IGxObjectPtr ipGxObject;
  98. ipGxDialog->get_FinalLocation(&ipGxObject);
  99. CComBSTR path;
  100. ipGxObject->get_FullName(&path);
  101. m_OutputPath=CString(path);
  102. CComBSTR name;
  103. ipGxDialog->get_Name(&name);
  104. m_OutputName=CString(name);
  105. UpdateData(TRUE);
  106. m_edit_viewshedRasteroutput=m_OutputPath+"\"+m_OutputName;
  107. UpdateData(FALSE);
  108. }
  109. void CDlgViewshed::OnButtonViewshedSurfaceinput() 
  110. {
  111. // TODO: Add your control notification handler code here
  112. IGxDialogPtr ipGxDialog(CLSID_GxDialog);
  113. IGxObjectFilterPtr ipGxObjectFilter( CLSID_GxFilterSurfaceDatasets);
  114. HRESULT hr=ipGxDialog->putref_ObjectFilter( ipGxObjectFilter);
  115. if(FAILED(hr)) return;
  116. hr = ipGxDialog->put_Title(CComBSTR("选择一个DEM表面数据"));
  117. if(FAILED(hr)) return;
  118. IEnumGxObjectPtr ipEnumGxObject;
  119. VARIANT_BOOL bResult;
  120. hr=ipGxDialog->DoModalOpen(0,&ipEnumGxObject,&bResult);
  121. if(FAILED(hr)) return;
  122. if(bResult==VARIANT_FALSE)return;
  123. hr=ipEnumGxObject->Reset();
  124. if(FAILED(hr)) return;
  125. IGxObjectPtr ipGxObject;
  126. ipGxDialog->get_FinalLocation(&ipGxObject);
  127. while(!ipEnumGxObject->Next(&ipGxObject))
  128. {   
  129. IGxDatasetPtr ipGxDataset(ipGxObject);    
  130. if(ipGxDataset!=0)     
  131. {
  132. IDatasetPtr ipDataset;
  133. hr=ipGxDataset->get_Dataset(&ipDataset);
  134. if(FAILED(hr )) return;
  135. IRasterDatasetPtr ipRasterDataset(ipDataset);
  136. if(ipRasterDataset!=NULL)
  137. {  
  138. m_ipR=ipRasterDataset;   
  139. CComBSTR bstrName;   
  140. hr=ipRasterDataset->get_CompleteName(&bstrName);
  141. if(FAILED(hr)) return;
  142. m_edit_viewshedSurfaceinput=bstrName;
  143. IRasterPtr ipRas;
  144. //获得输人Raster表面的网格大小,作为viewshed的默认值
  145. hr=ipRasterDataset->CreateDefaultRaster(&ipRas);
  146. IRasterAnalysisPropsPtr ipRA(ipRas);
  147. double defaultcellsize;
  148. hr=ipRA->get_PixelHeight(&defaultcellsize);
  149. m_edit_viewshedCellsize=defaultcellsize;
  150. UpdateData(FALSE);
  151. }      
  152. ITinPtr ipTin(ipDataset);      
  153. ITinSurfacePtr ipTS(ipDataset);      
  154. if( ipTin!=NULL)  
  155. {   
  156. m_ipT=ipTin;   
  157. CComBSTR bstrName;   
  158. hr=ipDataset->get_Name(&bstrName);   
  159. if(FAILED(hr)) return;
  160. m_edit_viewshedSurfaceinput=bstrName;  
  161. IGeoDatasetPtr plnTin(m_ipT);  
  162. //通过获得Tin的范围设置默认。ellsize大小  
  163. IEnvelopePtr pExtent;  
  164. hr=plnTin->get_Extent(&pExtent);  
  165. double width,height;
  166. hr=pExtent->get_Width(&width);
  167. hr= pExtent->get_Height(&height);
  168. double defaultcellsize;
  169. if ( width>height)
  170. defaultcellsize=height/250;
  171. else
  172. defaultcellsize=width/250;
  173. m_edit_viewshedCellsize=defaultcellsize;
  174. UpdateData( FALSE);
  175. }
  176. }
  177. }
  178. }
  179. void CDlgViewshed::OnOK() 
  180. {
  181. // TODO: Add extra validation here
  182. if(m_ipT!=NULL)
  183. {
  184. TintoRaster( m_ipT);//将Tin转为Raster}
  185. }
  186. Viewshed();
  187. CDialog::OnOK();
  188. }
  189.  void CDlgViewshed::TintoRaster(ITin*ipT)
  190. {
  191. HRESULT hr;
  192.     IGeoDatasetPtr pInTin(ipT);
  193.     IEnvelopePtr pExtent;
  194.     hr=pInTin->get_Extent(&pExtent);
  195. IPointPtr pOrigin;
  196. hr=pExtent->get_LowerLeft(&pOrigin);
  197. double x,y;
  198. hr=pOrigin->get_X(&x);
  199. hr=pOrigin->get_Y(&y);
  200. hr = pOrigin->put_X(x-m_edit_viewshedCellsize*0.5);
  201. hr = pOrigin->put_Y(y-m_edit_viewshedCellsize*0.5);
  202. long nCol,nRow;
  203. double width,height;
  204. hr=pExtent->get_Width(&width);
  205. hr=pExtent->get_Height(&height);
  206. nCol=int(width/m_edit_viewshedCellsize)+1;
  207. nRow=int(height/m_edit_viewshedCellsize)+1;
  208. ISpatialReferencePtr pSR;
  209. hr=pInTin->get_SpatialReference(&pSR);
  210. IRasterDatasetPtr pRDS;
  211. IWorkspaceFactoryPtr rWksFac(CLSID_RasterWorkspaceFactory);
  212. IWorkspacePtr wks;
  213. hr=rWksFac->OpenFromFile(CComBSTR(m_OutputPath),0,&wks);
  214. IRasterWorkspace2Ptr rWks(wks);
  215. long numbands=1;
  216. hr=rWks->CreateRasterDataset(CComBSTR("tempToR"),
  217.                                  CComBSTR("GRID"),
  218.                                  pOrigin,
  219.                                  nCol,
  220.                                  nRow,
  221.  m_edit_viewshedCellsize,
  222.  m_edit_viewshedCellsize,
  223.  numbands,
  224.  PT_FLOAT,
  225.  pSR,
  226.  VARIANT_TRUE,
  227.  &pRDS);
  228. if(FAILED(hr))
  229. {
  230. if(hr=-2147467259)
  231. {
  232. AfxMessageBox( " 临时文件tempTtoR已经存在,请先删除");
  233. }
  234. AfxMessageBox ( " 临时文件Raster文件tempTtoR生成失败!");
  235. return;
  236. }
  237. //下面是调用GetRawPixel。函数 
  238. IRasterBandCollectionPtr pBandCollection(pRDS);
  239. IRasterBandPtr pRasterBand;
  240. hr=pBandCollection->Item(0,&pRasterBand);
  241. IRawPixelsPtr pRawPixels(pRasterBand);
  242. IPntPtr pBlockSize(CLSID_DblPnt);
  243. hr=pBlockSize->put_X(nCol);
  244. hr=pBlockSize->put_Y(nRow);
  245. IPixelBlockPtr pPixelBlock;
  246. hr=pRawPixels->CreatePixelBlock(pBlockSize,&pPixelBlock);
  247. VARIANT val;
  248. val.vt=VT_SAFEARRAY ;//要指定类型
  249. hr=pPixelBlock->get_SafeArray(0,&val);
  250. ITinSurfacePtr pTinSurf( ipT);
  251. IRasterPropsPtr pRasterProps(pRawPixels);
  252. VARIANT nodataFloat;
  253. nodataFloat.vt=VT_R4 ;//要指定类型
  254.     hr=pOrigin->get_X(&x);
  255.     hr=pOrigin->get_Y(&y);
  256.     hr=pOrigin->put_X(x+m_edit_viewshedCellsize*0.5);
  257.     hr=pOrigin->put_Y(y+m_edit_viewshedCellsize*nRow-m_edit_viewshedCellsize*0.5);
  258. hr=pRasterProps->get_NoDataValue(&nodataFloat);
  259. hr=pOrigin->get_X(&x);
  260. hr=pOrigin->get_Y(&y);
  261. hr= pTinSurf->QueryPixelBlock(x,y,
  262. m_edit_viewshedCellsize,
  263. m_edit_viewshedCellsize,
  264. esriElevationAsRaster,
  265. nodataFloat,
  266. val);
  267. IPntPtr pOffset(CLSID_DblPnt);
  268. hr=pOffset->put_X(0);
  269. hr=pOffset->put_Y(0);
  270. hr=pRawPixels->Write(pOffset,pPixelBlock);
  271.     //注意:只有指针pRDS被释放,Raster才会从内存写人硬盘。
  272. }
  273. void CDlgViewshed::Viewshed()
  274. {
  275. HRESULT hr;
  276. if( m_ipT!=NULL)
  277. {
  278. IWorkspacePtr ppRW ;//将生成的Raster赋给ipR   
  279. IWorkspaceFactoryPtr pWF(CLSID_RasterWorkspaceFactory);    
  280. hr=pWF->OpenFromFile(CComBSTR(m_OutputPath),0,&ppRW);    
  281. IRasterWorkspacePtr pRW(ppRW);   
  282. hr=pRW->OpenRasterDataset(CComBSTR("tempTtoR"),&m_ipR);
  283. }
  284. //创建RasterSurface0p对象
  285. ISurfaceOpPtr pSurfaceOp(CLSID_RasterSurfaceOp);
  286. //声明输人表面对象
  287. IGeoDatasetPtr pElevation(m_ipR);
  288. //声明观察点对象
  289. IGeoDatasetPtr pObservers(m_ipfeat);
  290. //声明输出对象
  291. IGeoDatasetPtr pOutputRaster;
  292. //通过设置环境接口IRasterAnalysisEnvironment的
  293. //函数OutV}Torkspace改变路径
  294. IRasterAnalysisEnvironmentPtr pEnv(pSurfaceOp);
  295. hr=pEnv->Reset();
  296. VARIANT cellsize;//设置、iewshed输出结果cellsize的大小
  297. cellsize.vt=VT_R8;
  298. cellsize.dblVal=m_edit_viewshedCellsize;
  299. hr=pEnv->SetCellSize(esriRasterEnvValue,&cellsize);
  300. IWorkspacePtr pWo;
  301. IWorkspaceFactoryPtr pWSF(CLSID_RasterWorkspaceFactory);
  302. hr=pWSF->OpenFromFile(CComBSTR(m_OutputPath),NULL,&pWo);
  303. if(FAILED(hr))
  304. {
  305.        AfxMessageBox ("打开表面数据失败!");
  306.        return; 
  307. }
  308. hr=pEnv->putref_OutWorkspace(pWo);
  309. if(FAILED(hr ))
  310. {
  311. AfxMessageBox("输出路径设置失败!");
  312. return;
  313. }
  314. hr=pSurfaceOp->Visibility(pElevation,
  315.                               pObservers,
  316.                               esriGeoAnalysisVisibilityFrequency,
  317.                               &pOutputRaster);
  318. if(FAILED(hr))
  319. {    
  320. AfxMessageBox("viewshed failed!");     
  321. return;
  322. }
  323. //永久保存生成的Raster
  324. IRasterPtr pOutRaster(pOutputRaster);
  325. IRasterBandCollectionPtr pRasBandC(pOutRaster);
  326. IDatasetPtr pOut;
  327. hr=pRasBandC->SaveAs(CComBSTR(m_OutputName),pWo,CComBSTR("GRID"),&pOut);
  328. if(FAILED(hr))
  329. {
  330.     
  331. AfxMessageBox("分析失败!");
  332.         return;
  333. }