许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  ArcGIS Engine 10.0轻松入门级教程(5):ArcEngine 10.0三维开发

ArcGIS Engine 10.0轻松入门级教程(5):ArcEngine 10.0三维开发

阅读数 13
点赞 0
article_banner

该系统分为四个模块,分别是文件的操作、场景的浏览、点查询和矢量文件生成TIN。下面分别对这四个模块做详细介绍。

     文件操作。该模块包括打开工程文件(打开sxd文件)、打开栅格文件(打开Raster文件)和保存图片文件。所用到的控件有:SceneControl控件(用于显示打开的工程文件和栅格文件)、Button控件、OpenFileDialog控件、SaveFileDialog控件、TabControl控件(页面布局控件)、TOCControl控件(用于显示图层)。其布局如下:


控件类型Text属性控件名称备注
SceneControlmSceneControl显示数据
TOCControlmTOCControl显示图层
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属性控件名称备注
ComboBoxmLayerCombox选择图层
ComboBoxmFeildCombox选择与图层对应的字段
ComboBoxmTINType选择生成Tin文件的类型
Button刷新图层RefreshLayer将当前工程的图层显示到mLayerCombox中去
Button构建TINConstructTin创建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事件                     */

       /************************************************************************/

       //创建Tin

       private 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的条件");

               }

           }

    }


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空