实习指导书第八章arcgisengine三维开发.docx
《实习指导书第八章arcgisengine三维开发.docx》由会员分享,可在线阅读,更多相关《实习指导书第八章arcgisengine三维开发.docx(22页珍藏版)》请在冰豆网上搜索。
实习指导书第八章arcgisengine三维开发
实习指导书_第八章_ArcGISEngine三维开发
第八章ArcGISEngine的三维开发
8.1ArcGIS三维分析及其控件简介
8.1.1ArcGIS三维分析简介
ArcGIS三维分析提供了对表面数据有效的可视化和分析。
使用三维分析,可以从多个角度来浏览表面数据,查询表面,从表面上一选定的位置来确定什么对象可见,以及通过叠加栅格和矢量数据来创建一幅逼真的透视图。
三维分析(3DAnalyst)添加了两个专用的三维可视化应用程序:
ArcScene和ArcGlobe,它们扩展了ArcGISDesktop的功能,并且扩展了ArcCatalog和ArcMap的三维功能。
ArcScene允许用户制作具有透视效果的场景,在这个场景中可以对地理信息系统数据进行浏览和交互。
用户可以在表面上叠加栅格和矢量数据,并从矢量数据源创建线、面和体。
用户也可以使用ArcScene中的三维分析工具创建和分析表面。
ArcGlobe提供在标准计算机硬件上对巨型三维栅格、地形和矢量数据集进行实时漫游和缩放,在此过程中基本不会感觉到速度上的问题。
这主要是依靠一种新引入的索引和快速检索数据的方法实现的。
利用三维分析扩展ArcCatalog,从而实现对三维数据的管理并且创建具有三维视觉属性的图层。
用户可以在ArcCatalog中使用与ArcScene中相同的浏览工具预览三维场景和数据。
利用三维分析扩展ArcMap,从而可以由GIS数据生成新的表面,以及分析表面、查询表面某一位置的属性值和分析表面不同位置的可见性。
用户还可以计算表面面积和表面之上或者表面之下的体积,并沿表面上的三维线生成剖面。
8.2ArcGIS三维显示简介
ArcGISDesktop中,可用于三维场景展示的程序为ArcGlobe和ArcScene,由于两者的差别,在三维场景展示中适用的情况有所不同。
由于Engine与Desktop底层技术都是基于AO的,因此该比较结果在功能性和整体效率方面同样适用与GlobeControl和SceneControl。
ArcScene简介:
ArcScene是一个适合于展示三维透视场景的平台,可以在三维场景中漫游并与三维矢量与栅格数据进行交互。
ArcScene是基于OpenGL的,支持TIN数据显示。
显示场景时,ArcScene会将所有数据加载到场景中,矢量数据以矢量形式显示,栅格数据默认会降低分辨率来显示以提高效率。
图1ArcScene界面
ArcGlobe简介:
ArcGlobe是ArcGIS9.0之后出现的新产品,设计用于展示大数据量的场景,支持对栅格和矢量数据无缝的显示。
ArcGlobe基于全球视野,所有数据均投影到全球立方投影(WorldCubeProjection)下,并对数据进行分级分块显示。
为提高显示效率,ArcGlobe按需将数据缓存到本地,矢量数据可以进行栅格化。
图2ArcGlobe界面
ArcGlobe和ArcScene的主要区别:
(1)投影坐标系统的不同:
ArcGlobe将所有数据投影到球体表面上,使场景显示更接近现实世界。
适合于全市,全省,全国甚至全球大范围内的数据展示。
ArcScene将所有数据投影到当前场景所定义的空间参考中,默认情况下,场景的空间参考由所加入的第一个图层空间参考决定。
ArcScene中场景表现为平面投影,适合于小范围内精细场景刻画。
(2)缓存与内存管理机制的不同:
ArcGlobe和ArcScene最重要的区别在于此。
ArcGlobe设计用于海量数据展示,所以为提高显示效率而进行数据缓存是很必要的。
ArcGlobe将数据分块并按级别建立缓存和索引,才使得即使在ArcGlobe中显示海量数据仍可以高速的展示与漫游。
ArcScene会将所有数据读入场景中完全显示,因此会占用大量显存,物理内存和虚拟内存,这也是ArcScene适于小数据量小场景精细展示的原因之一。
(3)分析功能的不同:
ArcGlobe可以极好的展示大数据的场景,同时提供高速的漫游。
但ArcScene对传统的三维分析功能支持的更好。
例如Desktop中3DAnalyst工具条在ArcScene中被很好的支持,并支持Tin模型的显示。
ArcGlobe不支持Tin的显示,但支持其作为高程数据加入场景。
ArcGlobe支持Terrain数据集但ArcScene不支持。
(4)显示差别
ArcGlobe中用户可以选择是否将矢量数据栅格化后显示,该功能对注记数据的显示也有很大帮助。
用户可以选择将注记(Annotation)附着显示于地球表面或像广告牌一样面向当前用户。
ArcScene中不支持注记(Annotation)数据的显示。
在ArcGlobe中矢量数据栅格化后可以大幅提高显示效率,我们在ArcGlobe场景建设中采取“能够栅格化的矢量数据尽量栅格化”的策略也来自于此。
1.ArcGIS三维系统的设计
该系统分为四个模块,分别是文件的操作、场景的浏览、点查询和矢量文件生成TIN。
下面分别对这四个模块做详细介绍,其参考代码请参阅“例子程序”中的Chapter8。
1
2
2.1文件操作
该模块包括打开工程文件(打开sxd文件)、打开栅格文件(打开Raster文件)和保存图片文件。
所用到的控件有:
SceneControl控件(用于显示打开的工程文件和栅格文件)、Button控件、OpenFileDialog控件、SaveFileDialog控件、TabControl控件(页面布局控件)、TOCControl控件(用于显示图层)。
其布局如下:
图3文件操作的界面布局(红线内的)
表1控件的名称和类型对照表
控件类型
Text属性
控件名称
备注
SceneControl
无
mSceneControl
显示数据
TOCControl
无
mTOCControl
显示图层
Button
打开sxd文件
OpenSxdFile
打开工程的文件
Button
打开Raster文件
OpenRasterFile
打开栅格的文件
Button
保存图片文件
SaveImage
抓图
TabControl
两个页面分别为“基本操作”和“图层”
tabControl1
分为两个页面,“基本操作”和“图层”
除了上述表所列出的属性需要设置,另外还要将TOCControl的Buddy属性设置为mSceneControl,其方法如下:
(1)选中TOCControl控件,右击弹出菜单并选择“属性”。
(2)弹出对话框,选择General页面,并找到Buddy复选框,选择mSceneControl,如下图。
图4设置TOCControl控件的Buddy属性
将控件的属性设置完毕之后,为三个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();
}
}
2.2场景浏览
有两种方法定制场景的浏览,第一种方法是利用arcgis的向导,定制常用的浏览方法,如漫游、放大、缩小等等,该方法简单,并且不需要编写代码,第二种方法是通过添加代码的方法更改场景的CurrentTool属性,从而实现场景浏览的功能,下面对以上两种方法一一介绍:
第一种方法:
第一步:
添加ToolbarControl控件,该控件位于“工具箱”中的“ArcGISWindowsForms”选项中,把它的名字设置为”mToolbarControl”,将“Dock”属性设置为“Top”,并将其Buddy属性设置为mSceneControl,设置方法与mTOCControl控件相同。
第二步:
进入“mToolbarControl”属性对话框中的“items”页面,并单击“Add…”按钮。
弹出ControlCommands对话框,在ControlCommands对话框中选中“Category”列表框中的“Scene”选项,在“Commands”列表中就会出现与“Scene”关联的命令,双击命令就可以将该命令加入到“mToolbarControl”工具条中,如下图:
图5mToolbarControl属性对话框
图6ControlCommands对话框
第二种方法:
第一步,加入C#工具条(ToolStrip控件),并将其“Dock”属性设置为“Top”,
第二步,在工具条中加入按钮,并为按钮添加事件,并写入事件处理程序,其代码如下:
/************************************************************************/
/*工具条“ZoomIn”按钮按下事件*/
/************************************************************************/
//将场景的缩放
privatevoidZoomIn_Click(objectsender,EventArgse)
{
//创建命令
ICommandpCommand=newControlsSceneZoomInTool();
pCommand.OnCreate(mSceneControl.Object);
//将当前工具设置为缩放工具
mSceneControl.CurrentTool=pCommandasITool;
pCommand=null;
//刷新
mSceneControl.Refresh();
}
本例仅以缩放为例,其他浏览工具与此相同。
SceneControl控件中常用的浏览功能如下:
类名
功能
ControlsSceneFlyTool(Controls)
飞行
ControlsSceneFullExtentCommand(Controls)
全景视图
ControlsSceneNavigateTool(Controls)
导航
ControlsSceneOpenDocCommand(Controls)
打开文档
ControlsScenePanTool(Controls)
漫游
ControlsSceneZoomInTool(Controls)
放大
ControlsSceneZoomOutTool(Controls)
缩小
2.3点查询功能
点查询是通过鼠标点击事件来获取要素的方法,该功能是三维系统最常见的方法,arcgis中提供的LocateMultiple可以很方便的实现点查询功能,以下对点查询功能做详细的介绍:
第一步,在主窗口中添加一个CheckBox控件,并命名为mPointSearch,如图7所示,该控件控制是否进行点查询操作。
图7添加CheckBox控件
第二步,新建一个Windows窗口,命名为ResultForm,并将Text属性改为“查询结果”ResultForm窗口中有一个TreeView控件,该控件以树状形式显示了查询的结果,如图8所示:
图8ResultForm窗口布局
第三步,为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{
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{
node.Nodes.Add(pFeature.Fields.get_Field(j).Name+":
"+
pFeature.get_Value(j).ToString());
}
}
}
}
}
mTreeView.EndUpdate();
}
2.4矢量文件生成TIN
本例主要是利用大量的矢量文件生成不规则三界网TIN,并显示到mSceneControl控件中.其控件布局如下图所示:
图9矢量文件构造Tin界面布局(红线框内)
表2控件的名称和类型对照表
控件类型
Text属性
控件名称
备注
ComboBox
无
mLayerCombox
选择图层
ComboBox
无
mFeildCombox
选择与图层对应的字段
ComboBox
无
mTINType
选择生成Tin文件的类型
Button
刷新图层
RefreshLayer
将当前工程的图层显示到mLayerCombox中去
Button
构建TIN
ConstructTin
创建TIN
另外,由于生成Tin文件的类型是固定的,不需要从场景中获得,所以mTINType复选框下拉菜单的内容也是固定的,可以通过修改ComboBox控件的Items属性来设定下拉菜单的内容,如图10。
本文主要介绍以下“点”、“直线”、“光滑线”三种构建TIN的类型,其他的类型请参阅arcgis帮助文档。
图10设定mTINType复选框下拉菜单的内容
为RefreshLayer按钮添加Click事件,其代码如下:
/************************************************************************/
/*RefreshLayer按钮Click事件*/
/************************************************************************/
//刷新图层
privatevoidRefreshLayer_Click(objectsender,EventArgse)
{
mLayerCombox.Items.Clear();
//得到当前场景中所有图层
intnCount=mSceneControl.Scene.LayerCount;