1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > ArcGIS Engine10.0轻松入门级教程(5)——ArcEngine10.0三维开发

ArcGIS Engine10.0轻松入门级教程(5)——ArcEngine10.0三维开发

时间:2019-01-31 04:16:07

相关推荐

ArcGIS Engine10.0轻松入门级教程(5)——ArcEngine10.0三维开发

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

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

除了上述表所列出的属性需要设置,另外还要将TOCControl的Buddy属性设置为mSceneControl,其方法如下:

(1)选中TOCControl控件,右击弹出菜单并选择“属性”。

(2)弹出对话框,选择General页面,并找到Buddy复选框,选择mSceneControl。

将控件的属性设置完毕之后,为三个Button控件添加Click事件,并添加以下处理代码:

OpenSxdFile按钮控件的Click事件代码:

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

/*"打开sxd文件"按钮按下事件*/

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

//打开sxd工程文件

privatevoidOpenSxdFile_Click(objectsender,EventArgse)

{

//文件过滤

mOpenFileDialog.Filter="sxd文件|*.sxd";

//打开文件对话框打开事件

if(mOpenFileDialog.ShowDialog()==DialogResult.OK)

{

//从打开对话框中得到打开文件的全路径,并将该路径传入到mSceneControl中

mSceneControl.LoadSxFile(mOpenFileDialog.FileName);

}

}

OpenRasterFile按钮控件的Click事件代码:

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

/*"打开Raster文件"按钮按下事件*/

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

//向工程中添加栅格数据

privatevoidOpenRasterFile_Click(objectsender,EventArgse)

{

stringsFileName=null;

//新建栅格图层

IRasterLayerpRasterLayer=null;

pRasterLayer=newRasterLayerClass();

//取消文件过滤

mOpenFileDialog.Filter="所有文件|*.*";

//打开文件对话框打开事件

if(mOpenFileDialog.ShowDialog()==DialogResult.OK)

{

//从打开对话框中得到打开文件的全路径

sFileName=mOpenFileDialog.FileName;

//创建栅格图层

pRasterLayer.CreateFromFilePath(sFileName);

//将图层加入到控件中

mSceneControl.Scene.AddLayer(pRasterLayer,true);

//将当前视点跳转到栅格图层

ICamerapCamera=mSceneControl.Scene.SceneGraph.ActiveViewer.Camera;

//得到范围

IEnvelopepEenvelop=pRasterLayer.VisibleExtent;

//添加z轴上的范围

pEenvelop.ZMin=mSceneControl.Scene.Extent.ZMin;

pEenvelop.ZMax=mSceneControl.Scene.Extent.ZMax;

//设置相机

pCamera.SetDefaultsMBB(pEenvelop);

mSceneControl.Refresh();

}

}

SaveImage按钮控件的Click事件代码:

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

/*"保存图片文件"按钮按下事件*/

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

//抓图,将场景保存成图片文件

privatevoidSaveImage_Click(objectsender,EventArgse)

