博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ArcEngine10.0三维开发
阅读量:6999 次
发布时间:2019-06-27

本文共 14717 字,大约阅读时间需要 49 分钟。

该系统分为四个模块,分别是文件的操作、场景的浏览、点查询和矢量文件生成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事件                     */        /************************************************************************/        //创建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的条件");                }            }     }

 

转载于:https://www.cnblogs.com/leebokeyuan/p/7883927.html

你可能感兴趣的文章