实习指导书第七章 ArcGIS Engine高级空间分析功能开发Word格式.docx
《实习指导书第七章 ArcGIS Engine高级空间分析功能开发Word格式.docx》由会员分享,可在线阅读,更多相关《实习指导书第七章 ArcGIS Engine高级空间分析功能开发Word格式.docx(70页珍藏版)》请在冰豆网上搜索。
IElementpEle=pRectangleEleasIElement;
pEle.Geometry=pEnv;
//设置线框的边线对象,包括颜色和线宽
IRgbColorpColor=newRgbColorClass();
pColor.Red=255;
pColor.Green=0;
pColor.Blue=0;
pColor.Transparency=255;
//产生一个线符号对象
ILineSymbolpOutline=newSimpleLineSymbolClass();
pOutline.Width=2;
pOutline.Color=pColor;
//设置颜色属性
pColor.Transparency=0;
//设置线框填充符号的属性
IFillSymbolpFillSymbol=newSimpleFillSymbolClass();
pFillSymbol.Color=pColor;
pFillSymbol.Outline=pOutline;
IFillShapeElementpFillShapeEle=pEleasIFillShapeElement;
pFillShapeEle.Symbol=pFillSymbol;
//得到鹰眼视图中的图形元素容器
IGraphicsContainerpGra=axMapControl2.MapasIGraphicsContainer;
IActiveViewpAv=pGraasIActiveView;
//在绘制前,清除axMapControl2中的任何图形元素
pGra.DeleteAllElements();
//鹰眼视图中添加线框
pGra.AddElement((IElement)pFillShapeEle,0);
//刷新鹰眼
pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null);
}
当鼠标点击鹰眼窗体时,主窗体Extent随之改变。
在axMapControl2的OnMouseDown事件中添加代码如下:
privatevoidaxMapControl2_OnMouseDown(objectsender,ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvente)
if(this.axMapControl2.Map.LayerCount!
=0)
//按下鼠标左键移动矩形框
if(e.button==1)
IPointpPoint=newPointClass();
pPoint.PutCoords(e.mapX,e.mapY);
IEnvelopepEnvelope=this.axMapControl1.Extent;
pEnvelope.CenterAt(pPoint);
this.axMapControl1.Extent=pEnvelope;
this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography,null,null);
//按下鼠标右键绘制矩形框
elseif(e.button==2)
IEnvelopepEnvelop=this.axMapControl2.TrackRectangle();
this.axMapControl1.Extent=pEnvelop;
当鼠标在鹰眼窗体移动时,主窗体Extent随之改变。
在axMapControl2的OnMouseMove事件中添加代码如下:
privatevoidaxMapControl2_OnMouseMove(objectsender,ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvente)
//如果不是左键按下就直接返回
if(e.button!
=1)return;
this.axMapControl1.CenterAt(pPoint);
下面代码用于实现axMapControl2与axMapControl1的数据的同步更新,获取主视图中视图范围最大的图层作为鹰眼中的视图。
这个更新由两部分组成,一个是对axMapControl1添加地图文档(mxd文件)的响应,通过axMapControl1的OnMapReplace事件实现,一个是对axMapControl1添加单个图层的响应,通过axMapControl1的OnFullExtentUpdated事件实现。
我们获取主视图中的视图范围最大的图层写成一个独立的函数,方便调用。
privateILayerGetOverviewLayer(IMapmap)
//获取主视图的第一个图层
ILayerpLayer=map.get_Layer(0);
//遍历其他图层,并比较视图范围的宽度,返回宽度最大的图层
ILayerpTempLayer=null;
for(inti=1;
i<
map.LayerCount;
i++)
pTempLayer=map.get_Layer(i);
if(pLayer.AreaOfInterest.Width<
pTempLayer.AreaOfInterest.Width)
pLayer=pTempLayer;
returnpLayer;
然后在axMapControl1的OnMapReplaced事件中调用。
privatevoidaxMapControl1_OnMapReplaced(objectsender,IMapControlEvents2_OnMapReplacedEvente)
//获取鹰眼图层
this.axMapControl2.AddLayer(this.GetOverviewLayer(this.axMapControl1.Map));
//设置MapControl显示范围至数据的全局范围
this.axMapControl2.Extent=this.axMapControl1.FullExtent;
//刷新鹰眼控件地图
this.axMapControl2.Refresh();
在axMapControl1的OnFullExtentUpdated添加代码,用于实现在主视图添加图层时,实现对鹰眼视图的更新。
代码如下:
privatevoidaxMapControl1_OnFullExtentUpdated(objectsender,ESRI.ArcGIS.Controls.IMapControlEvents2_OnFullExtentUpdatedEvente)
本例的示例数据无特别要求,使用前面章节实例数据即可。
运行程序,添加地图数据,可以在主视图进行相关操作,鹰眼视图同步响应,在鹰眼视图可以移动红线框可以同步更新主视图的视图范围,在鹰眼视图单击右键拉框可以重新绘制红线框,效果如下:
图3鹰眼效果
7.1.3MyGIS中添加鹰眼
在上一讲中的最后一节,我们创建了一个简单的GIS系统MyGIS,这里,我们讲鹰眼功能嵌入到我们的系统中。
在这里我们对实现的思路做一个介绍,请您自己动手完善MyGIS。
首先需要修改一下MyGIS窗体的控件布局,我们讲鹰眼视图放到图层管理器的下方,需要在控件容器SpliterContainer1的Panel1中添加一个水平分隔的SpliterContainer,然后将图层管理器空间TOCControl和鹰眼视图MapControl分别置于上下的容器中,并将其属性Dock分别设为Fill。
另外,在此种窗体布局情况下,直接在TOCControl控件属性中设置伙伴控件无效,如图所示。
我们需要在MainForm的Load事件中为TOCControl设置伙伴控件为axMapControl1。
添加代码如下:
privatevoidForm1_Load(objectsender,EventArgse)
//设置axTOCControl1的伙伴控件
this.axTOCControl1.SetBuddyControl(axMapControl1.Object);
图4TOCControl控件属性中设置伙伴控件
然后依次添加本例中的代码,即可完成,运行效果如下图所示:
图5MyGIS中鹰眼的运行效果
7.1.4小结
在本小节中,我们实现了鹰眼功能并讲鹰眼加入了MyGIS,这部分的重点是鹰眼视图和主视图之间的事件交互。
推荐您仔细结合例子程序查看代码,如果需要获得进一步的信息,请查看帮助系统。
如果您对这一小节的内容比较熟悉了,就可以开始学习本章最后一小节的内容了。
在下一小节中,我们将尝试添加缓冲区分析功能。
7.2缓冲区分析
缓冲区分析指为了识别某一地理实体或空间物体对其周围地物影响度而在其周围建立的具有一定宽度的区域,以确定哪些实体落在了被影响的区域范围之内。
缓冲区分析与缓冲区查询不同,缓冲区查询是不破坏原有空间目标的关系,只是检索到该缓冲区范围内涉及到的目标。
而缓冲区分析是根据设定的距离条件对一类地物建立缓冲区多边形,存储到一个新的图层中。
然后再将新的图层与需要进行缓冲区分析的图层进行叠置分析,得到所需要的结果。
因此,缓冲区分析实际上进行了两步的操作,第一步是建立缓冲区图层,第二步是进行叠置剪裁分析。
缓冲区分析适用于点、线、面对象,如点状的居民点、线状的河流和面状的作物分布区等,只要地理实体能对周围一定区域形成影响即可使用这种分析方法。
图6点、线、面的缓冲区分析
ArcGIS的ArcToolBox中的分析工具提供了缓冲区分析的功能,本节实习我们首先使用Geoprocessor方法实现一个简单的缓冲区分析功能,然后将缓冲区分析功能添加到我们的MyGIS项目中。
程序运行前首先需要在D盘下新建一个名为Temp的文件夹,存放叠置分析生成的文件。
7.2.1Geoprocessor实现缓冲区分析
为了降低开发难度和提高开发效率,ArcGISEngine中添加了GeoProcessor类,使用Geoprocessor能帮助用户直接实现一些简单的工具性的功能,所有在ArcToolBox中的功能,基本都可以用Geoprocessor编程实现。
本节我们使用Geoprocessor实现缓冲区分析的功能。
7.2.1.1添加控件
新建一个C#.Net项目,项目名称为Buffer,将Form1的名字设置为MainForm,并添加ToolbarControl、MapControl、TOCControl、LicenceControl和Button等五个控件。
并将ToolbarControl、TOCControl的伙伴控件设为MapControl,Button控件的Name属性设定为btnBuffer,Text属性设定为“缓冲区分析”。
控件布局效果如下图所示。
图7控件布局效果
在ToolbarControl加载添加数据按钮和地图浏览的功能按钮,如下图所示。
图8添加按钮
7.2.1.2代码添加及解释
首先添加如下四个命名空间的引用。
usingESRI.ArcGIS.Carto;
usingESRI.ArcGIS.Geoprocessor;
usingESRI.ArcGIS.Geoprocessing;
usingESRI.ArcGIS.esriSystem;
在使用Geoprocessor工具实现缓冲区分析时,需要首先定义一个Geoprocessor对象,因为命名空间“ESRI.ArcGIS.Geoprocessing”也包含Geoprocessor类,为了避免混淆,我们使用命名空间来定义Geoprocessor,然后设置Geoprocessor中的环境参数,这里我们使用默认参数。
然后定义一个操作类Buffer,并设置参数,生成缓冲区的参数包含原始图层,缓冲半径和输出路径,最后使用已定义的Geoprocessor对象执行即可。
双击“生成缓存区”按钮,添加代码如下:
privatevoidbtnBuffer_Click(objectsender,EventArgse)
//判断MapControl中是否包含图层
if(this.axMapControl1.LayerCount==0)
return;
//获取MapControl中第一个图层
ILayerpLayer=this.axMapControl1.Map.get_Layer(0);
//输出路径,可以自行指定
stringstrOutputPath=@"
D:
\Buffer.shp"
;
//缓冲半径
doubledblDistace=1.0;
//获取一个geoprocessor的实例,避免与命名空间Geoprocessing中的Geoprocessor发生引用错误
ESRI.ArcGIS.Geoprocessor.Geoprocessorgp=newESRI.ArcGIS.Geoprocessor.Geoprocessor();
//OverwriteOutput为真时,输出图层会覆盖当前文件夹下的同名图层
gp.OverwriteOutput=true;
//创建一个Buffer工具的实例
ESRI.ArcGIS.AnalysisTools.Bufferbuffer=newESRI.ArcGIS.AnalysisTools.Buffer(pLayer,strOutputPath,dblDistace);
//执行缓冲区分析
IGeoProcessorResultresults=null;
results=gp.Execute(buffer,null)asIGeoProcessorResult;
//判断缓冲区是否成功生成
if(results.Status!
=esriJobStatus.esriJobSucceeded)
MessageBox.Show("
图层"
+pLayer.Name+"
缓冲区生成失败!
"
);
else
缓冲区生成成功!
//将生成图层加入MapControl
intindex=strOutputPath.LastIndexOf("
\\"
this.axMapControl1.AddShapeFile(strOutputPath.Substring(0,index),strOutputPath.Substring(index));
运行程序,添加一个图层(多个图层时本例中默认选择的图层为第一个图层),点击“生成缓冲区”,运行结果如图。
图9缓冲区生成效果
7.2.1.3小结
本例中,我们使用Geoprocessor工具实现了缓冲区分析。
从中我们可以得到Geoprocessor工具使用的一般方法,在使用Geoprocessor时,一般需先定义一个Geoprocessor对象,然后设置该对象的参数,如本例中的OverwriteOutput,再定义一个具体的操作类,如本例中的Buffer类,在设置完操作类的参数后,则通过Geoprocessor的Excute函数来执行。
至此,我们已经实现了一个简单的缓冲区分析的功能,从中我们学习了Geoprocessor的使用方法。
下一节我们讲对缓冲区份分析功能做进一步的改进,使其具有更强的适用性,并将这个功能添加到MyGIS中。
7.2.2MyGIS中添加缓冲区分析
我们在使用缓冲区分析时,需要设定原始的图层,缓冲半径以及生成缓冲区的保存路径。
本节我们将在上一节的基础上进一步实现缓冲区分析,实现缓冲图层,缓冲半径和保存路径的可选设置。
7.2.2.1添加控件
打开项目MyGIS,在MyGIS的主菜单添加一个新的菜单项“空间分析”,并添加子菜单“缓冲区分析”,Name属性修改为“menuBuffer”。
项目中添加一个新的窗体,名称为“BufferForm”,Name属性设为“缓冲区分析”,添加四个Label、一个ComboBox、两个TextBox、三个Button控件,控件属性设置如下:
表1控件属性设置
控件类型
Name属性
Text属性
控件说明
Label
选择图层:
缓冲半径:
lblUnit
地图单位
标示当前地图的地图单位
输出图层:
ComboBox
cboLayers
所有图层的名称
TextBox
txtBufferDistance
1.0
生成缓冲区的缓冲半径
txtOutputPath
缓冲区文件的输出路径,其ReadOnly属性设为True
Button
btnOutputLayer
…
选择缓冲区文件的输出路径
btnBuffer
分析
进行缓冲区分析
btnCancel
取消
7.2.2.2代码添加及解释
该项目需添加如下引用:
usingESRI.ArcGIS.Controls;
首先声明两个成员变量,用于保存地图数据和输出文件的路径。
//接收MapControl中的数据
privateIHookHelpermHookHelper=newHookHelperClass();
//缓冲区文件输出路径
publicstringstrOutputPath;
重写BufferForm的构造函数,添加一个参数,用于接收MapControl中的数据。
//重写构造函数,添加参数hook,用于传入MapControl中的数据
publicBufferForm(objecthook)
InitializeComponent();
this.mHookHelper.Hook=hook;
添加一个自定义函数,用于根据图层名称获取要素图层并返回。
privateIFeatureLayerGetFeatureLayer(stringlayerName)
IFeatureLayerpFeatureLayer=null;
//遍历图层,获取与名称匹配的图层
for(inti=0;
this.mHookHelper.FocusMap.LayerCount;
i++)
ILayerpLayer=this.mHookHelper.FocusMap.get_Layer(i);
if(pLayer.Name==layerName)
pFeatureLayer=pLay