ArcEngine10.0三维开发
該系統分為四個模塊,分別是文件的操作、場景的瀏覽、點查詢和矢量文件生成TIN。下面分別對這四個模塊做詳細介紹。
文件操作。該模塊包括打開工程文件(打開sxd文件)、打開柵格文件(打開Raster文件)和保存圖片文件。所用到的控件有:SceneControl控件(用于顯示打開的工程文件和柵格文件)、
Button控件、OpenFileDialog控件、SaveFileDialog控件、TabControl控件(頁面布局控件)、TOCControl控件(用于顯示圖層)。其布局如下:
?
| 控件類型 | Text屬性 | 控件名稱 | 備注 |
| SceneControl | 無 | mSceneControl | 顯示數據 |
| TOCControl | 無 | mTOCControl | ?顯示圖層 |
| Button | 打開sxd文件 | OpenSxdFile | 打開工程的文件 |
| Button | 打開Raster文件 | OpenRasterFile | 打開柵格的文件 |
| Button | 保存圖片文件 | SaveImage | 抓圖 |
| TabControl | 兩個頁面分別為“基本操作”和“圖層” | tabControl1 | 分為兩個頁面,“基本操作”和“圖層” |
??
除了上述表所列出的屬性需要設置,另外還要將TOCControl的Buddy屬性設置為mSceneControl,其方法如下:
(1)?選中TOCControl控件,右擊彈出菜單并選擇“屬性”。
(2)?彈出對話框,選擇General頁面,并找到Buddy復選框,選擇mSceneControl。
???? 將控件的屬性設置完畢之后,為三個Button控件添加Click事件,并添加以下處理代碼:
????? ? OpenSxdFile按鈕控件的Click事件代碼:
/************************************************************************//* "打開sxd文件"按鈕按下事件 *//************************************************************************///打開sxd工程文件private void OpenSxdFile_Click(object sender, EventArgs e){//文件過濾 mOpenFileDialog.Filter = "sxd文件|*.sxd";//打開文件對話框打開事件if (mOpenFileDialog.ShowDialog() == DialogResult.OK){//從打開對話框中得到打開文件的全路徑,并將該路徑傳入到mSceneControl中 mSceneControl.LoadSxFile(mOpenFileDialog.FileName);}}?OpenRasterFile按鈕控件的Click事件代碼:
/************************************************************************//* "打開Raster文件"按鈕按下事件 *//************************************************************************///向工程中添加柵格數據private void OpenRasterFile_Click(object sender, EventArgs e){string sFileName = null;//新建柵格圖層 IRasterLayer pRasterLayer = null;pRasterLayer = new RasterLayerClass();//取消文件過濾 mOpenFileDialog.Filter = "所有文件|*.*";//打開文件對話框打開事件if (mOpenFileDialog.ShowDialog() == DialogResult.OK){//從打開對話框中得到打開文件的全路徑 sFileName = mOpenFileDialog.FileName;//創建柵格圖層 pRasterLayer.CreateFromFilePath(sFileName);//將圖層加入到控件中 mSceneControl.Scene.AddLayer(pRasterLayer,true);//將當前視點跳轉到柵格圖層 ICamera pCamera = mSceneControl.Scene.SceneGraph.ActiveViewer.Camera;//得到范圍 IEnvelope pEenvelop = pRasterLayer.VisibleExtent;//添加z軸上的范圍 pEenvelop.ZMin = mSceneControl.Scene.Extent.ZMin;pEenvelop.ZMax = mSceneControl.Scene.Extent.ZMax;//設置相機 pCamera.SetDefaultsMBB(pEenvelop);mSceneControl.Refresh();}}?SaveImage按鈕控件的Click事件代碼:
/************************************************************************//* "保存圖片文件"按鈕按下事件 *//************************************************************************///抓圖,將場景保存成圖片文件private void SaveImage_Click(object sender, EventArgs e){string sFileName = "";//保存對話框的標題 mSaveFileDialog.Title = "保存圖片";//保存對話框過濾器 mSaveFileDialog.Filter = "BMP圖片|*.bmp|JPG圖片|*.jpg";//圖片的高度和寬度int Width = mSceneControl.Width;int Height = mSceneControl.Height;if( mSaveFileDialog.ShowDialog() == DialogResult.OK){sFileName = mSaveFileDialog.FileName;if(mSaveFileDialog.FilterIndex == 1)//保存成BMP格式的文件 {mSceneControl.SceneViewer.GetSnapshot(Width, Height, esri3DOutputImageType.BMP, sFileName);}else//保存成JPG格式的文件 {mSceneControl.SceneViewer.GetSnapshot(Width, Height,esri3DOutputImageType.JPEG, sFileName);}MessageBox.Show("保存圖片成功!");mSceneControl.Refresh();}}??????? 有兩種方法定制場景的瀏覽,第一種方法是利用arcgis的向導,定制常用的瀏覽方法,如漫游、放大、縮小等等,該方法簡單,并且不需要編寫代碼,第二種方法是通過添加代碼的方法更改場景的CurrentTool屬性,從而實現場景瀏覽的功能,下面對以上兩種方法一一介紹:
?? 第一種方法:
??? 第一步:添加ToolbarControl控件,該控件位于“工具箱”中的“ArcGIS?Windows?Forms”選項中,把它的名字設置為?”mToolbarControl”,將“Dock”屬性設置為“Top”,并將其Buddy屬性設置為mSceneControl,設置方法與mTOCControl控件相同。
??? 第二步:進入“mToolbarControl”屬性對話框中的“items”頁面,并單擊“Add…”按鈕。彈出Control?Commands對話框,在Control?Commands對話框中選中“Category”列表框中的“Scene”選項,在“Commands”列表中就會出現與“Scene”關聯的命令,雙擊命令就可以將該命令加入到“mToolbarControl”工具條中。
?? 第二種方法:
?? ?第一步,加入C#工具條(ToolStrip控件),并將其“Dock”屬性設置為“Top”,
??? 第二步,在工具條中加入按鈕,并為按鈕添加事件,并寫入事件處理程序,其代碼如下:
/************************************************************************//* 工具條“ZoomIn”按鈕按下事件 *//************************************************************************///將場景的縮放private void ZoomIn_Click(object sender, EventArgs e){//創建命令 ICommand pCommand = new ControlsSceneZoomInTool();pCommand.OnCreate(mSceneControl.Object);//將當前工具設置為縮放工具 mSceneControl.CurrentTool = pCommand as ITool;pCommand = null;//刷新 mSceneControl.Refresh();}?????? 本例僅以縮放為例,其他瀏覽工具與此相同。
?????? SceneControl控件中常用的瀏覽功能如下:
| 類名 | 功能 |
| ControlsSceneFlyTool?(Controls) | 飛行 |
| ControlsSceneFullExtentCommand?(Controls) | 全景視圖 |
| ControlsSceneNavigateTool?(Controls) | 導航 |
| ControlsSceneOpenDocCommand?(Controls) | 打開文檔 |
| ControlsScenePanTool?(Controls) | 漫游 |
| ControlsSceneZoomInTool?(Controls) | 放大 |
| ControlsSceneZoomOutTool?(Controls) | 縮小 |
點查詢是通過鼠標點擊事件來獲取要素的方法,該功能是三維系統最常見的方法,arcgis中提供的LocateMultiple可以很方便的實現點查詢功能,以下對點查詢功能做詳細的介紹:
??? 第一步,在主窗口中添加一個CheckBox控件,并命名為mPointSearch,如圖7所示,該控件控制是否進行點查詢操作。
??? 第二步,新建一個Windows窗口,命名為ResultForm,并將Text屬性改為“查詢結果”ResultForm窗口中有一個TreeView控件,該控件以樹狀形式顯示了查詢的結果,如圖8所示:
??? 第三步,為MainFrom添加私有成員函數private?ResultForm?mResultForm,并初始化。為mSceneControl控件添加鼠標按下事件OnMouseDown,并加入如下代碼:
/************************************************************************//* mSceneControl的OnMouseDown事件 *//************************************************************************///處理點查詢private void OnMouseDown(object sender, ISceneControlEvents_OnMouseDownEvent e){if(mPointSearch.Checked)//check按鈕處于打勾狀態 {//查詢 mSceneControl.SceneGraph.LocateMultiple(mSceneControl.SceneGraph.ActiveViewer,e.x, e.y, esriScenePickMode.esriScenePickAll, false, out mHit3DSet);mHit3DSet.OnePerLayer();if (mHit3DSet == null)//沒有選中對象 {MessageBox.Show("沒有選中對象");}else{//顯示在ResultForm控件中。mHit3DSet為查詢結果集合 mResultForm.Show();mResultForm.refeshView(mHit3DSet);}mSceneControl.Refresh();}}?
第四步,在ResultForm中顯示結果結合,其代碼如下:
?
//顯示結果集合public void refeshView(IHit3DSet pHit3Dset){//用tree控件顯示查詢結果 mTreeView.BeginUpdate();//清空tree控件的內容 mTreeView.Nodes.Clear();IHit3D pHit3D;int i;//遍歷結果集for (i = 0; i < pHit3Dset.Hits.Count; i++){pHit3D = pHit3Dset.Hits.get_Element(i) as IHit3D;if(pHit3D.Owner is ILayer){ILayer pLayer = pHit3D.Owner as ILayer;//將圖層的名稱和坐標顯示在樹節點中 TreeNode node = mTreeView.Nodes.Add(pLayer.Name);node.Nodes.Add("X=" + pHit3D.Point.X.ToString());node.Nodes.Add("Y=" + pHit3D.Point.Y.ToString());node.Nodes.Add("Z=" + pHit3D.Point.Z.ToString());//將該圖層中的所有元素顯示在該樹節點的子節點if(pHit3D.Object != null){if (pHit3D.Object is IFeature){IFeature pFeature = pHit3D.Object as IFeature;int j;//顯示Feature中的內容for (j = 0; j < pFeature.Fields.FieldCount; j++){node.Nodes.Add(pFeature.Fields.get_Field(j).Name + ":" +pFeature.get_Value(j).ToString());}}}}}mTreeView.EndUpdate();}?
????? 本例主要是利用大量的矢量文件生成不規則三界網TIN,并顯示到mSceneControl控件中.其控件布局如下所示:
?
| 控件類型 | Text屬性 | 控件名稱 | 備注 |
| ComboBox | 無 | mLayerCombox | 選擇圖層 |
| ComboBox | 無 | mFeildCombox | 選擇與圖層對應的字段 |
| ComboBox | 無 | mTINType | 選擇生成Tin文件的類型 |
| Button | 刷新圖層 | RefreshLayer | 將當前工程的圖層顯示到mLayerCombox中去 |
| Button | 構建TIN | ConstructTin | 創建TIN |
??????? 另外,由于生成Tin文件的類型是固定的,不需要從場景中獲得,所以mTINType復選框下拉菜單的內容也是固定的,可以通過修改ComboBox控件的Items屬性來設定下拉菜單的內容,如圖。本文主要介紹以下“點”、“直線”、“光滑線”三種構建TIN的類型,其他的類型請參閱arcgis幫助文檔。
?
為RefreshLayer按鈕添加Click事件,其代碼如下:
/************************************************************************//* RefreshLayer按鈕Click事件 *//************************************************************************///刷新圖層private void RefreshLayer_Click(object sender, EventArgs e){mLayerCombox.Items.Clear();//得到當前場景中所有圖層int nCount = mSceneControl.Scene.LayerCount;if (nCount <= 0)//沒有圖層的情況 {MessageBox.Show("場景中沒有圖層,請加入圖層");return;}int i;ILayer pLayer = null;//將所有的圖層的名稱顯示到復選框中for (i = 0; i < nCount; i++){pLayer = mSceneControl.Scene.get_Layer(i);mLayerCombox.Items.Add(pLayer.Name);}//將復選框設置為選中第一項 mLayerCombox.SelectedIndex = 0;addFieldNameToCombox(mLayerCombox.Items[mLayerCombox.SelectedIndex].ToString());}為mLayerCombox控件添加SelectedIndexChanged事件,其代碼如下:
?
/************************************************************************//* mLayerCombox的SelectedIndexChanged事件 *//************************************************************************/private void OnSelectIndexChange(object sender, EventArgs e){addFieldNameToCombox(mLayerCombox.Items[mLayerCombox.SelectedIndex].ToString());}//更加圖層的名字將該圖層的字段加入到combox中private void addFieldNameToCombox(string layerName){mFeildCombox.Items.Clear();int i;IFeatureLayer pFeatureLayer = null;IFields pField = null;int nCount = mSceneControl.Scene.LayerCount;ILayer pLayer = null;//尋找名稱為layerName的FeatureLayer;for (i = 0; i < nCount; i++){pLayer = mSceneControl.Scene.get_Layer(i) as IFeatureLayer;if (pLayer.Name == layerName)//找到了layerName的Featurelayer {pFeatureLayer = pLayer as IFeatureLayer;break;}}if(pFeatureLayer != null)//判斷是否找到 {pField = pFeatureLayer.FeatureClass.Fields;nCount = pField.FieldCount;//將該圖層中所用的字段寫入到mFeildCombox中去for (i = 0; i < nCount; i++ ){mFeildCombox.Items.Add(pField.get_Field(i).Name);}}mFeildCombox.SelectedIndex = 0;}?
為ConstructTin按鈕添加Click事件,其代碼如下:
?
/************************************************************************//* ConstructTin按鈕的Click事件 *//************************************************************************///創建Tinprivate void ConstructTin_Click(object sender, EventArgs e){if(mLayerCombox.Text == ""|| mFeildCombox.Text == "")//判斷輸入合法性 {MessageBox.Show("沒有相應的圖層");return;}ITinEdit pTin = new TinClass();//尋找Featurelayer IFeatureLayer pFeatureLayer =mSceneControl.Scene.get_Layer(mLayerCombox.SelectedIndex) as IFeatureLayer;if(pFeatureLayer != null){IEnvelope pEnvelope = new EnvelopeClass();IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;IQueryFilter pQueryFilter = new QueryFilterClass();IField pField = null;//找字段 pField = pFeatureClass.Fields.get_Field(pFeatureClass.Fields.FindField(mFeildCombox.Text));if(pField.Type == esriFieldType.esriFieldTypeInteger ||pField.Type ==esriFieldType.esriFieldTypeDouble ||pField.Type == esriFieldType.esriFieldTypeSingle)//判斷類型 {IGeoDataset pGeoDataset = pFeatureLayer as IGeoDataset;pEnvelope = pGeoDataset.Extent;//設置空間參考系 ISpatialReference pSpatialReference;pSpatialReference = pGeoDataset.SpatialReference;//選擇生成TIN的輸入類型 esriTinSurfaceType pSurfaceTypeCount = esriTinSurfaceType.esriTinMassPoint;switch (mTINType.Text){case "點":pSurfaceTypeCount = esriTinSurfaceType.esriTinMassPoint;break;case "直線":pSurfaceTypeCount = esriTinSurfaceType.esriTinSoftLine;break;case "光滑線":pSurfaceTypeCount = esriTinSurfaceType.esriTinHardLine;break;}//創建TIN pTin.InitNew(pEnvelope);object missing = Type.Missing; //生成TIN pTin.AddFromFeatureClass(pFeatureClass, pQueryFilter, pField, pField, pSurfaceTypeCount, ref missing);pTin.SetSpatialReference(pGeoDataset.SpatialReference);//創建Tin圖層并將Tin圖層加入到場景中去 ITinLayer pTinLayer = new TinLayerClass();pTinLayer.Dataset = pTin as ITin;mSceneControl.Scene.AddLayer(pTinLayer,true);}else{MessageBox.Show("該字段的類型不符合構建TIN的條件");}}}?
轉載于:https://www.cnblogs.com/leebokeyuan/p/7883927.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的ArcEngine10.0三维开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: golang中的类和接口的使用
- 下一篇: IAR spi调试