{

stringsFileName="";

//保存对话框的标题

mSaveFileDialog.Title="保存图片";

//保存对话框过滤器

mSaveFileDialog.Filter="BMP图片|*.bmp|JPG图片|*.jpg";

//图片的高度和宽度

intWidth=mSceneControl.Width;

intHeight=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控件,该控件位于“工具箱”中的“ArcGISWindowsForms”选项中,把它的名字设置为”mToolbarControl”,将“Dock”属性设置为“Top”,并将其Buddy属性设置为mSceneControl,设置方法与mTOCControl控件相同。

第二步:进入“mToolbarControl”属性对话框中的“items”页面,并单击“Add…”按钮。弹出ControlCommands对话框,在ControlCommands对话框中选中“Category”列表框中的“Scene”选项,在“Commands”列表中就会出现与“Scene”关联的命令,双击命令就可以将该命令加入到“mToolbarControl”工具条中。

第二种方法:

第一步,加入C#工具条(ToolStrip控件),并将其“Dock”属性设置为“Top”,

第二步,在工具条中加入按钮,并为按钮添加事件,并写入事件处理程序,其代码如下:

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

/*工具条“ZoomIn”按钮按下事件*/

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

//将场景的缩放

privatevoidZoomIn_Click(objectsender,EventArgse)

{

//创建命令

ICommandpCommand=newControlsSceneZoomInTool();

pCommand.OnCreate(mSceneControl.Object);

//将当前工具设置为缩放工具

mSceneControl.CurrentTool=pCommandasITool;

pCommand=null;

//刷新

mSceneControl.Refresh();

}

本例仅以缩放为例,其他浏览工具与此相同。

SceneControl控件中常用的浏览功能如下:

点查询是通过鼠标点击事件来获取要素的方法,该功能是三维系统最常见的方法,arcgis中提供的LocateMultiple可以很方便的实现点查询功能,以下对点查询功能做详细的介绍:第一步,在主窗口中添加一个CheckBox控件,并命名为mPointSearch,如图7所示,该控件控制是否进行点查询操作。第二步,新建一个Windows窗口,命名为ResultForm,并将Text属性改为“查询结果”ResultForm窗口中有一个TreeView控件,该控件以树状形式显示了查询的结果,如图8所示:

第三步,为MainFrom添加私有成员函数privateResultFormmResultForm,并初始化。为mSceneControl控件添加鼠标按下事件OnMouseDown,并加入如下代码:

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

/*mSceneControl的OnMouseDown事件*/

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

//处理点查询

privatevoidOnMouseDown(objectsender,ISceneControlEvents_OnMouseDownEvente)

{

if(mPointSearch.Checked)//check按钮处于打勾状态

{

//查询

mSceneControl.SceneGraph.LocateMultiple(mSceneControl.SceneGraph.ActiveViewer,

e.x,e.y,esriScenePickMode.esriScenePickAll,false,outmHit3DSet);

mHit3DSet.OnePerLayer();

if(mHit3DSet==null)//没有选中对象

{

MessageBox.Show("没有选中对象");

}

else

{

//显示在ResultForm控件中。mHit3DSet为查询结果集合

mResultForm.Show();

mResultForm.refeshView(mHit3DSet);

}

mSceneControl.Refresh();

}

}

第四步,在ResultForm中显示结果结合,其代码如下:

//显示结果集合

publicvoidrefeshView(IHit3DSetpHit3Dset)

{

//用tree控件显示查询结果

mTreeView.BeginUpdate();

//清空tree控件的内容

mTreeView.Nodes.Clear();

IHit3DpHit3D;

inti;

//遍历结果集

for(i=0;i<pHit3Dset.Hits.Count;i++)

{

pHit3D=pHit3Dset.Hits.get_Element(i)asIHit3D;

if(pHit3D.OwnerisILayer)

{

ILayerpLayer=pHit3D.OwnerasILayer;

//将图层的名称和坐标显示在树节点中

TreeNodenode=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.ObjectisIFeature)

{

IFeaturepFeature=pHit3D.ObjectasIFeature;

intj;

//显示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控件中.其控件布局如下所示:

另外,由于生成Tin文件的类型是固定的,不需要从场景中获得,所以mTINType复选框下拉菜单的内容也是固定的,可以通过修改ComboBox控件的Items属性来设定下拉菜单的内容,如图。本文主要介绍以下“点”、“直线”、“光滑线”三种构建TIN的类型,其他的类型请参阅arcgis帮助文档。

为RefreshLayer按钮添加Click事件,其代码如下:

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

/*RefreshLayer按钮Click事件*/

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

//刷新图层

privatevoidRefreshLayer_Click(objectsender,EventArgse)

{

mLayerCombox.Items.Clear();

//得到当前场景中所有图层

intnCount=mSceneControl.Scene.LayerCount;

if(nCount<=0)//没有图层的情况

{

MessageBox.Show("场景中没有图层,请加入图层");

return;

}

inti;

ILayerpLayer=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事件*/

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

privatevoidOnSelectIndexChange(objectsender,EventArgse)

{

addFieldNameToCombox(mLayerCombox.Items[mLayerCombox.SelectedIndex].ToString());

}

//更加图层的名字将该图层的字段加入到combox中

privatevoidaddFieldNameToCombox(stringlayerName)

{

mFeildCombox.Items.Clear();

inti;

IFeatureLayerpFeatureLayer=null;

IFieldspField=null;

intnCount=mSceneControl.Scene.LayerCount;

ILayerpLayer=null;

//寻找名称为layerName的FeatureLayer;

for(i=0;i<nCount;i++)

{

pLayer=mSceneControl.Scene.get_Layer(i)asIFeatureLayer;

if(pLayer.Name==layerName)//找到了layerName的Featurelayer

{

pFeatureLayer=pLayerasIFeatureLayer;

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

privatevoidConstructTin_Click(objectsender,EventArgse)

{

if(mLayerCombox.Text==""||mFeildCombox.Text=="")//判断输入合法性

{

MessageBox.Show("没有相应的图层");

return;

}

ITinEditpTin=newTinClass();

//寻找Featurelayer

IFeatureLayerpFeatureLayer=

mSceneControl.Scene.get_Layer(mLayerCombox.SelectedIndex)asIFeatureLayer;

if(pFeatureLayer!=null)

{

IEnvelopepEnvelope=newEnvelopeClass();

IFeatureClasspFeatureClass=pFeatureLayer.FeatureClass;

IQueryFilterpQueryFilter=newQueryFilterClass();

IFieldpField=null;

//找字段

pField=pFeatureClass.Fields.get_Field(pFeatureClass.Fields.FindField(mFeildCombox.Text));

if(pField.Type==esriFieldType.esriFieldTypeInteger||

pField.Type==esriFieldType.esriFieldTypeDouble||

pField.Type==esriFieldType.esriFieldTypeSingle)//判断类型

{

IGeoDatasetpGeoDataset=pFeatureLayerasIGeoDataset;

pEnvelope=pGeoDataset.Extent;

//设置空间参考系

ISpatialReferencepSpatialReference;

pSpatialReference=pGeoDataset.SpatialReference;

//选择生成TIN的输入类型

esriTinSurfaceTypepSurfaceTypeCount=

esriTinSurfaceType.esriTinMassPoint;

switch(mTINType.Text)

{

case"点":

pSurfaceTypeCount=esriTinSurfaceType.esriTinMassPoint;

break;

case"直线":

pSurfaceTypeCount=esriTinSurfaceType.esriTinSoftLine;

break;

case"光滑线":

pSurfaceTypeCount=esriTinSurfaceType.esriTinHardLine;

break;

}

//创建TIN

pTin.InitNew(pEnvelope);

objectmissing=Type.Missing;

//生成TIN

pTin.AddFromFeatureClass(pFeatureClass,pQueryFilter,pField,pField,pSurfaceTypeCount,refmissing);

pTin.SetSpatialReference(pGeoDataset.SpatialReference);

//创建Tin图层并将Tin图层加入到场景中去

ITinLayerpTinLayer=newTinLayerClass();

pTinLayer.Dataset=pTinasITin;

mSceneControl.Scene.AddLayer(pTinLayer,true);

}

else

{

MessageBox.Show("该字段的类型不符合构建TIN的条件");

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。