ArcGIS 开发集锦


1. 目录 1. 目录 ................................................................................................................................................................................................................................................. 1 2. 用 ArcEngine 的工具条添加图层要素 .......................................................................................................................................................................................... 2 3. ArcEngine 中对 Feature 的编辑 ..................................................................................................................................................................................................... 5 4. Feature 的概念 ................................................................................................................................................................................................................................ 6 5. 如何实现经度纬度到平面坐标的相互转换?(转载) ................................................................................................................................................................ 7 6. ArcEngine 最短路径分析(源码) ............................................................................................................................................................ 错误!未定义书签。 7. ArcEngine 中使用上下左右键移动地图功能的实现 ................................................................................................................................................................... 9 8. 缓冲区的创建 ............................................................................................................................................................................................................................... 10 9. C#制作鹰眼全过程(引自 ESRI 中国社区) .................................................................................................................................................................................. 12 10. ArcEngine 中拓扑的使用- - ..................................................................................................................................................................................................... 14 11. 为什么使用接口编程{转载} .................................................................................................................................................................................................... 17 12. ArcEngine 中闪烁目标 ............................................................................................................................................................................................................. 20 13. 创建多个 ArcSDE 实例 ............................................................................................................................................................................................................ 23 14. Geometry 对象浅析 ................................................................................................................................................................................................................. 24 15. 空间查询与空间分析功能 ....................................................................................................................................................................................................... 30 16. AO 中的空间关系 ..................................................................................................................................................................................................................... 32 17. ArcGIS Engine 中的相交分析的实现 ..................................................................................................................................................................................... 34 18. GIS 基本概念集锦 .................................................................................................................................................................................................................... 35 19. AE 开发中矢量图层叠加求交分析 ......................................................................................................................................................................................... 39 20. 矢量数据分析 ........................................................................................................................................................................................................................... 43 21. GIS 空间信息基本分析方法 .................................................................................................................................................................................................... 44 22. 如何判断图形间的逻辑运算 ................................................................................................................................................................................................... 47 23. AE 中 2 种方式 overlay ............................................................................................................................................................................................................ 48 24. ArcEngine 中实现捕捉功能 ..................................................................................................................................................................................................... 52 25. 在 LAYER(i)上添加缓冲区 ..................................................................................................................................................................................................... 73 26. C#编码标准--编码习惯 ....................................................................................................................................................................................................... 74 27. 基于 AE 删除选择的要素- - .................................................................................................................................................................................................... 90 28. 基于 AO/AE 获取要素信息 ..................................................................................................................................................................................................... 91 29. ArcEngine 中拓扑的使用- - ..................................................................................................................................................................................................... 94 30. ArcEngine 渲染的使用 ............................................................................................................................................................................................................ 97 31. 利用 ArcEngin 进行空间分析的简单应用- - ........................................................................................................................................................................ 104 32. IfeatureSelection:SelectFeatures 方法介绍 ............................................................................................................................................................................. 108 33. 常用数据入 sde 库的代码 ...................................................................................................................................................................................................... 110 34. ArcEngine 开发感想 ............................................................................................................................................................................................................... 116 35. Geometry 对象浅析 ............................................................................................................................................................................................................... 118 36. AE 开发中的一些基本方法(1)数据连接 ............................................................................................................................................................................... 128 2. 用 ArcEngine 的工具条添加图层要素 发现 AE 比起其它的组件 GIS 来要好用的多 但也有一些 bt 的地方 比如说 AE 没有提供图层编辑的工具条 但最近因为程序里要添加图元 必须得开发图层编辑的功能 于是去找了找资料 发现自带的帮助里有一个 MapEditing 的示例 但是从 AO 的示例改造而来 需要从按钮写起 想想如果这样搞的话 倒不如直接用 AO 算了 一直想省点事 在 AE 自带的工具条上做点文章 其实 AE 中也有一组相似的编辑按钮,是用于编辑 Graphics 的 自然就有了一个想法:能不能先生成一个 Graphic,然后将其加载进来 琢磨了几日,终于实现了 现在把代码拿出来和大家分享 private void Form1_Load(object sender, System.EventArgs e) { //清空图层 this.axMapControl1.Map.ClearLayers(); //加载服务器 SDE 地图信息 ESRI.ArcGIS.esriSystem.IpropertySet Proset = new ESRI.ArcGIS.esriSystem.PropertySetClass(); //属性集 ESRI.ArcGIS.Geodatabase.IWorkspaceFactory Fact;//工作空间仓库 ESRI.ArcGIS.Geodatabase.IWorkspace Workspace;//工作空间 Proset.SetProperty("Server","服务器名");//服务器名 Proset.SetProperty("Instance","端口");//实例化端口 Proset.SetProperty("user","用户名");//SDE 用户名 Proset.SetProperty("password","密码");//密码 Proset.SetProperty("version","sde.DEFAULT");//连接版本 Fact = new ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactoryClass();//实例化为 SDE 工作空间仓库 Workspace = Fact.Open(Proset,Int32.Parse(this.Handle.ToString()));//填入属性集 ESRI.ArcGIS.Geodatabase.IFeatureWorkspace FeatureWorkspace; FeatureWorkspace = Workspace as ESRI.ArcGIS.Geodatabase.IFeatureWorkspace;//传递给 Feature 工作空间 ESRI.ArcGIS.Geodatabase.IFeatureClass FeatureClass; FeatureClass = FeatureWorkspace.OpenFeatureClass("SDE.BBBB");//填充所需 Feature 集合 ESRI.ArcGIS.Carto.FeatureLayer FLayer = new ESRI.ArcGIS.Carto.FeatureLayerClass(); FLayer.FeatureClass = FeatureClass;//将 Feature 加载到图层 axMapControl1.Map.AddLayer(FLayer);//加载图层 axMapControl1.Update();//更新空白区域 axMapControl1.Refresh();//刷新地图视窗 } private void Form1_Closed(object sender, System.EventArgs e) { ESRI.ArcGIS.esriSystem.IAoInitialize aoi = new ESRI.ArcGIS.esriSystem.AoInitializeClass(); aoi.Shutdown(); } private void button1_Click(object sender, System.EventArgs e) { IGraphicsContainerSelect GraphicsContainerSelect = (IGraphicsContainerSelect)axMapControl1.Map; if(GraphicsContainerSelect.ElementSelectionCount ==0)//判断是否选中图斑 { MessageBox.Show("请选中欲导入图斑!"); return; } IWorkspaceEdit WorkspaceEdit; IFeatureLayer FeatureLayer; IFeatureClass FeatureClass; IFeature Feature; IDataset Dataset; FeatureLayer = (IFeatureLayer)this.axMapControl1.get_Layer(0);//选中导入图层 FeatureClass = FeatureLayer.FeatureClass;//该图层的 feature 集 Dataset = (IDataset)FeatureClass;//该图层的数据集 WorkspaceEdit = (IWorkspaceEdit)Dataset.Workspace;//关联到编辑空间 WorkspaceEdit.StartEditing(true);//使之可编辑 WorkspaceEdit.StartEditOperation();//开始编辑 Feature = FeatureClass.CreateFeature();//创建空 feature Feature.Shape = GraphicsContainerSelect.SelectedElement(0).Geometry;//仅导入最新选中图斑,即多选时只有一个可以导入 Feature.Store(); WorkspaceEdit.StopEditOperation(); WorkspaceEdit.StopEditing(true);//结束编辑并保存 IGraphicsContainer GraphicsContainer = (IGraphicsContainer)GraphicsContainerSelect; GraphicsContainer.DeleteAllElements();//删除 graphic 图层 axMapControl1.ActiveView.Refresh();//刷新当前视图 MessageBox.Show("ok"); } 3. ArcEngine 中对 Feature 的编辑 对 Feature 的编辑分为以下几个部分 1.新建 2.修改 3.删除 涉及到的接口有以下几个 IWorkspaceEdit IFeatureClass IFeatureCursor IFeature 其中 IWorkspaceEdit 用于启动编辑 开始编辑操作 结束编辑操作 结束编辑 IFeatureClass 是数据的所在地 IFeatureCursor 是一个游标 提供访问数据的接口和修改数据的接口 IFeature 是对象的代表 我们要编辑的目标 编辑的过程如下: 1.添加一个 Feature //假设 space 是一个 IWorkspaceEdit //参数表示是否需要使用 Undo/Redo 功能,该功能的粒度是 EditOperator. spaceEdit.StartEditing(false); spaceEdit.StartEditOperator(); //添加一个 Feature IFeature newFea=feaClass.createFeature(); //为 Feature 添加属性 设置图形 newFea.Store();//保存属性和图形 spaceEdit.StopEditOperator();//结束编辑操作 //结束编辑过程 //参数表示是否保存编辑 spaceEdit.StopEditing(true); 2.添加多个 Feature 添加多个 Feature 也可以向上面一样 使用多次就可以了 当时也可以使用 IFeatureCursor 来添加数据 3.修改 Feature 添加 Feature 中的修改属性和图形部分就是 每次修改后一定要调用 Store 方法 这样变化才可以保存下来 4.删除 IFeature 有一个方法 Delete 可以用于删除 当时经过测试发现对 Shapefile 会抛出异常来。 IFeatureCuror 有一个 DeleteFeature 方法 可以用来删除当前的 Feature ,经测试 对所有的数据源类型都可以使用。 注意事项 1.不能设置 Feature 的 OID 2.不能设置 Feature 的 Area 3.不能设置 Feature 的 Lenght 4.不能设置 Feature 的 Shape 字段,需要调用单独的方法来给 Feature 关联几何图形。 4. Feature 的概念 Feature 是二次开发中最常用的对象,feature 是 featureclass 中一个记录,从 object 中派生出来的,因此也具有属性和方法, object 又是从 row 中派生的,所以 featureclass 其实一张表,featured 就是表中的一条记录,feature 可以保存空间数据对象,要 素中的几何型体对象定义了要素的类型,它可以保存的几何型体对象有点、点集、多边形、多义线。这些都是些简单的要素对象,在 有些情况下要素还可以参与拓扑、网络运算。 Feature 相关接口 Feature 有派生出很多类,如:networkfeature、rastercatalogfeature、coverageannotationfeature、annotationfeature、 dimensionfeature。 feature 的主要接口是 Ifeature,其中的 Extent 用来返回要素对象的包络线,显示要素的空间范围;Featuretype 返回要素的类型; Shape 返回要素的几何型体对象;ShapeCopy 得到几何型体对象的一个拷贝。 IfeatureBuffer 中的 Shape 得到缓冲要素的几何型体对象 IfeatureEdit 中 MoveSet、RotateSet、DeleteSet 分别是移动、旋转、删除一个或者是多个要素组成的要素集上。Split 主要是用来 分割几何型体的,通过点分割线,通过多义线分割多边形,分割后旧的被删除,新的要素自动产生。因为每个要素都有对应的属性, 要素改变了,其对应的属性也相应的要改变。Splitattributes 就是用来分割要素属性字段中的值。该方法可以在 Split 方法执行后 自动执行。 IfeatureDraw 中的 InvalidArea 属性得到一个绘画的区域。Draw 在显示设备上绘制要素 IfeatureChanges 中 OriginalShape 得到要素的最初几何类型,ShapeChanged 指示要素的几何类型是否改变。 IfeatureSimplify 中 SimplifyGeometry 按照该元素的拓扑规则进行拓扑一致 5. 如何实现经度纬度到平面坐标的相互转换?(转载) 分类:WebGIS 网络地理信息系统研究 现在好多人在使用 ArcObject 的时候都可能需要作经纬度和平面坐标的相互转换。由于经纬度是球面坐标,平面坐标是 X-Y 的笛卡尔坐标系统,所以这是一个看起来 比较难的问题。 好多人一上来就搬出地图学、地图投影学或者测绘学中的投影公式(如高斯投影 或 墨卡托投影),又是基准坐标又是角度的搞的人头都大了。 实际上要想实现这个功能非常 easy。 ARC Engine 中的 IPoint 就可以进行投影和反投影运算了。 投影过程(C#): /// flatref 投影的坐标系统,这里的 54013 是世界投影 ,世界投影所有经纬度都可以转换为平面坐标,但是由于投影面积大失真也会比较大(相当于把整个地球劈 成一片片的,然后拉伸最后贴到平面上,失真当然大了)。当然也可以选择精度更高的平面如:esriSRProjCS_Beijing1954GK_23N 对应数值 21483 仅仅把北 京附近的地球平面拉伸铺在平面上,由于投影面积变小,所以投影经度提高。但是由于面积变小,所以有些经度纬度不能转换,比如所美国的精度纬度用北京投影就投 不了。 flatref = pfactory.CreateProjectedCoordinateSystem(54013); //没什么说的,标准大地经纬度,可以将 X-Y 逆投影为经度和纬度 earthref = pfactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_NAD1983); /// 将经纬度点转换为平面坐标。 private IPoint GetProject(double x, double y) { IPoint pt = new PointClass(); pt.PutCoords(x, y); IGeometry geo = (IGeometry)pt; geo.SpatialReference = earthref; geo.Project(flatref); return pt; } /// 将平面坐标转换为经纬度。 private IPoint GetGeo(double x, double y) { IPoint pt = new PointClass(); pt.PutCoords(x, y); IGeometry geo = (IGeometry)pt; geo.SpatialReference = flatref; geo.Project(earthref); double xx = pt.X; return pt; }实际上 IPoint 的投影和任何地图都没什么大关系,完全可以不用地图,直接调用 IPoint 进行投影的转换 6. ArcEngine 中使用上下左右键移动地图功能的实现 //闪烁目标 public static void FlashFeature(AxMapControl mapControl,IFeature iFeature, IMap iMap) { IActiveView iActiveView = iMap as IActiveView; if (iActiveView != null) { iActiveView.ScreenDisplay.StartDrawing(0, (short)esriScreenCache.esriNoScreenCache); //根据几何类型调用不同的过程 switch (iFeature.Shape.GeometryType) { case esriGeometryType.esriGeometryPolyline: FlashLine(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; case esriGeometryType.esriGeometryPolygon: FlashPolygon(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; case esriGeometryType.esriGeometryPoint: FlashPoint(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; default: break; } iActiveView.ScreenDisplay.FinishDrawing(); } } //闪烁线 static void FlashLine(AxMapControl mapControl,IScreenDisplay iScreenDisplay,IGeometry iGeometry) { ISimpleLineSymbol iLineSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iLineSymbol = new SimpleLineSymbol(); iLineSymbol.Width = 4; iRgbColor = new RgbColor(); iRgbColor.Red = 255; iLineSymbol.Color = iRgbColor; iSymbol = (ISymbol)iLineSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } //闪烁面 static void FlashPolygon(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry) { ISimpleFillSymbol iFillSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iFillSymbol = new SimpleFillSymbol(); iFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; iFillSymbol.Outline.Width = 12; iRgbColor = new RgbColor(); iRgbColor.RGB = System.Drawing.Color.FromArgb(100, 180, 180).ToArgb(); iFillSymbol.Color = iRgbColor; iSymbol = (ISymbol)iFillSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; iScreenDisplay.SetSymbol(iSymbol); mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } //闪烁点 static void FlashPoint(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry) { ISimpleMarkerSymbol iMarkerSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iMarkerSymbol = new SimpleMarkerSymbol(); iMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle; iRgbColor = new RgbColor(); iRgbColor.RGB = System.Drawing.Color.FromArgb(0, 0, 0).ToArgb(); iMarkerSymbol.Color = iRgbColor; iSymbol = (ISymbol)iMarkerSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } 7. 缓冲区的创建 蓝蓝的小志 发表于 2005-6-5 10:07:08 本文以面图层为例,并且把创建的缓冲区就存储在面图层中,当然也可以把创建的缓冲区另存为一个新的图层。程序运行环境 (.NET+AO) 代码如下: Private Sub ITopologicalOperator_Buffer(ByVal pFeatLyr As ESRI.ArcGIS.Carto.IFeatureLayer, ByVal distance As Double, Optional ByVal pFeatClass As ESRI.ArcGIS.Geodatabase.IFeatureClass = Nothing) 'pFeatLyr 为面图层 'distance 缓冲距离 Dim pFeatureClass As ESRI.ArcGIS.Geodatabase.IFeatureClass Dim pTopoOper As ESRI.ArcGIS.Geometry.ITopologicalOperator Dim pBufferPoly As ESRI.ArcGIS.Geometry.IPolygon Dim pFeatCursor As ESRI.ArcGIS.Geodatabase.IFeatureCursor Dim pFeature As ESRI.ArcGIS.Geodatabase.IFeature Try pFeatureClass = pFeatLyr.FeatureClass pFeatCursor = pFeatureClass.Search(Nothing, False) pFeature = pFeatCursor.NextFeature Do If Not (pFeature Is Nothing) Then pTopoOper = pFeature.Shape() pBufferPoly = pTopoOper.Buffer(distance) 'pFeature = pFeatClass.CreateFeature pFeature.Shape = pBufferPoly pFeature.Store() pFeature = pFeatCursor.NextFeature() End If Loop Until (pFeature Is Nothing) Catch MsgBox(Err.Description, MsgBoxStyle.OKOnly, "错误提示") pFeature = Nothing pFeatCursor = Nothing pBufferPoly = Nothing pTopoOper = Nothing pFeatureClass = Nothing pFeatLyr = Nothing End Try pFeature = Nothing pFeatCursor = Nothing pBufferPoly = Nothing pTopoOper = Nothing pFeatureClass = Nothing pFeatLyr = Nothing End Sub 8. C#制作鹰眼全过程(引自 ESRI 中国社区) 1. axMapControl1 是主控件,axMapControl2 是鹰眼控件 2. 1.鹰眼地图资源载入 3. private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e) 4. { 5. //当主地图显示控件的地图更换时,鹰眼中的地图也跟随更换 6. axMapControl2.LoadMxFile(axMapControl1.DocumentFilename); 7. axMapControl2.Extent = axMapControl2.FullExtent; 8. } 9. 2.绘制鹰眼矩形框 10. private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e) 11. { 12. // 得到新范围 13. IEnvelope pEnv = (IEnvelope)e.newEnvelope; 14. IGraphicsContainer pGra = axMapControl2.Map as IGraphicsContainer; 15. IActiveView pAv = pGra as IActiveView; 16. //在绘制前,清除 axMapControl2 中的任何图形元素 17. pGra.DeleteAllElements(); 18. IRectangleElement pRectangleEle = new RectangleElementClass(); 19. IElement pEle = pRectangleEle as IElement; 20. pEle.Geometry = pEnv; 21. //设置鹰眼图中的红线框 22. IRgbColor pColor = new RgbColorClass(); 23. pColor.Red = 255; 24. pColor.Green = 0; 25. pColor.Blue = 0; 26. pColor.Transparency = 255; 27. //产生一个线符号对象 28. ILineSymbol pOutline = new SimpleLineSymbolClass(); 29. pOutline.Width = 2; 30. pOutline.Color = pColor; 31. //设置颜色属性 32. pColor = new RgbColorClass(); 33. pColor.Red = 255; 34. pColor.Green = 0; 35. pColor.Blue = 0; 36. pColor.Transparency = 0; 37. //设置填充符号的属性 38. IFillSymbol pFillSymbol = new SimpleFillSymbolClass(); 39. pFillSymbol.Color = pColor; 40. pFillSymbol.Outline = pOutline; 41. IFillShapeElement pFillShapeEle = pEle as IFillShapeElement; 42. pFillShapeEle.Symbol = pFillSymbol; 43. pGra.AddElement((IElement)pFillShapeEle, 0); 44. pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); 45. } 46. 3. 实现互动 47. private void axMapControl2_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) 48. { 49. IPoint pPt=new PointClass (); 50. pPt.PutCoords (e.mapX ,e.mapY ); 51. //改变主控件的视图范围 52. axMapControl1 .CenterAt (pPt ); 53. } 9. ArcEngine 中拓扑的使用- - 拓扑(ITopology)的使用包括 1.建立拓扑 2.验证拓扑 3.编辑过程中保证拓扑的正确 4.查询系统中存在的拓扑 1.首先 来看看建立拓扑 Topology 实现了 ITopology 这个接口 但是给类是不能用来创建对象的。 必须要通过调用 ITopologyContainer::CreateTopology 这个方法来建立一个 Topology FeatureDataset 实现了 ITopologyContainer 这个接口。那么 这就是说拓扑只能在一个 FeatureDataset 的范围内建立。而不能独立存在于 Workspace 中。这样做的原因是需要保证 参与同一个拓扑的 FeatureClass 具有同一个投影坐标系统。 建立拓扑后需要将 ObjectClass 加入到拓扑中去。这样这个拓扑就可以用来验证这几个 ObjectClass 的对象之间的关系了。 验证关系就要有规则,规则是由 ITopologyRule 来表达的。ITopologyRule 必须要被 加入到一个 ITopologyRuleContainer 中去。而 Topology 实现了这个接口。 一个 ITopologyRule 用来表达两个 ObjectClass 的对象之间的某个关系。 具体代码参看接口就可以了。 2.验证拓扑 ITopology 有一个方法 ValidateTopology 用来验证指定区域内的拓扑。需要注意 没有版本 的拓扑可以在 任何时候验证。而有版本的拓扑必须在编辑回话中验证。 3.拓扑编辑 1.移动共用点 1.首先需要打开拓扑 建立拓扑图(ITopologyGraph) 代码如下: //topoLayer 是一个打开的拓扑图层 ITopologyGraph pTG=topoLayer.Topology.Cache; pTG.Build(pA.Extent,false); 2.然后 需要获得当前节点或者边 这个操作要使用拓扑图的点击测试 ITopologyElement topeEle pTG.HitTest(... ref topeEle); 这个方法在点击测试成功的时候返回 true.而且会通过 topeEle 这个 ref 参数将选中的元素(点或者边) 返回. 3.还有一种获取节点的方法 首先调用拓扑图的 Select 方法 选中点击测试的元素(pTG.Select) 然后可以查询拓扑图的选中节点集合 就可以找到该节点(pTG.NodeSelection) 4.为该元素使用一个 Feedback. //其中 pNode 就是当前节点 sr 是参考坐标系 可以使用 null //还有给 Feedback 设置 Display m_pNodeFeedback =pTG.GetSplitMoveNodeFeedback(pNode,false,sr); m_pNodeFeedback.Display= activeView.ScreenDisplay; 5.在鼠标移动的时候 调用 Feedback 的 MoveTo 方法。 if(m_pNodeFeedback!=null) { //activeView 是活动的试图 //首先要把将点坐标转换为地图中的坐标。 //然后调用 MoveTo 方法 IPoint pt=activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y); m_pNodeFeedback.MoveTo(pt); } 6.在鼠标释放的时候 //获取拓扑图 ITopologyGraph pTG=topoLayer.Topology.Cache; //转换坐标 IPoint pt=pA.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y); //获得正在做拓扑编辑的元素 ITopologyNode pTN=(ITopologyNode)m_pTopoElement; //实施拓扑编辑 pTG.SplitMoveNode(pTN,pt,false); //提交拓扑编辑结果 IEnvelope pE; pTG.Post(out pE); 4.查询系统中的拓扑 还是 ITopologyContainer 这个接口 这个接口有 FeatureDataset 这个唯一的实现。 CreateTopology 建立一个新的拓扑 DefaultClusterTolerance The default cluster tolerance as per the topology engine. MaximumClusterTolerance The maximal cluster tolerance as per the topology engine. MinimumClusterTolerance The minimal cluster tolerance as per the topology engine. Topology 通过索引打开拓扑. TopologyByID 通过 ID 打开拓扑. TopologyByName 通过名字打开拓扑 TopologyCount 拓扑的数目 10. 为什么使用接口编程{转载} 进行接口的介绍,必须介绍一下程序语言发展的历史才行,鲁迅先生说过“治学先治史”,明白了程序语言发展的前世今生,才能知道为什么这么多语言为什么会这样,为什么么会那样? 计算机出现以后,科学家相继开发了多种语言,从 smalltalk,Pascal,Basic,C 语言,C++,java,.net 等等,这些语言的发展步伐,可以看作是从面向过程向面向对象发展的一段历史。 很多面向对象的书在介绍自己的历史的时候,都会给读者介绍这一段历史,并鼓吹 OO 编程是多么多么的优异。问题是,很多刚开始学程序的人根本不知道为什么要有这个转变,他们也 很难理解 OO 语言中的虚函数,接口等概念到底为了什么而提出来。 我们在了解这一段历史以前,首先给大家介绍一个概念??“粒度”,什么是粒度?作者认为所谓粒度其实就是一个程序中使用代码单元的组合尺度,我们可以举一个例子,沙砾??砖块??房 屋模板,我们设想去修建一座房子,其实有很多中修筑方法,如果你不闲麻烦,可以使用沙砾一点点地建筑,或者将沙砾烧制为砖块,用砖块来砌,甚至直接从工厂购买房屋的门,窗, 墙组件来堆砌。这三种不同的方法代表了三种不同的组合尺度。沙砾是最小的单位,使用它搭建小的房子说不定还可以,但是毫无疑问,我们必须使用很多很多“沙砾”,不便于管理;砖 块比沙砾聚合了一层,可以用来修建较大的房子了;房屋模板是最高的尺寸,使用它可以快速地搭建大规模的房屋。这三种尺度的区别和联系,与我们编写程序概念是有很大的相似之处 的。 在早期学习 Pascal,老师告诉我们这种面向过程语言的最基本的单元是过程和函数,它们是程序中的最小的组件。过程和函数可以实现最基本的代码重用,当我们把某些固定功能的代码 使用过程和函数编写后,我们可以在程序中调用它们而不必在任何需要的地方都写上这样一段代码,这样的好处是显而易见的。在一些小型的程序里面,使用过程和函数是合适的,但是 在大中型程序中,它们的弊端就显示出来,过程和函数的粒度太低了,如果我们一个系统,有 10000 个函数和过程,我们的程序员将不得不花费大量的时间去寻找和维护它们,10000 个 没有任何关系的函数和过程的管理难度是显而易见的,就好像 10000 个人的企业一样,如果没有部门和职务,这还不乱了套?! 面向对象语言的出现,就是为了解决这个问题,别听 OO 语言吹的天花乱坠,其实它出现就为一个理由??提高编程的粒度。面向对象语言的基本单位是类 CLASS,类封装了很多数据成 员和成员函数,过程,将最小组件的提高了一个等级,我们需要直接操作的不是过程和函数了,而是一个个更高层次上的类。我们把 10000 人分了很多部门,不同的部门负责不同的事宜, 这样公司终于可以走上正轨了。 做成了类 CLASS 是否就万事大吉了呢?不一定,新的问题随之而来,也许我们有一个部门的人很多,可以做很多事情,如何在部门内部实现更好的管理呢?好比我们有一个类,它提供 了很多种方法和属性,这些方法和属性其实可以分为一堆堆,为不同的功能服务,但是我们的类并没有做这个管理。在 AO 种,map 对象拥有很多功能,比如管理图层,管理元素,管理 选择集,进行地图显示,每种不同的功能都有好多方法和属性,现在这些属性和方法是杂乱无章,没有任何区别堆积在一个类里面的,当我们的程序员需要寻找一个方法的时候,不得不 一个个去寻找,很不方便。 这个时候,接口 interface 出现了,C++的发明者第一次提出纯虚函数(其实就是接口)概念的时候,遭到了很多抵制,很多人都不明白接口的意义何在,我们用虚函数好好的,何必又出 来个啥东西都没有的空架子?说它是类吧,又不能实现产生一个对象;说它是对象吧,又没有方法体来使用。接口出来干了一件好事,就是将类内部进行分类。对于 map 对象,我们可 以做好几个接口,这些接口中定义不同功能的方法,函数和属性,map 类实现这些接口,这样我们可以使用接口定义,实现对象。因此,所谓接口就是一系列相关方法与属性集合的定义。 Dim pGraphicsContainer as iGraphicsContainer pGraphicsContainer=application.document.ActiveView.focusMap pGraphicsContainer 可以使用的属性和方法就只能是它定义的那部分了,而不能使用管理元素等的接口定义的方法和属性,那我们如何使用其它的功能呢?这就是所谓的 QI(Query Inter face)功能。从一个接口查询另一个接口。 Dim pGeoFeatureLayer as iGeofeatureLayer pGeoFeatureLayer= pGraphicsContainer QI 好了,我们罗嗦了这么多,已经走进了 COM 的概念了,在正式介绍 COM 以前我们得最后罗嗦一点:计算机语言的发展历史,其实就是一部不断提高组件粒度的历史,不断提高代码重 用的历史。以前我们使用过程和函数,后来我们使用类,现在我们使用接口,都是为了一个目的,让我们操作的组件在具体和抽象之间寻找一个平衡点。太具体了,如过程和函数,就没 有了框架;太抽象,如类,就无法分别。 一个代码示例: public interface IForm { void Show(); void ShowDialog(); } public class A:IForm { public void Show() { } public void ShowDialog() { } } public class B:IForm { public void Show() { } public void ShowDialog() { } } public class FormFactory { public static IForm CreateInstance(string parm) { if (parm == "A") { return new A(); else if (parm == "B") return new B(); } return null; } } 这是逻辑的抽象 这是方法的具体 这就是编写程序的哲学. 11. ArcEngine 中闪烁目标 //闪烁目标 public static void FlashFeature(AxMapControl mapControl,IFeature iFeature, IMap iMap) { IActiveView iActiveView = iMap as IActiveView; if (iActiveView != null) { iActiveView.ScreenDisplay.StartDrawing(0, (short)esriScreenCache.esriNoScreenCache); //根据几何类型调用不同的过程 switch (iFeature.Shape.GeometryType) { case esriGeometryType.esriGeometryPolyline: FlashLine(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; case esriGeometryType.esriGeometryPolygon: FlashPolygon(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; case esriGeometryType.esriGeometryPoint: FlashPoint(mapControl, iActiveView.ScreenDisplay, iFeature.Shape); break; default: break; } iActiveView.ScreenDisplay.FinishDrawing(); } } //闪烁线 static void FlashLine(AxMapControl mapControl,IScreenDisplay iScreenDisplay,IGeometry iGeometry) { ISimpleLineSymbol iLineSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iLineSymbol = new SimpleLineSymbol(); iLineSymbol.Width = 4; iRgbColor = new RgbColor(); iRgbColor.Red = 255; iLineSymbol.Color = iRgbColor; iSymbol = (ISymbol)iLineSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } //闪烁面 static void FlashPolygon(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry) { ISimpleFillSymbol iFillSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iFillSymbol = new SimpleFillSymbol(); iFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; iFillSymbol.Outline.Width = 12; iRgbColor = new RgbColor(); iRgbColor.RGB = System.Drawing.Color.FromArgb(100, 180, 180).ToArgb(); iFillSymbol.Color = iRgbColor; iSymbol = (ISymbol)iFillSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; iScreenDisplay.SetSymbol(iSymbol); mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } //闪烁点 static void FlashPoint(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry) { ISimpleMarkerSymbol iMarkerSymbol; ISymbol iSymbol; IRgbColor iRgbColor; iMarkerSymbol = new SimpleMarkerSymbol(); iMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle; iRgbColor = new RgbColor(); iRgbColor.RGB = System.Drawing.Color.FromArgb(0, 0, 0).ToArgb(); iMarkerSymbol.Color = iRgbColor; iSymbol = (ISymbol)iMarkerSymbol; iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; mapControl.FlashShape(iGeometry, 3, 200, iSymbol); } 12. 创建多个 ArcSDE 实例 编号: 000037 相关产品及版本: ArcSDE 3.x,8.x,9.0 平台: N/A 提交时间: 2004-08-23 修改时间: 2004-08-31 提交人: 吴乐茂 内容摘要 有时候,我们需要有多于一个的 ArcSDE 实例同时运行。只要存在多个数据库实例,就可以实现这个目的。ArcSDE 与 RDBMS 之间必须是一个一一对应的关系。 ArcSDE 会锁定版本表,以保证每个数据库实例只对应一个 ArcSDE 实例。 过程描述 对于 Windows: 1. 拷贝 %SDEHOME% 到一个新的位置。 2. 用适当的 RDBMS 连接变量(如 RACLE_SID)更新新的 dbinit.sde 文件。 3. 用新的实例名、端口号和网络协议更新 %SDEHOME%etcservices.sde 文件。 4. 添加服务名、端口号和网络协议到 WINNTsystem32driversetcservices 文件中。须确认所用的端口号没有被用过。 5. 删除新的 giomgr.log 文件中的内容。 6. 如果需要,更新新的 giomgr.defs 文件,以指定新实例的操作参数。 7. 如果需要,更新新的 dbtune.sde 文件,以指定参数给在新实例的数据库中创建数据时使用。 8. 确认 SDEHOME 变量指向正确的新 ArcSDE 实例位置,并运行给对应数据库使用的 sdesetup 命令来创建新数据的存储表。 9. 使用 “sdeservice -o create” 命令创建新的 ArcSDE 服务。 对于 UNIX: 1. 给新实例创建一个新的工作目录。 2. 拷贝 $SDEHOME 到新创建的工作目录。 3. 用适当的 RDBMS 连接变量(如 ORACLE_SID)更新新的 dbinit.sde 文件。 4. 用新的实例名、端口号和网络协议更新 $SDEHOME/etc/services.sde 文件。 5. 添加服务名、端口号和网络协议到 /etc/services 文件。须确认所用的端口号没有被用过。 6. 删除新的 giomgr.log 文件中的内容。 7. 如果需要,更新新的 giomgr.defs 文件,以指定新实例的操作参数。 8. 如果需要,更新新的 dbtune.sde 文件,以指定参数给在新实例的数据库中创建数据时使用。 9. 确认 SDEHOME 变量指向正确的新 ArcSDE 实例位置,并运行给对应数据库使用的 sdesetup 命令来创建新数据的存储表。 常用 ArcSDE 命令 启动 cmd 1. 创建和删除 ArcSDE 服务操作命令(sdeservice) 创建 ArcSDE for oracle9i 服务 sdeservice -o create -d oracle9i,sid -p sde -i esri_sde 删除 ArcSDE for oracle9i 服务 sdeservice -o delete -i esri_sde -d oracle9i,sid 注:-d 后面填写数据库类型及其 SID sdeservice 命令帮助 创建、删除 SDE 服务 2.ArcSDE 服务操作命令(sdemon) 检测服务状态命令: Sdemon -o status -I esri_sde 启动服务命令: Sdemon -o start -I esri_sde -p sde 停止服务命令: Sdemon -o shutdown -I esri_sde -p sde Sdemon 命令帮助 更多操作命令,请查看路径“\ArcSDE\ora9iexe\bin”下的“*.exe”文件 13. Geometry 对象浅析 [ 来源:cnblogs.com | 作者:Flyingis | 时间:2007-04-20 09:26:57 | 收藏本文 ] 【大 中 小】 ArcEngine Geometry 库定义了基本几何图形的矢量表达形式,顶级的几何图形有 Points、Multipoints、Polylines、Polygons、 Multipatches,Geodatabase 和绘图系 统使用这些几何图形来定义其他各种形状的特征和图形,提供了编辑图形的操作方法和地图符号系统符号化特征数据的途径。 Geometry 库中几个核心类和接口构成了 Geometry 对象的基本框架。 GeometryEnvironment GeometryEnvironment 提供了从不同的输入、设置或获取全局变量来创建几何图形的方法,以便控制 geometry 方法的行为。GeometryEnvironment 对象是一 个单例对象。 以下为引用的内容: public IPolyline TestGeometryEnvironment() { ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass(); //Create a projected coordinate system and define its domain, resolution, and x,y tolerance. IspatialReferenceResolution spatialReferenceResolution = spatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_NAD1983UTM_11N) as ISpatialReferenceResolution; spatialReferenceResolution.ConstructFromHorizon(); ISpatialReferenceTolerance spatialReferenceTolerance = spatialReferenceResolution as ISpatialReferenceTolerance; spatialReferenceTolerance.SetDefaultXYTolerance(); ISpatialReference spatialReference = spatialReferenceResolution as ISpatialReference; Chinaz.com //Create an array of WKSPoint structures starting in the middle of the x,y domain of the //projected coordinate system. double xMin; double xMax; double yMin; double yMax; spatialReference.GetDomain(out xMin, out xMax, out yMin, out yMax); double xFactor = (xMin + xMax) * 0.5; double yFactor = (yMin + yMax) * 0.5; WKSPoint[] wksPoints = new WKSPoint[10]; for (int i = 0; i < wksPoints.Length; i++) { wksPoints[i].X = xFactor + i; wksPoints[i].Y = yFactor + i; } IPointCollection4 pointCollection = new PolylineClass(); IGeometryBridge2 geometryBridge = new GeometryEnvironmentClass(); geometryBridge.AddWKSPoints(pointCollection, ref wksPoints); IPolyline polyline = pointCollection as IPolyline; polyline.SpatialReference = spatialReference; return polyline; } new GeometryEnvironmentClass 仅仅是创建了一个指向已存在的 GeometryEnvironmentClass 的引用。注意 IGeometryBridge2 接口的使用,addWKSPoints 方 法将 WKSPoint 二维点添加到 PointCollection 中,用于构建 path、ring、polyline、polygon,或增加新点到 Multipoint、TriangleFan、TriangleStrip。在 Geometry 库中,除了 IGeometryBridge2 还有 IGeometryBridge 接口,后者继承了前者,增加了一些编辑功能(添加点、插入点、重置点、分段等)。 GeometryBag GeometryBag 是支持 IGeometry 接口的几何对象引用的集合,任何几何对象都可以通过 IGeometryCollection 接口添加到 GeometryBag 中,但是在使用拓扑 操作的时候,需要注意不同类型的几何类型可能会有相互不兼容的情况。在向 GeometryBag 中添加几何对象的时候,GeometryBag 对象需要指定空间参考,添 加到其中的几何对象均拥有和 GeometryBag 对象一样的空间参考。 以下为引用的内容: private IPolygon GeometryBag_Example(IFeatureClass featureClass) { //Check input objects. if (featureClass == null) { return null; } IGeoDataset geoDataset = featureClass as IGeoDataset; ISpatialFilter queryFilter = new SpatialFilterClass(); //Set the properties of the spatial filter here. IGeometry geometryBag = new GeometryBagClass(); //Define the spatial reference of the bag before adding geometries to it. geometryBag.SpatialReference = geoDataset.SpatialReference; //Use a nonrecycling cursor so each returned geometry is a separate object. IFeatureCursor featureCursor = featureClass.Search(queryFilter, false); IGeometryCollection geometryCollection = geometryBag as IGeometryCollection; IFeature currentFeature = featureCursor.NextFeature(); while (currentFeature != null) { //Add a reference to this feature's geometry into the bag. //You don't specify the before or after geometry (missing), //so the currentFeature.Shape IGeometry is added to the end of the geometryCollection. object missing = Type.Missing; geometryCollection.AddGeometry(currentFeature.Shape, ref missing, ref missing); currentFeature = featureCursor.NextFeature(); } // Create the polygon that will be the union of the features returned from the search cursor. // The spatial reference of this feature does not need to be set ahead of time. The // ConstructUnion method defines the constructed polygon's spatial reference to be the same as // the input geometry bag. ITopologicalOperator unionedPolygon = new PolygonClass(); unionedPolygon.ConstructUnion(geometryBag as IEnumGeometry); return unionedPolygon as IPolygon; } Points 一个点包括 X、Y 坐标,同时可以增加 M、Z 值及 ID 属性来扩展点的功能。 Multipoints 点的集合,多点组成 Multipoint 几何类型,使用 multipoint 对象实现了的 IPointCollection 接口可以访问所有的点元素,这些点同样可以拥有 M、Z 值及 ID 属性来获得更多的地理空间内涵。 下面列举一个例子,通过一个已知的 polyline 来定义一个新的 multipart polyline。 以下为引用的内容: public IPolyline ConstructMultiPartPolyline(IPolyline inputPolyline) { IGeometry outGeometry = new PolylineClass(); //Always associate new, top-level geometries with an appropriate spatial reference. outGeometry.SpatialReference = inputPolyline.SpatialReference; IGeometryCollection geometryCollection = outGeometry as IGeometryCollection; ISegmentCollection segmentCollection = inputPolyline as ISegmentCollection; //Iterate over existing polyline segments using a segment enumerator. Chinaz^com IEnumSegment segments = segmentCollection.EnumSegments; ISegment currentSegment; int partIndex = 0;; int segmentIndex = 0;; segments.Next(out currentSegment,ref partIndex, ref segmentIndex); while(currentSegment != null) { ILine normal = new LineClass(); //Geometry methods with _Query_ in their name expect to modify existing geometries. //In this case, the QueryNormal method modifies an existing line //segment (normal) to be the normal vector to //currentSegment at the specified location along currentSegment. currentSegment.QueryNormal(esriSegmentExtension.esriNoExtension, 0.5, true, currentSegment.Length / 3, normal); //Since each normal vector is not connected to others, create a new path for each one. ISegmentCollection newPath = new PathClass(); object missing = Type.Missing; newPath.AddSegment(normal as ISegment, ref missing, ref missing); //The spatial reference associated with geometryCollection will be assigned to all incoming paths and segments. geometryCollection.AddGeometry(newPath as IGeometry, ref missing, ref missing); segments.Next(out currentSegment,ref partIndex, ref segmentIndex); } //The geometryCollection now contains the new, multipart polyline. return geometryCollection as IPolyline; } ISegment 接口的 QueryNormal 方法用来在弧段上的某一点生成该弧段的法线,指定其长度,这样就生成了新的 segment,并且多个 path 添加到 geometryCollection 中,以 IPolyline 的形式返回。 Polylines Polylines 是有序 path 组成的集合,可以拥有 M、Z 和 ID 属性值。Polyline 对象的 IPointCollection 接口包含了所有节点的复制,IGeometryCollection 接口可 以获取 polyline 的 paths,ISegmentCollection 接口可以获取 polyline 的 segments。 Polyline 结构图 Polygons Polygon 是一系列 rings 组成的集合,可以拥有 M、Z 和 ID 属性值。每一个 ring 由一个或多个 segment 组成,Polygon 或 ring 对象的 IPointCollection 接口包 含了所有节点的复制,IGeometryCollection 接口可以获取 polygon 的 rings, ISegmentCollection 接口可以获取 polygon 的 segments。 Polygon 结构图 Multipatch Multipatch 用于描述 3D 面状几何类型,由一系列的矢量三角形构成,如果其中的 part 是一个 ring,那么它必须是封闭的,第一个节点和最后一个节点相同, 另外每个 part 所包含节点的顺序非常重要,Inner Rings 在 Outer Rings 之后,代表单个表面 patch 的一系列 rings 必须由第一个 ring 开始。 在 9.0 以后的开发包中,使用 IGeneralMultiPatchCreator 创建新的 Multipatch,IGeometryMaterial 进行材质贴图。 以下为引用的内容: public IMultiPatch CreateMultipatch() { //Prepare the geometry material list. IGeometryMaterial texture = new GeometryMaterialClass(); texture.TextureImage = "C:\\Temp\\MyImage.bmp"; IGeometryMaterialList materialList = new GeometryMaterialListClass(); materialList.AddMaterial(texture); //Create the multipatch. IGeneralMultiPatchCreator multiPatchCreator = new GeneralMultiPatchCreatorClass(); multiPatchCreator.Init(4, 1, false, false, false, 4, materialList); //Set up part. //Could also use a Ring or a TriangleFan. multiPatchCreator.SetPatchType(0, esriPatchType.esriPatchTypeTriangleStrip); multiPatchCreator.SetMaterialIndex(0, 0); multiPatchCreator.SetPatchPointIndex(0, 0); multiPatchCreator.SetPatchTexturePointIndex(0, 0); //Set real-world points. WKSPointZ upperLeft = new WKSPointZ(); WKSPointZ lowerLeft = new WKSPointZ(); WKSPointZ upperRight = new WKSPointZ(); WKSPointZ lowerRight = new WKSPointZ(); upperLeft.X = 0; upperLeft.Y = 0; upperLeft.Z = 0; upperRight.X = 300; upperRight.Y = 0; upperRight.Z = 0; lowerLeft.X = 0; lowerLeft.Y = 0; lowerLeft.Z = -100; lowerRight.X = 300; lowerRight.Y = 1; lowerRight.Z = -100; multiPatchCreator.SetWKSPointZ(0, ref upperRight); multiPatchCreator.SetWKSPointZ(1, ref lowerRight); multiPatchCreator.SetWKSPointZ(2, ref upperLeft); multiPatchCreator.SetWKSPointZ(3, ref lowerLeft); //Set texture points. //Set the texture coordinates for a panel. WKSPoint textureUpperLeft = new WKSPoint(); WKSPoint textureLowerLeft = new WKSPoint(); WKSPoint textureUpperRight = new WKSPoint(); WKSPoint textureLowerRight = new WKSPoint(); textureUpperLeft.X = 0; textureUpperLeft.Y = 0; textureUpperRight.X = 1; textureUpperRight.Y = 0; textureLowerLeft.X = 0; textureLowerLeft.Y = 1; textureLowerRight.X = 1; textureLowerRight.Y = 1; multiPatchCreator.SetTextureWKSPoint(0, ref textureUpperRight); multiPatchCreator.SetTextureWKSPoint(1, ref textureLowerRight); multiPatchCreator.SetTextureWKSPoint(2, ref textureUpperLeft); multiPatchCreator.SetTextureWKSPoint(3, ref textureLowerLeft); IMultiPatch multiPatch = multiPatchCreator.CreateMultiPatch() as IMultiPatch; return multiPatch; } 14. 空间查询与空间分析功能 GIS 的面向用户的应用功能不仅仅表现在它能提供一些静态的查询、检索数据,更有意义的在于用户可以根据需要建立一个应用分析的模式,通过动态的分析, 从而为评价、管理和决策服务。这种分析功能可以在系统操作运算功能的支持下或建立专门的分析软件来实现,如空间信息量测与分析、统计分析、地形分析、 网络分析、叠置分析、缓冲分析、决策支持等。系统本身是否具有建立各种应用模型的功能是判别它好坏的重要标志之一,因为这种功能在很大程度上决定了 该系统在实际应用中的灵活性和经济效益。 空间查询和空间分析是从 GIS 目标之间的空间关系中获取派生的信息和新的知识,用以回答有关空间关系的查询和应用分析。 拓扑空间查询 在此操作中,用户将地图当作查询工具,而不仅仅是数据载体。空间目标之间的拓扑关系可以有两类:一种是几何元素的结点、弧段和面块之间的关联关系, 用以描述和表达几何元素间的拓扑关系;另一种是 GIS 中地物之间的空间拓扑关系,可以通过关联关系和位置关系隐含表达,用户需通过特殊的方法查询。 这些空间关系主要有以下几项:面与面的关系,如检索与某个面状地物相邻的所有多边形及属性;线与线的关系,如检索与某一主干河相关联的所有支流;点 与点的关系,如检索到某点一定距离内的所有点状地物;线与面的关系,如检索某公路所经过的所有县市或某县市内的所有公路;点与线的关系,如某河流上 的所有桥梁;点与面的关系,如检索某市所有银行分布点。 缓冲区分析 缓冲区用以确定围绕某地要素绘出的定宽地区,以满足一定的分析条件。点的缓冲区是个圆饼,线的缓冲区是个条带状,多边形的缓冲区则是个更大的相似多 边形。缓冲区分析是 GIS 中基本的空间分析功能之一,尤其对于建立影响地带是必不可少的。如道路规划中建立缓冲区以确定道路两边若干距离内的土地利用 性质。 叠加分析 叠加分析提供根据两幅或两幅以上图层在空间上比较地图要素和属性的能力,通常有合成叠加和统计叠加之分,前者是根据两组多边形边界的交点建立具有多 重属性的多边形,后者则进行多边形范围的属性特征统计分析(如图 1-3 所示)。合成叠加得到一张新的叠加图,产生了许多新多边形,每个多边形都具有两种 以上的属性。统计叠加的目的是统计一种要素在另一种要素中的分布特征。 距离分析及相邻相接分析 距离分析提供了在地图上距离的功能,相邻分析确定哪些地图要素与其它要素相接触或相邻,而相接分析则结合距离和相邻分析两者的针对性,提供确定地图 要素间邻近或邻接的功能。相邻和相接分析广泛应用于环境规划和影响评价的公共部门。大多数 GIS 软件目前不能直接进行相邻相接分析,而是通过先建立一 定要求的缓冲区,再与其它图形要素进行叠置分析的间接方法解决。 地形分析功能 通过数字地形模型 DTM,以离散分布的平面点来模拟连续分布的地形,再从中内插提取各种地形分析数据,地形分析包括以下内容: 等高线分析 等高线图是人们传统上观测地形的主要手段,可以从等高线上精确地获得地形的起伏程度,区域内各部分的高程等。 透视图分析 等高线虽然精确,但不够直观,用户往往需要从直观上观察地形的概貌,所以 GIS 通常具有绘制透视图的功能,有些系统还能在三维空间格网上着色,使图形 更为逼真。 坡度坡向分析 在 DTM 中计算坡度和坡向,派生出坡度坡向图供地形分析(如日照分析、土地适宜性分析等)。 断面图分析 用户可以在断面图上考察该剖面地形的起伏并计算剖面面积,以便用于工程设计和工程量算。 地形表面面积和填挖方体积计算 利用 DTM 数据,可以比较容易地求出所需要地区的地形表面面积以及施工区域内填挖方的体积(土石方量)。 制图功能、地理数据库、空间查询与空间分析能力是 GIS 最具有独特吸引力所在。而系统是否具有良好的用户接口和各种应用分析程序的支持也是至关重要的, 但是应由 GIS 开发人员和用户来共同完成的。 地理信息系统技术广泛应用于农业、林业、国土资源、地矿、军事、交通、测绘、水利、广播电视、通讯、电力、公安、社区管理、教育、能源等几乎所有的 行业,并正在走进人们日常的工作、学习和生活中。 地理信息系统的主要任务是对与地理空间位置或区域有关的社会经济、人文景观、自然资源及环境等多种信息进行综合管理和分析,主要任务有以下三个方面 15. AO 中的空间关系 最近在做 AO 的一些东西,有些空间关系让我搞不太懂,查到一个东西,还是很好的 名词解释: Boundary(边界): 只有线和面才有边界。面的边界是指组成面的框架线;线的边界是指线的二个端点(即起点和终点,不包括中间部分的节点);点没有边界。 Interior(内部): 除去边界后剩下的部分即是一个要素的内部。因此线的内部指除去端点后的部分;面的内部是指除去框架线后的部分;点的内部就是点本身。 Exterior(外部): 除去该要素后的剩余的空间范围即是该要素的外部。 空间关系具体描述(Queryable Spatial Relationships): 示意图: 空间关系: 1, esriSpatialRelTouches(邻接) 应用范围: 除点与点之间的关系外,其它的要素之间都可以具有该关系。 描述: 如果二个要素有相同的边界,且它们内部不相交的话,称这二个要素之间的关系是邻接的关系,图 1-1、2-1、3-1、3-2,注意图 3-3 中点与线是包涵的关系。 当查询要素和被查询要素具有该关系时,即 spatialRel 的值是 esriSpatialRelTouches,则会返回查询要素。 2, esriSpatialRelCrosses (交叉) 应用范围: 线与面,线与线等。不能用于面与面(面与面相交部分是面,不能二个要素中的最高维数低一),面与点,点与线(二个要素的维数差 2)。 描述: 如果二个要素的相交部分不为空,并且相交部分形状的维数比两个要素中最高维数低 1(即线面交叉是线,线线交叉是点)则称这二个要素具有交叉关系,图 2-4、4-1,图 2-1 中中二条线的关系属于邻接关系,而不属于交叉关系,因为它们的内部相交部分为空。 当查询要素和被查询要素具有该关系时,即 spatialRel 的值是 esriSpatialReCrosses,则会返回查询要素。 3, esriSpatialRelOverlaps(重叠关系) 应用范围: 线与线,面与面之间,其它的不具有该关系。 描述: 二个同维的要素之间的相交部分的图形具有与这二个要素相同的维数的,且不与任何一个要素完全相同,则称这二个要素重叠。图 1-2、2-2 均是重叠关系,但是 2-3 中的二条 线不是重叠关系,因为相交的部分与黄色的线完全相同。 当查询要素和被查询要素具有该关系时,即 spatialRel 的值是 esriSpatialRelOverlaps,则会返回查询要素。 4,esriSpatialRelWithin 和 esriSpatialRelContains(包涵) 应用范围: 所有要素类之间均具有该关系。 描述: 该关系可细分为一个要素完全位于另一个要素的内部和一个要素完全包涵另外一个要素,它们是相对的关系。如果说要素 1 完全位于要素 2 的内部,则要素 2 完全包涵要素 1。 当查询的要素完全位于被查询的要素内部的话(即 spatialRel 的值是 esriSpatialRelWithin),则返回被查询的要素;同时如果查询的要素完全被被查询的要素包括时(即 spatialRel 的值是 esriSpatialRelContains)则返回被查询的要素。 5,esriSpatialRelIntersects(相交) 描述: 相交关系是一个广义的关系,包括上述 4 种关系。因此如果 spatialRel 的值是 esriSpatialRelIntersects 关系的话,只要查询要素和被查询要素之间满足上述四种空间关系的 任一种空间关系,即可返回被查询的要素。 6,esriSpatialRelRelate 描述: 需要通过 SpatialRelDescription 属性对二个要素的空间关系进行定制,可以对二个要素的内部,外部,边界之间的相交的情况进行描述,例如:字符串'****T***'代表的是二 个要素共享边界。 16. ArcGIS Engine 中的相交分析的实现 在 ArcGIS Engine 中实现点和面进行相交分析,应该是用 IBasicGeoprocessor.Intersect 方法,不知道对不对啊? 用点和面进行相交分析,主要目的是为了确定点在哪个区域内!比如可以用一个井的点图层和一个行政区划的面图层进行相交分析,得到的是一个井的点图层, 而此图层的属性包含了两个图层的属性,从而通过对属性表的查询,来确定在某个区域内井的个数等等信息。 以下代码编译通过,但是在运行时,就报错,说是参数错误,各位帮忙看看,谢谢!! 1 private void M_OverLayer_Click(object sender, System.EventArgs e) 2 { 3 try 4 { 5 //分析层 6 ILayer pLayer=this.axMapControl1.get_Layer(0); 7 IFeatureLayer pInputFeatLayer=pLayer as IFeatureLayer; 8 ITable pInputTable=pLayer as ITable; 9 IFeatureClass pInputFeatClass=pInputFeatLayer.FeatureClass; 10 11 //叠加表 12 pLayer=this.axMapControl1.get_Layer(1); 13 ITable pOverlayTable=pLayer as ITable; 14 15 //叠加分析表 16 IFeatureClassName pFeatClassName=new FeatureClassNameClass(); 17 pFeatClassName.FeatureType=esriFeatureType.esriFTSimple; 18 pFeatClassName.ShapeFieldName="shape"; 19 pFeatClassName.ShapeType=pInputFeatClass.ShapeType; 20 21 //工作空间名称 22 IWorkspaceName pNewWSName=new WorkspaceNameClass(); 23 pNewWSName.WorkspaceFactoryProgID = "esriDataSourcesFile.ShapefileWorkspaceFactory"; 24 pNewWSName.PathName = @"C:\temp"; 25 26 //数据集名称 27 IDatasetName pDatasetName=pFeatClassName as IDatasetName; 28 pDatasetName.Name="ss"; 29 pDatasetName.WorkspaceName=pNewWSName; 30 31 //几何处理 32 IBasicGeoprocessor pBGP=new BasicGeoprocessorClass(); 33 IFeatureClass pOutputFeatClass=pBGP.Intersect(pInputTable,false,pOverlayTable,false,0.01,pFeatClassName); 34 35 //输出要素层设置 36 IFeatureLayer pOutputFeatLayer=new FeatureLayerClass(); 37 pOutputFeatLayer.FeatureClass=pOutputFeatClass; 38 pOutputFeatLayer.Name=pOutputFeatClass.AliasName; 39 40 this.axMapControl1.AddLayer((ILayer)pOutputFeatClass,0); 41 axMapControl1.Update(); 42 } 43 catch(Exception ex) 44 { 45 MessageBox.Show(ex.Message); 46 } 47 } 17. GIS 基本概念集锦 1、地理信息系统(geographic information system ,即 gis )——一门集计算机科学、信息学、地理学等多门科学为一体的新兴学科,它是在计算机软件和硬件 支持下,运用系统工程和信息科学的理论,科学管理和综合分析具有空间内涵的地理数据,以提供对规划、管理、决策和研究所需信息的空间信息系统。gis 有 以下子系统:数据输入子系统,数据存储和检索子系统,数据操作和分析子系统,报告子系统. 信息系统 非空间的 空间的 管理信息系统 非地理学的 gis cad/cam 其他 gis lis 社会经济,人口普查 基于非地块,基于地块的 2、比较 gis 与 cad、cac 间的异同。 cad——计算机辅助设计,规则图形的生成、编辑与显示系统,与外部描述数据无关。 cac——计算机辅助制图,适合地图制图的专用软件,缺乏空间分析能力。 gis——地理信息系统,集规则图形与地图制图于一身,且有较强的空间分析能力。 3、图层:将空间信息按其几何特征及属性划分成的专题。 4、地理数据采集——实地调查、采样;传统的测量方法,如三角测量法、三边测量法;全球定位系统(gps);现代遥感技术;生物遥测学;数字摄影技术;人 口普查。 5、信息范例——传统的制图方法,称为信息范例,即假定地图本身是一个最终产品,通过使用符号、分类限制的选择等方式交换空间信息的模式。这个范例是 传统的透视图方法,由于原始而受到很多限制,地图用户不能轻易获得预分类数据。也就是说,用户只限于处理最终产品,而无法将数据重组为更有效的形式 以适应环境或需求的变化。 6、分析范例(整体范例)——存储保存原始数据的属性数据,可根据用户的需求进行数据的显示、重组和分类。整体范例是一种真正的用于制图学和地理学的 整体方法。 7、栅格——栅格结构是最简单最直接的空间数据结构,是指将地球表面划分为大小均匀紧密相邻的网格阵列,每个网格作为一个象元或象素由行、列定义,并 包含一个代码表示该象素的属性类型或量值,或仅仅包括指向其属性记录的指针。因此,栅格结构是以规则的阵列来表示空间地物或现象分布的数据组织,组 织中的每个数据表示地物或现象的非几何属性特征。特点:属性明显,定位隐含,即数据直接记录属性本身,而所在的位置则根据行列号转换为相应的坐标, 即定位是根据数据在数据集中的位置得到的,在栅格结构中,点用一个栅格单元表示;线状地物用沿线走向的一组相邻栅格单元表示,每个栅格单元最多只有 两个相邻单元在线上;面或区域用记有区域属性的相邻栅格单元的集合表示,每个栅格单元可有多于两个的相邻单元同属一个区域。 8、矢量——它假定地理空间是连续,通过记录坐标的方式尽可能精确地表示点、线、多边形等地理实体,坐标空间设为连续,允许任意位置、长度和面积的精 确定义。对于点实体,矢量结构中只记录其在特定坐标系下的坐标和属性代码;对于线实体,用一系列坐标对的连线表示;多边形是指边界完全闭合的空间区 域,用一系列坐标对的连线表示。 9、“拓扑”(topology)一词来源于希腊文,它的原意是“形状的研究”。拓扑学是几何学的一个分支,它研究在拓扑变换下能够保持不变的几何属性——拓扑属 性(拓扑属性:一个点在一个弧段的端点,一个点在一个区域的边界上;非拓扑属性:两点之间的距离,弧段的长度,区域的周长、面积)。这种结构应包括: 唯一标识,多边形标识,外包多边形指针,邻接多边形指针,边界链接,范围(最大和最小 x、y 坐标值)。地理空间研究中三个重要的拓扑概念(1)连接性: 弧段在结点处的相互联接关系;(2)多边形区域定义:多个弧段首尾相连构成了多边形的内部区域;(3)邻接性:通过定义弧段的左右边及其方向性来判断弧 段左右多边形的邻接性。 10、矢量的实体错误——伪节点:即需要假节点进行识别的节点,发生在线和自身相连接的地方(如岛状伪结点——显示存在一个岛状多边形,这个多边形处 于另一个更大的多边形内部),或发生在两条线沿着平行路径而不是交叉路径相交的地方(节点——表示线与线间连接的特殊点)。摇摆结点:有时称为摇摆, 来源于 3 种可能的错误类型:闭合失败的多边形;欠头线,即结点延伸程度不够,未与应当连接的目标相连;过头线,结点的线超出想与之连接的实体。碎多 边形:起因于沿共同边界线进行的不良数字化过程,在边界线位置,线一定是不只一次地被数字化。高度不规则的国家边境线,例如中美洲,特别容易出现这 样的数字变形。标注错误:丢失标注和重复标注。异常多边形:具有丢失节点的多边形。丢失的弧。 11、空间分析方法——1、空间信息的测量:线与多边形的测量、距离测量、形状测量;2、空间信息分类:范围分级分类、邻域功能、漫游窗口、缓冲区;3、 叠加分析:多边形叠加、点与多边形、线与多边形;4、网络分析:路径分析、地址匹配、资源匹配; 5、空间统计分析:插值、趋势分析、结构分析;6、表 面分析:坡度分析、坡向分析、可见度和相互可见度分析。 12、欧拉数——最通常的空间完整性,即空洞区域内空洞数量的度量,测量法称为欧拉函数,它只用一个单一的数描述这些函数,称为欧拉数。数量上,欧拉 数=(空洞数)-(碎片数-1),这里空洞数是外部多边形自身包含的多边形空洞数量,碎片数是碎片区域内多边形的数量。有时欧拉数是不确定的。 13、函数距离——描述两点间距离的一种函数关系,如时间、摩擦、消耗等,将这些用于距离测量的方法集中起来,称为函数距离。 14、曼哈顿距离——两点在南北方向上的距离加上在东西方向上的距离,即 d(i,j)=|xi-xj|+|yi-yj|。对于一个具有正南正北、正东正西方向规则布局的城镇街 道,从一点到达另一点的距离正是在南北方向上旅行的距离加上在东西方向上旅行的距离因此曼哈顿距离又称为出租车距离,曼哈顿距离不是距离不变量,当 坐标轴变动时,点间的距离就会不同。 15、邻域功能——所谓邻域是指具有统一属性的实体区域或者焦点集中在整个地区的较小部分实体空间。邻域功能就是在特定的实体空间中发现其属性的一致 性。它包括直接邻域和扩展邻域。 16、缓冲区分析——是指根据数据库的点、线、面实体基础,自动建立其周围一定宽度范围内的缓冲区多边形实体,从而实现空间数据在水平方向得以扩展的 空间分析方法。缓冲区在某种程度上受控于目前存在的摩擦表面、地形、障碍物等,也就是说,尽管缓冲区建立在位置的基础上,但是还有其他实质性的成分。 确定缓冲区距离的四种基本方法:随机缓冲区、成因缓冲区、可测量缓冲区、合法授权缓冲区。 17、统计表面——表面是含有 z 值的形貌,z 值又称为高度值,它的位置被一系列 x 和 y 坐标对定义且在区域范围内分布。z 值也常被认为是高程值,但是不必 局限于这一种度量。实际上,在可定义的区域内出现的任意可测量的数值(例如,序数、间隔和比率数据)都可以认为组成了表面。一般使用的术语是统计表 面,因为在考虑的范围内 z 值构成了许多要素的统计学的表述(robinson et al., 1995)。 18、dem——数字高程模型(digital elevation model)。地形模型不仅包含高程属性,还包含其它的地表形态属性,如坡度、坡向等。dem 通常用地表规则网格单 元构成的高程矩阵表示,广义的 dem 还包括等高线、三角网等所有表达地面高程的数字表示。在地理信息系统中,dem 是建立数字地形模型(digital terrain model) 的基础数据,其它的地形要素可由 dem 直接或间接导出,称为“派生数据”,如坡度、坡向。 19、空间插值——空间插值常用于将离散点的测量数据转换为连续的数据曲面,以便与其它空间现象的分布模式进行比较,它包括了空间内插和外推两种算法。 空间内插算法:通过已知点的数据推求同一区域未知点数据。空间外推算法:通过已知区域的数据,推求其它区域数据。20、泰森多边形——通过数学方法定 义、平分点间的空间并以直线相连结,在点状物体间生成多边形的方法。 21、线密度——用所有区域内的线的总长度除以区域的面积。 22、连通性——连通性是衡量网络复杂性的量度,常用γ指数和α指数计算它。其中,γ指数等于给定空间网络体节点连线数与可能存在的所有连线数之比; α指数用于衡量环路,节点被交替路径连接的程度称为α指数,等于当前存在的环路数与可能存在的最大环路数之比。 23、图形叠加——将一个被选主题的图形所表示的专题信息放在另一个被选主题的图形所表示的专题信息之上。 24、栅格自动叠加——基于网格单元的多边形叠加是一个简单的过程,因为区域是由网格单元组成的不规则的块,它共享相同的一套数值和相关的标注。毫无 疑问,网格单元为基础的多边形叠加缺乏空间准确性,因为网格单元很大,但是类似于简单的点与多边形和线与多边形叠加的相同部分,由于它的简单性,因 此可以获得较高的灵活程度和处理速度。 25、拓扑矢量叠加——如何决定实体间功能上的关系,如定义由特殊线相连的左右多边形,定义线段间的关系去检查交通流量,或依据个别实体或相关属性搜 索已选择实体。它也为叠加多个多边形图层建立了一种方法,从而确保连结着每个实体的属性能够被考虑,并且因此使多个属性相结合的合成多边形能够被支 持。这种拓扑结果称作最小公共地理单元(lcgu)。 26、矢量多边形叠加——点与多边形和线与多边形叠加使用的主要问题是,线并不总是出现在整个区域内。解决该问题的最强有力的办法是让软件测定每组线 的交叉点,这就是所谓的结点。进行矢量多边形的叠加,其任务是基本相同的,除了必须计算重叠交叉点外,还要定义与之相联系的多边形线的属性。 27、布尔叠加——一种以布尔代数为基础的叠加操作。 28、制图建模——用以指明应用命令组合来回答有关空间现象问题的处理。制图模型是针对原始数据也包括导出数据和中间地图数据进行一系列交互有序的地 图操作来模拟空间决策的处理。 29、地理模型的类型——类似统计同类的描述性模型和与推理统计技术相关的规则性模型。 30、常见模型——1、注重样式与处理的问题长时间以来用于解释类似农业活动与运输成本间的关系——独立状态模型。2、最初为预测工业位置点的空间分布 的样式而设计的 weber 模型,进行改进后可使参与者寻找最佳商业和服务位置——位置-分配模型。3、建立在吸引力与到潜在市场的距离呈反比这一基础上的经 济地理模型——重力模型。4、通过空间验证思想如今广泛用于生态群落,通过地理空间跟踪动植物运动——改进扩散模型。 31、专题地图——以表现某单一属性的位置或若干选定属性之间关系为主要目的的地图。专题图形设计的一般程序包括合适的符号和图形对象的选择、生成和 放置,以明确突出研究主题的重要属性和空间关系,同时还要考虑参考系统。gis 专题地图输出的规则:不但要有精美的图形,最重要的是去读图、分析地图和 理解地图。 32、元数据——关于数据的数据,对数据库内容的全面描述,其目的是促进数据集的高效利用和充分共享。使用元数据的理由:性能上,完整性、可扩展性、特 殊性、安全性;功能上,差错功能、浏览功能、程序生成。 33、聚合——将单个数据元素进行分类的大量数字处理过程。 34、克立金法——依靠地球自然表面随距离的变化概率而确定高程的一种精确内插方法。 35、四叉树——一种压缩数据结构,它把地理空间定量划分为可变大小的网格,每个网格具有相同性质的属性。 36、比较工具型地理信息系统和应用型地理信息系统的异同。 工具型地理信息系统:是一种通用型 gis,具有一般的功能和特点,向用户提供一个统一的操作平台。一般没有地理空间实体,而是由用户自己定义。具有很好 的二次开发功能。如:arcinfo、genamap、mapinfo、mapgis、geostar。 应用型地理信息系统:在较成熟的工具型 gis 软件基础上,根据用户的需求和应用目的而设计的用于解决一类或多类实际问题的地理信息系统,它具有地理空间 实体和解决特殊地理空间分布的模型。如 lis、cgis、ugis。 37、详细描述应用型地理信息系统的开发过程 1、 系统总体设计:需求和可行性分析、数据模型设计、数据库设计、方法设计 2、 系统软件设计:开发语言、用户界面、流程、交互 3、 程序代码编写:投影、数据库、输入、编辑 4、 系统的调试与运行:α调试、β调试 5、 系统的评价与维护:功能评价、费用评价、效益评价 38、空间信息系统:以多媒体技术为依托,以空间数据为基础,以虚拟现实为手段的集空间数据的输入、编辑、存储、分析和显示于一体的巨系统,体由若干 个子系统组成。 39、地理数据测量标准——命名(对数据命名,允许我们对把对象叫什么做出声明,但不允许对两个命名的对象进行直接比较)、序数(提供对空间对象进行逻 辑对比的结果,但这种对比仅限于所谈论问题的范围内)、间隔(可以对待测项逐个赋值,能够更为精确地估计对比物的不同点)、比率(用途最广的测量数据 标准,它是允许直接比较空间变量的惟一标准)。 40、根据样本进行推理的取样原则——未取样位置的数据可以从已取样位置的数据中推测出来;区域边界内的数据可以合并计算;一组空间单元中的数据能够 转换成具有不同空间配置的另外一组空间单元数据。常用的方法:内插法:当有数值边界或知道缺失部分两端数值;外推法:当缺失的数据一侧有数值,而另 一侧每一数值。 18. AE 开发中矢量图层叠加求交分析 AE 开发中矢量图层叠加求交分析: AE 开发中,矢量图层叠加分析需要用到的主要类为 BasicGeoprocessor,其主要接口为 IBasicGeoprocessor。IBasicGeoprocessor 接口提供了基本的空间数据处理 的方法和属性,其中包括叠加求交(Interset)和叠加求和(Union)。 下面提供叠加求交的开发实例: C#+AE9.1 叠加求交示例代码: 1 private void M_OverLayer_Click(object sender, System.EventArgs e) 2 { 3 try 4 { 5 //分析层 6 ILayer pLayer=this.axMapControl1.get_Layer(0); 7 IFeatureLayer pInputFeatLayer=pLayer as IFeatureLayer; 8 ITable pInputTable=pLayer as ITable; 9 IFeatureClass pInputFeatClass=pInputFeatLayer.FeatureClass; 10 11 //叠加表 12 pLayer=this.axMapControl1.get_Layer(1); 13 ITable pOverlayTable=pLayer as ITable; 14 15 //叠加分析表 16 IFeatureClassName pFeatClassName=new FeatureClassNameClass(); 17 pFeatClassName.FeatureType=esriFeatureType.esriFTSimple; 18 pFeatClassName.ShapeFieldName="shape"; 19 pFeatClassName.ShapeType=pInputFeatClass.ShapeType; 20 21 //工作空间名称 22 IWorkspaceName pNewWSName=new WorkspaceNameClass(); 23 pNewWSName.WorkspaceFactoryProgID = "esriDataSourcesFile.ShapefileWorkspaceFactory"; 24 pNewWSName.PathName = @"C:\temp"; 25 26 //数据集名称 27 IDatasetName pDatasetName=pFeatClassName as IDatasetName; 28 pDatasetName.Name="ss"; 29 pDatasetName.WorkspaceName=pNewWSName; 30 31 //几何处理 32 IBasicGeoprocessor pBGP=new BasicGeoprocessorClass(); 33 IFeatureClass pOutputFeatClass=pBGP.Intersect(pInputTable,false,pOverlayTable,false,0.01,pFeatClassName); 34 35 //输出要素层设置 36 IFeatureLayer pOutputFeatLayer=new FeatureLayerClass(); 37 pOutputFeatLayer.FeatureClass=pOutputFeatClass; 38 pOutputFeatLayer.Name=pOutputFeatClass.AliasName; 39 40 this.axMapControl1.AddLayer((ILayer)pOutputFeatClass,0); 41 axMapControl1.Update(); 42 } 43 catch(Exception ex) 44 { 45 MessageBox.Show(ex.Message); 46 } 47 } 最近在研究 ae 中实现 overlay 的方法,终于发现了 2 个方法。(针对 shapefile) 方法一:利用 ITopology 接口: void COverlayDlg::Overlay(ILayerPtr inputLayer, ILayerPtr OverlayLayer,IFeatureClassPtr ipNewClass) { int mode=m_modeCombo.GetCurSel();IFeatureLayerPtr ipPutlayer(inputLayer); IFeatureClassPtr ipPutClass; ipPutlayer->get_FeatureClass(&ipPutClass); IFeatureClassPtr ipOutClass; IFeatureLayerPtr ipOverlayer(OverlayLayer); ipOverlayer->get_FeatureClass(&ipOutClass); IQueryFilterPtr ipQF(CLSID_QueryFilter); long number1,number2; ipPutClass->FeatureCount(ipQF,&number1); ipPutClass->FeatureCount(ipQF,&number2); IActiveViewPtr ipView=p_View->m_ctrlMap.GetActiveView();ITopologicalOperatorPtr ipTo; IFeaturePtr ipFeature1,ipFeature2; IGeometryPtr ipGeo1,ipGeo2,ipNew; for(long i=0;iGetFeature(i,&ipFeature1); ipOutClass->GetFeature(j,&ipFeature2); ipFeature1->get_Shape(&ipGeo1); ipFeature2->get_Shape(&ipGeo2); ipTo=ipGeo1; switch(mode) { case 0: ipTo->Intersect(ipGeo2,esriGeometry2Dimension,&ipNew); break; case 1: ipTo->Union(ipGeo2,&ipNew); break; case 2: ipTo->Difference(ipGeo2,&ipNew); } IFeaturePtr ipFeature; ipNewClass->CreateFeature(&ipFeature); ipFeature->putref_Shape(ipNew); ipFeature->Store(); }ipView->Refresh(); } 这种方法是一个一个 feature 的创建,存入 featureclass 接口中。 方法二:利用 IBasicGeoprocess 接口 //把第一个图层和第 0 个图层叠置 IFeatureLayerPtr ipFeaLay; IFeatureClassPtr ipFeaCls; HRESULT hr; ILayerPtr ipLay; IMapPtr ipMap(m_ctrlMap.GetMap()); hr=ipMap->get_Layer(0,&ipLay); ipFeaLay=ipLay; if(ipFeaLay) { hr=ipFeaLay->get_FeatureClass(&ipFeaCls); if (FAILED(hr)) return; } ITablePtr ipInPutTable(ipLay);hr=ipMap->get_Layer(1,&ipLay); ipFeaLay=ipLay; if(ipFeaLay!=0) hr=ipFeaLay->get_FeatureClass(&ipFeaCls); ITablePtr ipOverlayTable(ipLay); hr=ipDatasetName->putref_WorkspaceName(ipWSName); if(FAILED(hr)) return; IBasicGeoprocessorPtr ipBGP(CLSID_BasicGeoprocessor); IFeatureClassPtr ipOutputFeaCls;hr=ipBGP->Intersect(ipInPutTable,VARIANT_FALSE,ipOverlayTable,VARIANT_FALSE,double(0),ipFeaClsName,&ipOutputFeaCls); IFeatureLayerPtr ipOutputFeaLay(CLSID_FeatureLayer); ipOutputFeaLay->putref_FeatureClass(ipOutputFeaCls); BSTR OutFeaClsAliName; hr=ipOutputFeaCls->get_AliasName(&OutFeaClsAliName); if(FAILED(hr)) return; hr=ipOutputFeaLay->put_Name(OutFeaClsAliName); if(FAILED(hr)) return; hr=ipMap->AddLayer(ipOutputFeaLay); if(FAILED(hr)) return;IActiveViewPtr ipAV(ipMap); ipA V->Refresh(); 19. 矢量数据分析 地图叠加:将两幅数字化地图的几何形状和属性结合在一起,生成输出地图的一种属性数据。 点与多边形叠加:一种 GIS 操作,点状地图上的每个点被赋予点所落入的多边形内的属性数据。 线与多边形叠加:一种 GIS 操作,现状地图被叠加地图上的多边形边界所分割,输出地图上每个弧段结合了来自线状地图和所落入多边形的属性。 多边形与多边形叠加:一种 GIS 操作,其输出地图结合了来自输入地图和叠加地图的多边形边界,生成一套新的多边形,每个新的多边形携带了两幅地图的属 性。 缓冲:一种 GIS 操作,将落在所选地图要素指定距离之内的区域与之外的区域分开。 相交(Intersect):一种地图叠加方法,仅保留那些落在输入地图和叠加地图共同范围的要素。 联合(Union):保留输入地图和叠加地图全部要素的一种多边形与多边形叠加方法。 层叠置(Identity):一种地图叠加方法,仅保留那些落在由输入地图定义范围内的要素。 模糊容差:用于 GIS 软件的距离容差,落在这一指定距离内的点和线被强制捕捉到一起。 破碎多边形:在地图叠加中沿着两个输入地图的共同边界出现的极小多边形。破碎多边形往往来自数字化误差。 误差传递:由于输入地图的误差造成地图叠加输出中误差的产生。 最小制图单元:由政府机构或组织所指定的最小面积单元。 20. GIS 空间信息基本分析方法 www.TeleCarto.com 2001-6-29 远图开发室 地理信息系统(GIS)具有很强的空间信息分析功能,这是区别于计算机地图制图系统的显著特征之一。利用空间信息分析技术,通过对原始数据模型的观察和实 验,用户可以获得新的经验和知识,并以此作为空间行为的决策依据。 空间信息分析的内涵极为丰富。作为 GIS 的核心部分之一,空间信息分析在地理数据的应用中发挥着举足轻重的作用。 叠置分析(Overlay Analysis) 覆盖叠置分析是将两层或多层地图要素进行叠加产生一个新要素层的操作,其结果将原来要素分割生成新的要素,新要素综合了原来两层或多层要素所具有的 属性。也就是说,覆盖叠置分析不仅生成了新的空间关系,还将输入数据层的属性联系起来产生了新的属性关系。覆盖叠置分析是对新要素的属性按一定的数 学模型进行计算分析,进而产生用户需要的结果或回答用户提出的问题。 1)多边形叠置 这个过程是将两层中的多边形要素叠加,产生输出层中的新多边形要素,同时它们的属性也将联系起来,以满足建立分析模型的需要。一般 GIS 软件都提供了 三种多边形叠置: (1)多边形之和(UNION):输出保留了两个输入的所有多边形。 (2)多边形之积(INTERSECT):输出保留了两个输入的共同覆盖区域。 (3)多边形叠合(IDENTITY):以一个输入的边界为准,而将另一个多边形与之相匹配,输出内容是第一个多边形区域内二个输入层所有多边形。 多边形叠置是个非常有用的分析功能,例如,人口普查区和校区图叠加,结果表示了每一学校及其对应的普查区,由此就可以查到作为校区新属性的重叠普查 区的人口数。 2)点与多边形叠加 点与多边形叠加,实质是计算包含关系。叠加的结果是为每点产生一个新的属性。例如,井位与规划区叠加,可找到包含每个井的区域。 3)线与多边形叠加 将多边形要素层叠加到一个弧段层上,以确定每条弧段(全部或部分)落在哪个多边形内。 网络分析(Network Analysis) 对地理网络(如交通网络)、城市基础设施网络(如各种网线、电力线、电话线、供排水管线等)进行地理分析和模型化,是地理信息系统中网络分析功能的主要目的。 网络分析是运筹学模型中的一个基本模型,它的根本目的是研究、筹划一项网络工程如何按排,并使其运行效果最好,如一定资源的最佳分配,从一地到另一地 的运输费用最低等。其基本思想则在于人类活动总是趋向于按一定目标选择达到最佳效果的空间位置。这类问题在生产、社会、经济活动中不胜枚举,因此研 究此类问题具有重大意义。 网络中的基本组成部分和属性如下: (1)链(Links),网络中流动的管线,如街道,河流,水管等,其状态属性包括阻力(Impedence)和需求(Demand)。 (2)障碍(Barriers),禁止网络中链上流动的点。 (3)拐角点(Turns),出现在网络链中所有的分割结点上,状态属性有阻力,如拐弯的时间和限制(如不允许左拐)。 (4)中心(Centers),是接受或分配资源的位置,如水库、商业中心、电站等,其状态属性包括资源容量,如总的资源量;阻力限额,如中心与链之间的最大距离或时间 限制。 (5)站点(Stops),在路径选择中资源增减的站点,如库房、汽车站等,其状态属性有要被运输的资源需求,如产品数。 网络中的状态属性有阻力和需求两项,实际的状态属性可通过空间属性和状态属性的转换,根据实际情况赋到网络属性表中。 1)路径分析 (1)静态求最佳路径:由用户确定权值关系后,即给定每条弧段的属性,当需求最佳路径时,读出路径的相关属性,求最佳路径。 (2)动态分段技术:给定一条路径由多段联系组成,要求标注出这条路上的公里点或要求定位某一公路上的某一点,标注出某条路上从某一公里数到另一公里数的 路段。 (3)N 条最佳路径分析:确定起点、终点,求代价较小的 N 条路径,因为在实践中往往仅求出最佳路径并不能满足要求,可能因为某种因素不走最佳路径,而走 近似最佳路径。 (4)最短路径:确定起点、终点和所要经过的中间点、中间连线,求最短路径。 (5)动态最佳路径分析:实际网络分析中权值是随着权值关系式变化的,而且可能会临时出现一些障碍点,所以往往需要动态地计算最佳路径。 2)地址匹配 地址匹配实质是对地理位置的查询,它涉及到地址的编码(Geocode)。地址匹配与其它网络分析功能结合起来,可以满足实际工作中非常复杂的分析要求。所需 输入的数据,包括地址表和含地址范围的街道网络及待查询地址的属性值。 3)资源分配 资源分配网络模型由中心点(分配中心)及其状态属性和网络组成。分配有两种方式,一种是由分配中心向四周输出,另一种是由四周向中心集中。这种分配功能 可以解决资源的有效流动和合理分配。其在地理网络中的应用与区位论中的中心地理论类似。在资源分配模型中,研究区可以是机能区,根据网络流的阻力等 来研究中心的吸引区,为网络中的每一连接寻找最近的中心,以实现最佳的服务。还可以用来指定可能的区域。 资源分配模型可用来计算中心地的等时区,等交通距离区,等费用距离区等。可用来进行城镇中心,商业中心或港口等地的吸引范围分析,以用来寻找区域中 最近的商业中心,进行各种区划和港口腹地的模拟等。 缓冲区分析(Buffer Analysis) 缓冲区分析是针对点、线、面实体,自动建立其周围一定宽度范围以内的缓冲区多边形。缓冲区的产生有三种情况:一是基于点要素的缓冲区,通常以点为圆 心、以一定距离为半径的圆;二是基于线要素的缓冲区,通常是以线为中心轴线,距中心轴线一定距离的平行条带多边形;三是基于面要素多边形边界的缓冲 区,向外或向内扩展一定距离以生成新的多边形。 缓冲区分析是地理信息系统重要的空间分析功能之一,它在交通、林业、资源管理、城市规划中有着广泛的应用。例如:湖泊和河流周围的保护区的定界,汽车 服务区的选择,民宅区远离街道网络的缓冲区的建立等。 空间统计分析(Spacial Analysis) 1)常规统计分析 常规统计分析主要完成对数据集合的均值、总和、方差、频数、峰度系数等参数的统计分析。 2)空间自相关分析 空间自相关分析是认识空间分布特征、选择适宜的空间尺度来完成空间分析的最常用的方法。目前,普遍使用空间自相关系数—— MoranI 指数,其计算公式如下: 其中:N 表示空间实体数目;xi 表示空间实体的属性值;x 是 xi 的平均值;Wij=1 表示空间实体 i 与 j 相邻,Wij=0 表示空间实体 i 与 j 不相邻 I 的值介于 1 与 I 之间, I=1 表示空间自正相关,空间实体呈聚合分布;I=1 表示空间自负相关,空间实体呈离散分布;I=0 则表示空间实体是随机分布的。Wij 表示实体 i 与 j 的空间关 系,它通过拓扑关系获得。 3)回归分析 回归分析用于分析两组或多组变量之间的相关关系,常见回归分析方程有:线性回归、指数回归、对数回归、多元回归等。 4)趋势分析 通过数学模型模拟地理特征的空间分布与时间过程,把地理要素时空分布的实测数据点之间的不足部分内插或预测出来。 5)专家打分模型 专家打分模型将相关的影响因素按其相对重要性排队,给出各因素所占的权重值;对每一要素内部进行进一步分析,按其内部的分类进行排队,按各类对结果 的影响给分,从而得到该要素内各类别对结果的影响量,最后系统进行复合,得出排序结果,以表示对结果影响的优劣程度,作为决策的依据。 专家打分模型可分二步实现。第一步——打分:用户首先在每个 feature 的属性表里增加一个数据项,填入专家赋给的相应的分值;第二步——复合:调用加权 符合程序,根据用户对各个 feature 给定的权重值进行叠加,得到最后的结果。 21. 如何判断图形间的逻辑运算 本小节以 Polyline(Polygon 类似)为例, 讲解如何判断图形间的逻辑关系,主要用到的接口是 IRelationalOperator。 在本例中,使用 Relational Operator 对两个图形进行比较,返回一个布尔值来指出这两个图形间是否存在特定的关系。一些关系的判断是要求两个图形要有相同 的维数的(如必须 Polyline 之间或 Polygon 之间),而另外一些对图形维数就没有太多限制。大多数已定义的关系操作符是互斥的。RelationalOperator 的具体方 法有: Contains:判断一个图形是否包含另外一个图形。 Within:判断一个图形是否被另外一个图形所包含。 Crosses:判断两个图形是否在维数较少的那个图形的内部相交。 Disjoint:判断两个图形间是否没有相同点。 Equals:判断两个图形是否是同一个类型并且在平面上的点是否是相同的位置。如果返回值为真,则它们应该包含(Contains)另外一个图形同时也被另外一个 图形所包含(Within)。 Overlaps:判断两个图形的交集是否和其中的一个图形拥有相同的维数,并且他们交集不能和其中任何一个图形相等。该方法只使用与两个 Polyline 之间或者两 个 Polygon 之间。 Touch:判断两个图形的边界是否相交,如果两个图形的交集不为空,但两个图形内部的交集为空,则返回值为真。 下图为几个图形的边界(Boundary)和内部(Interior)概念的图解: 下面针对较易混淆的两个概念,Crosses 和 Touch 进行举例说明(Polyline/Polyline): Crossess Touch Crossess Touch 22. AE 中 2 种方式 overlay 最近在研究 ae 中实现 overlay 的方法,终于发现了 2 个方法。(针对 shapefile) 方法一:利用 ITopology 接口: void COverlayDlg::Overlay(ILayerPtr inputLayer, ILayerPtr OverlayLayer,IFeatureClassPtr ipNewClass) { int mode=m_modeCombo.GetCurSel(); IFeatureLayerPtr ipPutlayer(inputLayer); IFeatureClassPtr ipPutClass; ipPutlayer->get_FeatureClass(&ipPutClass); IFeatureClassPtr ipOutClass; IFeatureLayerPtr ipOverlayer(OverlayLayer); ipOverlayer->get_FeatureClass(&ipOutClass); IQueryFilterPtr ipQF(CLSID_QueryFilter); long number1,number2; ipPutClass->FeatureCount(ipQF,&number1); ipPutClass->FeatureCount(ipQF,&number2); IActiveViewPtr ipView=p_View->m_ctrlMap.GetActiveView(); ITopologicalOperatorPtr ipTo; IFeaturePtr ipFeature1,ipFeature2; IGeometryPtr ipGeo1,ipGeo2,ipNew; for(long i=0;iGetFeature(i,&ipFeature1); ipOutClass->GetFeature(j,&ipFeature2); ipFeature1->get_Shape(&ipGeo1); ipFeature2->get_Shape(&ipGeo2); ipTo=ipGeo1; switch(mode) { case 0: ipTo->Intersect(ipGeo2,esriGeometry2Dimension,&ipNew); break; case 1: ipTo->Union(ipGeo2,&ipNew); break; case 2: ipTo->Difference(ipGeo2,&ipNew); } IFeaturePtr ipFeature; ipNewClass->CreateFeature(&ipFeature); ipFeature->putref_Shape(ipNew); ipFeature->Store(); } ipView->Refresh(); } 这种方法是一个一个 feature 的创建,存入 featureclass 接口中。 方法二:利用 IBasicGeoprocess 接口 //把第一个图层和第 0 个图层叠置 IFeatureLayerPtr ipFeaLay; IFeatureClassPtr ipFeaCls; HRESULT hr ; ILayerPtr ipLay; IMapPtr ipMap(m_ctrlMap.GetMap()); hr=ipMap->get_Layer(0,&ipLay); ipFeaLay=ipLay; if(ipFeaLay) { hr=ipFeaLay->get_FeatureClass(&ipFeaCls); if (FAILED(hr)) return; } ITablePtr ipInPutTable(ipLay); hr=ipMap->get_Layer(1,&ipLay); ipFeaLay=ipLay; if(ipFeaLay!=0) hr=ipFeaLay->get_FeatureClass(&ipFeaCls); ITablePtr ipOverlayTable(ipLay); hr=ipDatasetName->putref_WorkspaceName(ipWSName); if(FAILED(hr)) return; IBasicGeoprocessorPtr ipBGP(CLSID_BasicGeoprocessor); IFeatureClassPtr ipOutputFeaCls; hr=ipBGP->Intersect(ipInPutTable,VARIANT_FALSE,ipOverlayTable,VARIANT_FALSE,double(0),ipFeaClsName,&ipOutputFeaCls); IFeatureLayerPtr ipOutputFeaLay(CLSID_FeatureLayer); ipOutputFeaLay->putref_FeatureClass(ipOutputFeaCls); BSTR OutFeaClsAliName; hr=ipOutputFeaCls->get_AliasName(&OutFeaClsAliName); if(FAILED(hr)) return; hr=ipOutputFeaLay->put_Name(OutFeaClsAliName); if(FAILED(hr)) return; hr=ipMap->AddLayer(ipOutputFeaLay); if(FAILED(hr)) return; IActiveViewPtr ipAV(ipMap); ipA V->Refresh(); 23. ArcEngine 中实现捕捉功能 捕捉功能主要使用 ArcEngine 中的两个接口 1. IHitTest 用于作点击测试 2. IFeatureCache 用于建立做缓存 由于数据库中有多个 FeatureClass ,而每个 FeatureClass 又可以做多种点击测试 所以这里有会有好几种捕捉方案。 我们称呼每一个可以执行捕捉的对象叫捕捉代理,所有的代理在一个捕捉环境中 方案 1:每个代理负责测试一种 FeatureClass 的一种点击方式 方案 2:每个代理负责测试一种 FeatureClass 的所有点击方式 方案 3:一代理负责测试所有的 FeatureClass 的一种点击方式 方案 4:一个代理负责测试所有 FeatureClass 的所有点击方式 在实际使用过程中 我们使用的是第一种方案。但是我个人认为第二种方案比较好。当然这只是个人推测 没有测试数据证明。 下面给出第一种方案的代码: /// /// IFeatureSnapAgent 的摘要说明。 /// public interface IFeatureSnapAgent:ISnapAgent,ISnapAgentFeedback { IFeatureCache FeatureCache { get; } IFeatureClass FeatureClass { get; set; } esriGeometryHitPartType HitPartType { get; set; } /// /// 为捕捉连接事件,当捕捉发生的时候,就会触发事件。 /// /// void AddSnapedEventHandler(GeometrySnapedEventHandler handler); /// /// 不再监听捕捉事件 /// /// void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler); } /// /// 默认的要素捕捉代理 /// public class DefaultFeatureSnapAgent :IFeatureSnapAgent,IEditEvents,ESRI.ArcGIS .esriSystem .IPersistVariant { #region 构造函数 /// /// 为代理指定别名。注意该代理目前还没有关联到任何目标 FeatureClass /// 要使得该代理起作用,必须要为他设置 FeatureClass. /// /// 名称(请确保唯一) public DefaultFeatureSnapAgent(string name):this(name,null) { } /// /// 将使用该 FeatureClass 的别名做代理的名称 /// /// public DefaultFeatureSnapAgent(IFeatureClass feaClass):this(feaClass.AliasName,feaClass) { } /// /// 完全初始化捕捉代理 /// /// 名称(请确保唯一) /// 目标 FeatureClass public DefaultFeatureSnapAgent(string name,IFeatureClass feaClass) { m_snapAgentName=name; m_bCacheHasCreated=false; m_hitPartType=esriGeometryHitPartType.esriGeometryPartNone; this.m_isSnapWorking=true; this.m_featureClass=feaClass; this.m_snapFeedbackText=""; } #endregion #region IFeatureSnapAgent 成员 private event GeometrySnapedEventHandler m_snapSubsciber; /// /// FeatureClass 缓冲区。 /// private IFeatureCache m_featureCache; /// /// 该代理将捕捉在该 FeatureClass 上的 Feature.和 Geometry /// private IFeatureClass m_featureClass; /// /// 点击测试的有效类型。 /// protected esriGeometryHitPartType m_hitPartType; /// /// 缓冲区对象是否已经被创建了。跟是否建立了缓冲没有关系。 /// private bool m_bCacheHasCreated; /// /// 缓冲区对象 /// public IFeatureCache FeatureCache { get { return m_featureCache; } } /// /// 目标 FeatureClass。SnapAgent 将针对该 FeatureClass 做捕捉 /// public IFeatureClass FeatureClass { get { return m_featureClass; } set { m_featureClass=value; } } /// /// 点击测试类型。哪些点击类型会被测试 /// public ESRI.ArcGIS.Geometry.esriGeometryHitPartType HitPartType { get { // TODO: 添加 DefaultFeatureSnapAgent.HitPartType getter 实现 return m_hitPartType; } set { m_hitPartType=value; } } /// /// 创建缓冲区对象。 /// private void CreateFeatureCache() { m_featureCache=new ESRI.ArcGIS.Carto.FeatureCacheClass(); m_bCacheHasCreated=true; } /// /// 填充缓冲区。如果还没有创建缓冲区对象,就先创建缓冲区对象。 /// 如果已经拥有缓冲区,而且当前点依然在该缓冲区内部,那么不会填充生成新的缓冲。 /// 由于缓冲是在捕捉方法内部被使用的。所以可以保证 m_featureClass 必然不会为空引用。 /// /// 当前点 /// 缓冲区大小 private void FillCache(IPoint point,double size) { if(!m_bCacheHasCreated) { CreateFeatureCache(); } if(!m_featureCache.Contains (point)) { m_featureCache.Initialize(point,size); m_featureCache.AddFeatures(this.m_featureClass); } } /// /// 添加事件侦听者。捕捉发生后,事件将会被发送到该侦听者。 /// /// public void AddSnapedEventHandler(GeometrySnapedEventHandler handler) { m_snapSubsciber+=handler; } /// /// 移去事件侦听者。 /// /// public void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler) { m_snapSubsciber-=handler; } #endregion #region ISnapAgent 成员 private string m_snapAgentName; /// /// SnapAgent 是否在工作。代表用户是打开还是关闭了 SnapAgent /// 初始化的时候默认是打开的。 /// private bool m_isSnapWorking; public string Name { get { return m_snapAgentName; } } public bool IsWorking() { return this.m_isSnapWorking ; } /// /// 捕捉。 /// /// /// /// /// public virtual bool Snap(IGeometry metry, IPoint snapPoint, double tolerance) { /* * 捕捉的过程: * 首先使用当前位置、目标图层、和误差的 10 倍构造一个缓冲区。 * 对缓冲区中的每个 Feature,找到他包含的每一个 Geometry。 * 对 Geometry 做点击测试。 */ if(!this.m_isSnapWorking) { //捕捉代理已经被用户关闭了。不会有任何捕捉动作发生 return false; } if(m_featureClass==null) { //没有目标图层。不能做捕捉动作。此时应该报错 //但是目前只是返回 false。 return false; } FillCache(snapPoint,tolerance*10); //当前被测试的 Feature IFeature feature=null; //当前被测试的几何图形 IGeometry curMetry=null; //当前被测试的 Feature 的索引和缓冲区中拥有的 feature 的个数。 int featureIndex,featureCount; featureCount=m_featureCache.Count; for(featureIndex=0;featureIndex /// 打开捕捉代理 /// public void TurnOn() { this.m_isSnapWorking=true; } /// /// 关闭捕捉代理 /// public void TurnOff() { this.m_isSnapWorking =false; } private void LaunchSnapEvent(SnapEventArgs args) { if(this.m_snapSubsciber!=null&&args!=null) { this.m_snapSubsciber(this,args); } } #endregion #region Object 成员 /// /// 名字是一个 agent 的唯一标志。 /// /// /// public override bool Equals(object obj) { if(! (obj is DefaultFeatureSnapAgent)) { return false; } DefaultFeatureSnapAgent agent=(DefaultFeatureSnapAgent)obj; return this.m_snapAgentName.Equals(agent.m_snapAgentName); } public override int GetHashCode() { return this.m_snapAgentName.GetHashCode(); } #endregion #region IEditEvents 成员 public void AfterDrawSketch(IObject obj) { // TODO: 添加 DefaultFeatureSnapAgent.AfterDrawSketch 实现 } public void OnChangeFeature(IObject obj) { // TODO: 添加 DefaultFeatureSnapAgent.OnChangeFeature 实现 } public void OnConflictsDetected() { // TODO: 添加 DefaultFeatureSnapAgent.OnConflictsDetected 实现 } public void OnCreateFeature(IObject obj) { // TODO: 添加 DefaultFeatureSnapAgent.OnCreateFeature 实现 } public void OnCurrentLayerChanged() { // TODO: 添加 DefaultFeatureSnapAgent.OnCurrentLayerChanged 实现 } public void OnCurrentTaskChanged() { // TODO: 添加 DefaultFeatureSnapAgent.OnCurrentTaskChanged 实现 } public void OnDeleteFeature(IObject obj) { // TODO: 添加 DefaultFeatureSnapAgent.OnDeleteFeature 实现 } public void OnRedo() { // TODO: 添加 DefaultFeatureSnapAgent.OnRedo 实现 } public void OnSelectionChanged() { // TODO: 添加 DefaultFeatureSnapAgent.OnSelectionChanged 实现 } public void OnSketchFinished() { // TODO: 添加 DefaultFeatureSnapAgent.OnSketchFinished 实现 } public void OnSketchModified() { // TODO: 添加 DefaultFeatureSnapAgent.OnSketchModified 实现 } public void OnStartEditing() { // TODO: 添加 DefaultFeatureSnapAgent.OnStartEditing 实现 } public void OnStopEditing(Boolean save) { // TODO: 添加 DefaultFeatureSnapAgent.OnStopEditing 实现 } public void OnUndo() { // TODO: 添加 DefaultFeatureSnapAgent.OnUndo 实现 } #endregion #region ISnapFeedback 成员 private string m_snapFeedbackText; public string SnapText { get { return this.m_snapFeedbackText; } } private void SetFeedback(string feedback) { this.m_snapFeedbackText=feedback; } #endregion #region IPersistVariant 成员 public ESRI.ArcGIS .esriSystem .UID ID { get { ESRI.ArcGIS .esriSystem .UID uid=new ESRI.ArcGIS .esriSystem .UIDClass (); uid.Value ="ls.gis.Editor.DefaultFeatureSnapAgent"+this.m_snapAgentName; return uid; } } public void Load(ESRI.ArcGIS .esriSystem .IVariantStream vs) { this.m_snapAgentName =(string)vs.Read (); this.m_isSnapWorking =(bool)vs.Read (); string hitPartStr=(string)vs.Read (); this.m_hitPartType =(esriGeometryHitPartType)Enum.Parse (this.m_hitPartType .GetType (),hitPartStr,false); bool hasFeatureClass=(bool)vs.Read (); if(hasFeatureClass) { ESRI.ArcGIS .esriSystem .IName name=(ESRI.ArcGIS .esriSystem .IName)vs.Read (); this.m_featureClass =(IFeatureClass)name.Open (); } } public void Save(ESRI.ArcGIS .esriSystem .IVariantStream vs) { vs.Write (this.m_snapAgentName); vs.Write (this.m_isSnapWorking ); vs.Write (this.m_hitPartType.ToString ()); if(this.m_featureClass !=null) { vs.Write (true); IDataset dataset=(IDataset)this.m_featureClass ; vs.Write (dataset.FullName ); } else { vs.Write (false); } } #endregion } public class DefaultSnapAgentEnvironment:ISnapAgentEnvironment { private double m_tolerance; private SnapToleranceUnit m_snapToleranceUnit; private ArrayList m_snapAgentArray; /// /// 用于转换误差单位 /// private IActiveView m_activeView; /// /// 如果误差单位为地图单位,那么可以调用这个构造函数。 /// 如果误差单位为象素。那么应该调用有参数的构造方法。 /// 如果在调用时不能确定参数 activeView,那么也可以先调用该方法构造对象。 /// 然后用属性 ActiveView 来设置该参数的值。 /// public DefaultSnapAgentEnvironment():this(null) { } public DefaultSnapAgentEnvironment(IActiveView activeView) { m_snapAgentArray=new ArrayList (); m_tolerance=7; m_snapToleranceUnit=SnapToleranceUnit.UnitPixels; this.m_activeView=activeView; } /// /// 用于转换误差的单位。如果没有设置,或者设置为 null, /// 那么误差的单位将不会被转换,而直接被认为是地图单位。 /// public IActiveView ActivView { set { this.m_activeView=value; } get { return this.m_activeView; } } #region ISnapAgentEnvironment 成员 public void AddSnapAgent(ISnapAgent agent) { if(agent==null) { return; } if(this.m_snapAgentArray.Contains(agent)) { return; } this.m_snapAgentArray.Add(agent); } public void ClearSnapAgent() { this.m_snapAgentArray.Clear(); } /// /// 如果索引越界,那么返回 null,而不会抛出异常。 /// /// /// public ISnapAgent GetSnapAgent(int index) { if(index=0) { return (ISnapAgent)this.m_snapAgentArray[index]; } else { return null; } } /// /// 如果不存在,回返回 null /// /// /// ISnapAgent ls.gis.Editor.ISnapAgentEnvironment.GetSnapAgent(string name) { ISnapAgent retAgent=null; int retAgentIndex=-1; for(int index=0; index /// /// /// public void RemoveSnapAgent(int index) { if(index<0||index>=this.m_snapAgentArray.Count) { return ; } this.m_snapAgentArray.RemoveAt(index); } public bool SnapPoint(IPoint point) { for(int index=0;index { void SomeMethod(T t) { object temp = t; SomeClass obj = (SomeClass)temp; } } // 正确: class MyClass where T : SomeClass { void SomeMethod(T t) { SomeClass obj = t; } } 64. 在一般情况下不要定影有限制符的接口。接口的限制级别通常可以用强类型来替换之。 public class Customer {…} //避免: public interface IList where T : Customer {…} //正确: public interface ICustomerList : IList {…} 65. 不确定在接口内的具体方法的限制条件。 66. 总是选择使用 C#内置(一般的 generics)的数据结构。 26. 基于 AE 删除选择的要素- - ' //Deletes all features selected on the current layer Public Sub DeleteAllSelectedFeatures(ByVal pFeatureCursor As IFeatureCursor, ByVal GeometryTypeStr As String) Dim pWorkspaceEdit As IWorkspaceEdit Dim pFeature As IFeature ' If there are no features currently selected then nothing to do If pFeatureCursor Is Nothing Then Exit Sub Try Dim bResponse As DialogResult bResponse = MsgBox("您确定删除所有" & GeometryTypeStr & "要素吗?", MessageBoxButtons.YesNo) If bResponse = Windows.Forms.DialogResult.Yes Then ' Loop over the selected features deleting each in turn pWorkspaceEdit = pSdeWorkspace pWorkspaceEdit.StartEditing(True) pWorkspaceEdit.StartEditOperation() pFeature = pFeatureCursor.NextFeature While Not pFeature Is Nothing pFeature.Delete() pFeature = pFeatureCursor.NextFeature End While pWorkspaceEdit.StopEditOperation() pWorkspaceEdit.StopEditing(True) End If mainForm1.AxMapControl1.ActiveView.Refresh() Exit Sub Catch ex As Exception MsgBox(ex.ToString) End Try End Sub 27. 基于 AO/AE 获取要素信息 1、基于 AE 获取要素简单信息 Private Sub AxMapControl1_OnMouseDown(ByVal sender As Object, ByVal e As ESRI.ArcGIS.MapControl.IMapControlEvents2_OnMouseDownEvent) Handles AxMapControl1.OnMouseDown Me.AxMapControl1.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerIdentify Dim pMap As IMap Dim i As Integer Dim groupLayer As IGroupLayer groupLayer = New GroupLayer For i = 0 To Me.AxMapControl1.Map.LayerCount - 1 groupLayer.Add(Me.AxMapControl1.Map.Layer(i)) Next Dim pPoint As IPoint pMap = Me.AxMapControl1.Map pPoint = Me.AxMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y) Dim pIdentify As IIdentify Dim pIDArray As IArray Dim pFeatIdObj As IFeatureIdentifyObj Dim pIdObj As IIdentifyObj pIdentify = groupLayer Dim pEnv As IEnvelope pEnv = New Envelope pEnv = Me.AxMapControl1.ActiveView.Extent pEnv.Height = 100 pEnv.Width = 100 pEnv.CenterAt(pPoint) pIDArray = pIdentify.Identify(pEnv) If Not pIDArray Is Nothing Then pFeatIdObj = pIDArray.Element(0) pIdObj = pFeatIdObj pIdObj.Flash(Me.AxMapControl1.ActiveView.ScreenDisplay) '消息显示查询目标的信息 MsgBox("Layer:" & pIdObj.Layer.Name & vbNewLine & "Feature:" & pIdObj.Name) Else MsgBox("No feature identified.") End If Me.AxMapControl1.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault End Sub 2、基于 AO 获取要素详细信息 Private Sub AxMapControl1_OnMouseDown(ByVal sender As Object, ByVal e As ESRI.ArcGIS.MapControl.IMapControlEvents2_OnMouseDownEvent) Handles AxMapControl1.OnMouseDown Me.AxMapControl1.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerIdentify Dim pActiveView As IActiveView pActiveView = Me.AxMapControl1.ActiveView Dim pIdentifyDialog As IIdentifyDialog Dim pIdentifyDialogProps As IIdentifyDialogProps Dim pEnumLayer As IEnumLayer Dim pLayer As ILayer pIdentifyDialog = New IdentifyDialog pIdentifyDialogProps = pIdentifyDialog 'QI pIdentifyDialog.Map = Me.AxMapControl1.Map pIdentifyDialog.Display = pActiveView.ScreenDisplay '//Clear the dialog on each mouse click pIdentifyDialog.ClearLayers() '//Perform an identify on all of the layers the dialog '//says are searchable pEnumLayer = pIdentifyDialogProps.Layers pEnumLayer.Reset() pLayer = pEnumLayer.Next Do While Not pLayer Is Nothing pIdentifyDialog.AddLayerIdentifyPoint(pLayer, e.x, e.y) pLayer = pEnumLayer.Next Loop pIdentifyDialog.Show() Me.AxMapControl1.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault End Sub 28. ArcEngine 中拓扑的使用- - 拓扑(ITopology)的使用包括 1.建立拓扑 2.验证拓扑 3.编辑过程中保证拓扑的正确 4.查询系统中存在的拓扑 1.首先 来看看建立拓扑 Topology 实现了 ITopology 这个接口 但是给类是不能用来创建对象的。 必须要通过调用 ITopologyContainer::CreateTopology 这个方法来建立一个 Topology FeatureDataset 实现了 ITopologyContainer 这个接口。那么 这就是说拓扑只能在一个 FeatureDataset 的范围内建立。而不能独立存在于 Workspace 中。这样做的原因是需要保证 参与同一个拓扑的 FeatureClass 具有同一个投影坐标系统。 建立拓扑后需要将 ObjectClass 加入到拓扑中去。这样这个拓扑就可以用来验证这几个 ObjectClass 的对象之间的关系了。 验证关系就要有规则,规则是由 ITopologyRule 来表达的。ITopologyRule 必须要被 加入到一个 ITopologyRuleContainer 中去。而 Topology 实现了这个接口。 一个 ITopologyRule 用来表达两个 ObjectClass 的对象之间的某个关系。 具体代码参看接口就可以了。 2.验证拓扑 ITopology 有一个方法 ValidateTopology 用来验证指定区域内的拓扑。需要注意 没有版本 的拓扑可以在 任何时候验证。而有版本的拓扑必须在编辑回话中验证。 3.拓扑编辑 1.移动共用点 1.首先需要打开拓扑 建立拓扑图(ITopologyGraph) 代码如下: //topoLayer 是一个打开的拓扑图层 ITopologyGraph pTG=topoLayer.Topology.Cache; pTG.Build(pA.Extent,false); 2.然后 需要获得当前节点或者边 这个操作要使用拓扑图的点击测试 ITopologyElement topeEle pTG.HitTest(... ref topeEle); 这个方法在点击测试成功的时候返回 true.而且会通过 topeEle 这个 ref 参数将选中的元素(点或者边) 返回. 3.还有一种获取节点的方法 首先调用拓扑图的 Select 方法 选中点击测试的元素(pTG.Select) 然后可以查询拓扑图的选中节点集合 就可以找到该节点(pTG.NodeSelection) 4.为该元素使用一个 Feedback. //其中 pNode 就是当前节点 sr 是参考坐标系 可以使用 null //还有给 Feedback 设置 Display m_pNodeFeedback =pTG.GetSplitMoveNodeFeedback(pNode,false,sr); m_pNodeFeedback.Display= activeView.ScreenDisplay; 5.在鼠标移动的时候 调用 Feedback 的 MoveTo 方法。 if(m_pNodeFeedback!=null) { //activeView 是活动的试图 //首先要把将点坐标转换为地图中的坐标。 //然后调用 MoveTo 方法 IPoint pt=activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y); m_pNodeFeedback.MoveTo(pt); } 6.在鼠标释放的时候 //获取拓扑图 ITopologyGraph pTG=topoLayer.Topology.Cache; //转换坐标 IPoint pt=pA.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y); //获得正在做拓扑编辑的元素 ITopologyNode pTN=(ITopologyNode)m_pTopoElement; //实施拓扑编辑 pTG.SplitMoveNode(pTN,pt,false); //提交拓扑编辑结果 IEnvelope pE; pTG.Post(out pE); 4.查询系统中的拓扑 还是 ITopologyContainer 这个接口 这个接口有 FeatureDataset 这个唯一的实现。 CreateTopology 建立一个新的拓扑 DefaultClusterTolerance The default cluster tolerance as per the topology engine. MaximumClusterTolerance The maximal cluster tolerance as per the topology engine. MinimumClusterTolerance The minimal cluster tolerance as per the topology engine. Topology 通过索引打开拓扑. TopologyByID 通过 ID 打开拓扑. TopologyByName 通过名字打开拓扑 TopologyCount 拓扑的数目 29. ArcEngine 渲染的使用 1.Feature 的基本渲染方法 Feature 的常用的绘制方法包括: 1.简单绘制 2.唯一值绘制/多字段唯一值绘制 3.点密度/多字段点密度绘制 4.数据分级绘制 5.质量图(饼图/直方图) 6.按比例尺渲染 7.比例符号渲染 1.简单渲染 简单渲染是 ArcEngine 的默认渲染,我们打开一个 FeatureClass,建立一个 FeatureLayer 的时候, 如果没有给 FeatureLayer 设置 Renderer 那么使用的就是简单渲染。简单渲染对整个图层中的所有 Feature 使用同一种方式显示。 简单渲染在 ArcEngine 中用 ISimpleRenderer 来表示。 ISimpleRenderer 的使用方式如下: //假设 layer 是一个 IFeatureLayer,获取 IGeoFeatureLayer IGeoFeatureLayer geoLayer=layer as IGeoFeatureLayer; //构造 SimpleRenderer ISimpleRenderer renderer=new SimpleRendererClass(); renderer.description="简单的渲染一下"; renderer.Label="符号的标签"; //假设 sym 是一个和该图层中 Geometry 类型对应的符号; renderer.Symbol=sym; //为图层设置渲染,注意需要刷新该图层。 geoLayer.Renderer=renderer; 2.独立值/多字段独立值渲染 独立值/多字段独立值渲染,根据 Feature 的某一个字段的数据或某几个字段的组合结果来确定符号。 具有相同值或相同组合值的 Feature,使用一样的符号。在使用多个字段的使用,每个字段的取值之间 使用分割符来连接。字段的取值顺序和在 Renderer 中设置的一样。 基本使用方式如下: //假设 layer 是一个 IFeatureLayer,获取 IGeoFeatureLayer IGeoFeatureLayer geoLayer=layer as IGeoFeatureLayer; //构造一个 UniqueValueRenderer IUniqueValueRenderer renderer=new UniqueValueRendererClass(); //假设使用两个字段来渲染 renderer.FieldCount=2; //假设 YSLX 字段表示要素类型 //假设 YSYT 字段表示要数用途 renderer.set_Field(0,"YSLX"); renderer.set_Field(1,"YSYT"); //字段之间使用 | 来连接(默认取值) renderer.FieldDelimiter="|"; //设置默认符号 renderer.DefaultSymbol=defaultSymbol; renderer.DefaultLabel="默认 Label"; //添加值 renderer.addValue("房屋|民居","民居房屋",MJSymbol); renderer.addValue("房屋|商业用地","商业用地",SYSymbol); ... //还可以通过 set_Symbol,set_Heading、set_Value 来修改上述设置。 geoLayer.Renderer=renderer. 3.点密度/多字段点密度 点密度图通过在 Feature 的图形上打点来表示数据的数多,点越密集表示数据量越大。 还可以使用多字段的点密度图。这个使用同一个 Feature 上就可以显示几种不同的点。 注意点密度图有一个特殊的地方: 点密度图使用的符号是面状符号。而其中有需要包括点状符号。 接口使用如下: IDotDensityRenderer renderer=new DotDensityRendererClass (); IRendererFields flds=(IRendererFields)renderer; flds.AddField("MJ ","面积"); flds.AddField("RK","人口"); IDotDensityFillSymbol ddSym=new DotDensityFillSymbolClass(); ISymbolArray symArray=(ISymbolArray)ddSym; symArray.AddSymbol(mjSymbol); symArray.AddSymbol(rkSymbol); ddSym.Outline =(ILineSymbol)outlineSymbol ; ddSym.DotSize =10 ; ddSym.FixedPlacement=true; renderer.DotDensitySymbol =ddSym; renderer.DotValue=20 ; renderer.MaintainSize=this.m_dotdensityParam .MaintainSize ; IGeoFeatureLayer geoLayer=(IGeoFeatureLayer)layer ; geoLayer.Renderer =(IFeatureRenderer)renderer; 4.数据分级绘制(使用 IClassBreaksRenderer) 5.饼图/直方图(使用 IChartRenderer) 6.按比例尺渲染(使 IScaleDependentRenderer) 7.比例符号渲染(使用 IProportionalSymbolRenderer ) 2.图例的使用 图例的使用通过 ILegendInfo 接口。每个 Renderer 都实现了该接口,但是有时候该实现不好用, 所以也可以自己实现该接口。实现过程是比较简单的。 3.渲染层次 使用 ILevelRender 接口。该接口可以指定一 当前的 Level(-1)表示绘制全部。 然后 提供一个符号数组 ,注意每个符号要指定 Level .如果不指定就默认为 0。 4.透明度控制 透明度控制使用 ITransparencyRenderer 接口。该接口允许指定一个字段,字段取值用来表示透明度 注意 透明度的取值在 0--100 之间。 5.数据正规化 数据正规化用 IDataNormalization 接口来表示。该接口提供了几种正规化表示方法。 6.部分渲染 部分渲染通过使用 IDataExclusion 来实现。该接口允许提供过滤语句来过滤掉不需要渲染的 Feature。 同时也可以给他们制定特殊的符号。同时控制是否显示 7.旋转控制 旋转控制通过使用 IRotationRenderer 接口来表示。该接口要求提供旋转角度的字段。同时要求提供旋转的 方法。 8.数据样本 IDataSampling 没有使用过。 9.外表关联 ITable dispTable=((IDisplayTable)feaLayer).DisplayTable ;//图层 ITable attTable;//外表 IMemoryRelationshipClassFactory fac=new MemoryRelationshipClassFactoryClass (); IRelationshipClass relClass=fac.Open("JZMJ",(IObjectClass)dispTable,"ZDDJH", IObjectClass)attTable,"G03", "Forward","Backward", esriRelCardinality.esriRelCardinalityOneToOne); IDisplayRelationshipClass dispRelClass=feaLayer as IDisplayRelationshipClass ; dispRelClass.DisplayRelationshipClass(relClass,esriJoinType.esriLeftInnerJoin); 10.统计分析 ITableHistogram tableHistogram=new BasicTableHistogramClass (); tableHistogram.Table =((IDisplayTable)layer).DisplayTable ; tableHistogram.Field =fieldName ; object valueArray=null, freq=null; IBasicHistogram basicHistogram=(IBasicHistogram)tableHistogram; basicHistogram.GetHistogram(out valueArray,out freq); IClassify classify=null; int breakNum=6; //分类方法 switch(ClassifyMethod ) { case ClassifyMethodName.lsClassifyMethodEqualInterval: { EqualIntervalClass eq=new EqualIntervalClass (); eq.Classify (valueArray,freq,ref breakNum); classify=(IClassify)eq; break; } case ClassifyMethodName.lsClassifyMethodStandardDeviation: { StandardDeviationClass sd=new StandardDeviationClass (); IStatisticsResults stat= histogram as IStatisticsResults ; classify=sd as IClassify; classify.SetHistogramData (valueArray,freq); IDeviationInterval di=sd as IDeviationInterval ; di.DeviationInterval=1; di.Mean=stat.Mean; di.StandardDev=stat.StandardDeviation; classify.Classify (ref breakNum); break; } case ClassifyMethodName.lsClassifyMethodQuantile: { Quantile qc=new QuantileClass (); qc.Classify (valueArray,freq,ref breakNum); classify=qc as IClassify ; break; } case ClassifyMethodName.lsClassifyMethodNaturalBreaks: { NaturalBreaksClass nb=new NaturalBreaksClass (); nb.Classify (valueArray,freq,ref breakNum); classify=nb as IClassify ; break; } case ClassifyMethodName.lsClassifyMethodDefinedInterval: { DefinedIntervalClass di=new DefinedIntervalClass (); di.IntervalRange =this.m_classBreaksParam .Interval ; di.Classify (valueArray,freq,ref breakNum); classify=di as IClassify ; break; } default: { EqualIntervalClass eq=new EqualIntervalClass (); eq.Classify (valueArray,freq,ref breakNum); classify=(IClassify)eq; break; } } object o=classify.ClassBreaks ; System.Array breakArray= o as System.Array; 现在 breakArray 中就是统计后的数据了。 30. 利用 ArcEngin 进行空间分析的简单应用- - 一个简单的空间分析例子:vb 实现在地图上画一个矩形或者 圆后,计算出该区域内的要素的数目。 创建临时图层 在临时图层上用程序或者让用户手动的创建一个矩形或者圆形 然后使用空间过滤器,spatialfilter 指定一下它的参数,进行查找就行了。 具体的使用在帮助文档里有。 在地图上画矩形或者圆形可以通过 INewCircleFeedback 接口实现,画矩形同理,只需转换使用的接口就可以了,以下以画圆形为例(该代码是在 ArcMap 的 VBA 环境下,建立用户控件使用的): Private m_pDoc As IMxDocument Private m_pAV As IActiveView Private m_pScrD As IScreenDisplay Private m_pNewCircFeedback As INewCircleFeedback Private Function UIToolControl1_Enabled() As Boolean 'Set the ToolControl to enabled (disabled by default if any code is present in this event) UIToolControl1_Enabled = True 'Check that we have a reference to the ActiveView and ScreenDisplay If m_pScrD Is Nothing Then Set m_pDoc = Application.Document Set m_pAV = m_pDoc.ActiveView Set m_pScrD = m_pAV.ScreenDisplay End If End Function Private Sub UIToolControl1_MouseDown(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long) Dim pPnt As IPoint ' Get the current mouse location in Map Units Set pPnt = m_pScrD.DisplayTransformation.ToMapPoint(x, y) ' Check that user is not using an existing feedback If m_pNewCircFeedback Is Nothing Then ' Create a NewCircleFeedback object Set m_pNewCircFeedback = New NewCircleFeedback 'Set the Feedback's Display and StartPoint Set m_pNewCircFeedback.Display = m_pScrD m_pNewCircFeedback.Start pPnt End If End Sub Private Sub UIToolControl1_MouseMove(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long) ' Check if the user is currently using the feedback If Not m_pNewCircFeedback Is Nothing Then Dim pPnt As IPoint 'Move the Feedback to the current mouse location Set pPnt = m_pScrD.DisplayTransformation.ToMapPoint(x, y) m_pNewCircFeedback.MoveTo pPnt End If End Sub Private Sub UIToolControl1_MouseUp(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long) Dim pCircArc As IGeometry ' Check if the user is currently using the feedback If Not m_pNewCircFeedback Is Nothing Then 'Get the geometry (ICircularArc) returned from the feedback Set pCircArc = m_pNewCircFeedback.Stop ' If it is valid then create a CircleElement on the ActiveView using the 'AddCreateElement' procedure If Not pCircArc Is Nothing Then AddCreateElement pCircArc, m_pAV m_pAV.Refresh End If ' Set the feedback to nothing for the next use Set m_pNewCircFeedback = Nothing End If End Sub Private Sub AddCreateElement(pCircArc As ICircularArc, pAV As IActiveView) ' Takes an ICircularArc and IActiveView and creates a CircleElement in the ActiveView's BasicGraphicsLayer Dim pElemFillShp As IFillShapeElement Dim pElem As IElement Dim pGraCont As IGraphicsContainer Dim pSFSym As ISimpleFillSymbol Dim pRGB As IRgbColor Dim pSegColl As ISegmentCollection ' Create a new Polygon object and access the ISegmentCollection interface to add a segment Set pSegColl = New Polygon pSegColl.AddSegment pCircArc ' Create a new circleelement and use the IElement interface to set the its Geometry Set pElem = New CircleElement pElem.Geometry = pSegColl ' QI for the IFillShapeElement interface so that the Symbol property can be set Set pElemFillShp = pElem ' Create a new RGBColor Set pRGB = New RgbColor With pRGB .Red = 198 .Green = 255 .Blue = 214 End With ' Create a new SimpleFillSymbol and set its Color and Style Set pSFSym = New SimpleFillSymbol pSFSym.Color = pRGB pSFSym.Style = esriSFSSolid pElemFillShp.Symbol = pSFSym ' QI for the IGraphicsContainer interface from the IActiveView, allows access to the BasicGraphicsLayer Set pGraCont = pAV 'Add the element at Z order zero pGraCont.AddElement pElemFillShp, 0 End Sub 至于搜索,只需在取得 pCircArc 后利用 ISpatialFilter 即可实现,代码如下: Dim pFilter As IspatialFilter Set pFilter = New SpatialFilter With pFilter Set .Geometry = pCircArc .GeometryField = "SHAPE" .SpatialRel = esriSpatialRelIntersects End With dim featureCount as Integer featurecount=pFeatureClass.FeatureCount pFilter featurecount 即为要搜索的 pfeatureclass 中的实体个数 31. IfeatureSelection:SelectFeatures 方法介绍 已知一个要素图层和我们的选择条件,寻找出符合要求的要素并闪烁显示,使用的 IfeatureSelection 接口的 SelectFeatures 方法 Public Sub searchSelection(byval sqlfilter as string, byval pFeatLyr as iFeatureLayer) Dim pFilter As IqueryFilter ‘做一个过滤器 pFilter = New QueryFilter pFilter.WhereClause = sqlfilter 如"area>100000",ARCGIS 中的字段值是区分大小写的,如 nevada 不能写成 Nevada Dim pFeatureSelection As IFeatureSelection ‘获取图层 pFeatureSelection = pFeatLyr ‘QI pFeatureSelection.SelectFeatures(pFilter, esriSelectionResultEnum.esriSelectionResultNew, False) ‘重要方法 Dim pColor As IRgbColor pColor = New RgbColor pColor.Red = 220 pColor.Green = 112 pColor.Blue = 60 pFeatureSelection.SelectionColor = pColor ‘将选择集添上颜色 AxMapControl1.CtlRefresh(esriViewDrawPhase.esriViewGeoSelection) ‘控件局部刷新 Dim pFeatSet As IselectionSet ‘新建一个 selectionset 对象,它用于保存获得的要素 pFeatSet = pFeatureSelection.SelectionSet Dim pFeatCursor As IFeatureCursor pFeatSet.Search(Nothing, True, pFeatCursor) ‘使用要素游标去获取单个要素 Dim pFeat As IFeature pFeat = pFeatCursor.NextFeature Do Until pFeat Is Nothing If Not pFeat Is Nothing Then Dim pFillsyl2 As ISimpleFillSymbol pFillsyl2 = New SimpleFillSymbol pFillsyl2.Color = getRGB(220, 60, 60) AxMapControl1.FlashShape(pFeat.Shape, 15, 20, pFillsyl2) ‘被选中的要素闪烁 ‘将要素的某个字段值写入 LISTBOX ListBox1.Items.Add(pFeat.Value(pFeatCursor.FindField("state_name"))) ListBox1.Refresh() ‘可以使 listbox 中的项逐个出现 End If pFeat = pFeatCursor.NextFeature Loop End Sub 我们需要注意“将选择集添上颜色”这个语句,在这个过程中,符合要求的要素将呈选择状态,我们可以使用另外一种方法来设置选择集的颜色: Dim pSelEnv As ISelectionEnvironment Dim pRgbColor As IRgbColor Set pSelEnv = New SelectionEnvironment Set pRgbColor = New RgbColor pRgbColor.Red = 255 pSelEnv.AreaSelectionMethod = esriSpatialRelIntersects Set pSelEnv.DefaultColor = pRgbColor MapControl1.Map.SelectByShape MapControl1.TrackCircle, pSelEnv, False MapControl1.Refresh esriViewGeography 如上面代码中看到的,SelectionEnvironment 能够控件的要素选择集的缺省颜色,缺省 symbol 等。 32. 常用数据入 sde 库的代码 '**************************************************************** '函数功能: 将矢量要素导入到指定数据库的数据集中,可以将 shapefile,dxf,coverage 格式导入倒 GEodatabase 中 ' 参数表: ' pInDatasetNameCol 一个存储要导入的矢量要素(IFeatureClassName 类型)的 Collection 对象 ' pOutNameCol 一个存储导入的矢量要素名称(string 类型)的 Collection 对象 ' strGDBPath 包含矢量要素数据集名称的 GDB 路径,如“D:\world\Map3D.mdb” '**************************************************************** Public Function convFeatureClass(pInDatasetNameCol As Collection, pOutNameCol As Collection, strGDBPath As String) '获得导入数据的数目 Dim iInFCNum As Integer iInFCNum = pInDatasetNameCol.Count '获得输出的数据库名和数据集名 Dim sOutFDSName As String Dim sOutGDBName As String sOutFDSName = GetPathName(strGDBPath, 1) sOutGDBName = GetPathName(strGDBPath, 0) '获得输出要素集的 IFeatureDatasetName Dim pWSF As IWorkspaceFactory Set pWSF = New AccessWorkspaceFactory Dim pWS As IWorkspace Set pWS = pWSF.OpenFromFile(sOutGDBName, 0) Dim pOutFeatureWS As IFeatureWorkspace Set pOutFeatureWS = pWS '获得输出要素集的 Dataset Name Dim pOutFDSName As IFeatureDatasetName Dim pOutFDS As IFeatureDataset Set pOutFDS = pOutFeatureWS.OpenFeatureDataset(sOutFDSName) Set pOutFDSName = pOutFDS.FullName Dim i As Integer For i = 1 To iInFCNum Dim pOutPropertySet As IPropertySet Set pOutPropertySet = New PropertySet pOutPropertySet.SetProperty "DATASET", sOutGDBName Dim pOutWorkspaceName As IWorkspaceName Set pOutWorkspaceName = New WorkspaceName pOutWorkspaceName.ConnectionProperties = pOutPropertySet pOutWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory.1" '设置输出要素的 FeatureClass Name Dim pOutFCName As IFeatureClassName Set pOutFCName = New FeatureClassName Dim pDatasetName As IDatasetName Set pDatasetName = pOutFCName Set pDatasetName.WorkspaceName = pOutWorkspaceName pDatasetName.name = pOutNameCol.Item(i) '获得输入要素的 FeatureClass Name Dim pInDatasetName As IDatasetName Set pInDatasetName = pInDatasetNameCol.Item(i) '判断是否有重名现象 Dim pWS2 As IWorkspace2 Set pWS2 = pWS '如果名称已存在 If pWS2.NameExists(esriDTFeatureClass, pDatasetName.name) Then Dim R R = MsgBox("矢量要素" & pDatasetName.name & "在数据库中已存在!" & Chr(13) & "是否覆盖?", vbExclamation + vbYesNo) '覆盖原矢量要素 If R = vbYes Then Dim pFWS As IFeatureWorkspace Set pFWS = pWS Dim pDataset As IDataset Set pDataset = pFWS.OpenFeatureClass(pDatasetName.name) pDataset.Delete Set pFWS = Nothing Set pDataset = Nothing '不覆盖,则退出 for 循环,忽略这个要素,转入下一个要素的导入 Else GoTo NextStep End If Set pWS2 = Nothing End If '打开 Table 获得 Fields Dim pname As IName Dim pInTable As ITable Set pname = pInDatasetName Set pInTable = pname.Open Dim pInFields As IFields Set pInFields = pInTable.Fields '检查 Field Name Dim pFieldChecker As IFieldChecker Set pFieldChecker = New FieldChecker Dim pOutFields As IFields pFieldChecker.Validate pInFields, Nothing, pOutFields '对 Fields 进行循环查,查找 Geometry 域 Dim j As Integer Dim pGeoField As IField For j = 0 To pOutFields.FieldCount - 1 If pOutFields.Field(j).Type = esriFieldTypeGeometry Then Set pGeoField = pOutFields.Field(j) Exit For End If Next j '获得 Geometry Field 的 GeometryDef Dim pOutFCGeoDef As IGeometryDef Set pOutFCGeoDef = pGeoField.GeometryDef '设置 GeometryDef 的 GridCount,GridSize,SpatialReference Dim pOutFCGeoDefEdit As IGeometryDefEdit Set pOutFCGeoDefEdit = pOutFCGeoDef pOutFCGeoDefEdit.GridCount = 1 pOutFCGeoDefEdit.GridSize(0) = DefaultIndexGrid(pInTable) Dim re '判断空间参考是否一致,全局变量 m_SpatialRef 是创建的矢量要素集的空间参考 If m_SpatialRef.name <> pGeoField.GeometryDef.SpatialReference.name Then re = MsgBox(pInDatasetName.name & "的空间参考与数据库中的矢量要素集空间参考不符!" & Chr(13) _ & "导入后会丢失数据。 是否继续导入?", vbYesNo + vbExclamation) Set pOutFCGeoDefEdit.SpatialReference = m_SpatialRef If re = vbNo Then GoTo NextStep End If Else Set pOutFCGeoDefEdit.SpatialReference = pGeoField.GeometryDef.SpatialReference End If '+++++++++++++++++++ 'Set pOutFCGeoDefEdit.SpatialReference = pGeoField.GeometryDef.SpatialReference '进行导入 Dim pConverter As IFeatureDataConverter Set pConverter = New FeatureDataConverter pConverter.ConvertFeatureClass pInDatasetNameCol.Item(i), Nothing, pOutFDSName, pOutFCName, pOutFCGeoDef, pOutFields, "", 1000, 0 Set pOutPropertySet = Nothing Set pOutWorkspaceName = Nothing Set pOutFCName = Nothing Set pDatasetName = Nothing Set pInDatasetName = Nothing Set pname = Nothing Set pInTable = Nothing Set pFieldChecker = Nothing Set pOutFields = Nothing Set pGeoField = Nothing Set pOutFCGeoDef = Nothing Set pConverter = Nothing NextStep: Next i Set pWSF = Nothing Set pWS = Nothing End Function 33. ArcEngine 开发感想 用 AO 开发已经有一段时间了,对 AO 开发的模式也有一定的了解了!AO 是 ESRI 开发的一组 COM 的集合,利用它用户可以进行二次开发,以快速建立满足自 己要求的 GIS 应用. AO 开发就是利用一些类和这些类的接口进行开发. 1、抽象类,类,和组件对象类 抽象类是不能实例化的,抽象类中是一系列抽象的方法,故是不能实例化的,它只能被继承。不同的类可以继承同一个抽象类,但内部对同一方法的实现 可能是不一样的。如 AO 中的接口都是抽象类。用户可以在类中实现这些接口,也就是继承这些接口。如用户可以在自己的类中实现 ICommand 接口,生成一 个 Command,或者实现 ICommand、ITool 接口,生成一个 Tool. 类是不能直接实例化的,它只能作为另一个类的属性或者被其它类的对象实例化。如 Sde3Workspace Class、Sde4Workspace Class,FeatureClass,FeatureDataset 它们是不能通过 New 直接实例化的,只能通过 SdeWorkspaceFactory CoClass 这个组件对象类所实现的 IWorkspaceFactory 接口里的 Open 方法来实例化。 FeatureClass,FeatureDataset 也是不能直接实例化的,他只能通过 IFeatureWorkspace 接口里的 CreateFeatureClass,CreateFeatureDataset 方法来实例化。 组件对象类能够通过 New 来直接实例化。如 SdeWorkspaceFactory,QueryFilter 它们是可以通过 New 来直接实例化的。 2、继承 3、类和接口的实现 一些类可能实现多个接口,一个接口也可能被多个类所实现,但不同的类实现同一个接口可能内部并不是一样的,这就实现了多态性.如 ILayer 这个接口 被多个接口实现,其中包括 FeatureLayer 和 RasterLayer,但这两个类实现 ILayer 接口时内部实现肯定是不一样的!但在外部对 ILayer 的操作是一样的! 4、接口之间的相互查询 一个类可以实现多个接口,每一个接口可能包括一系列的属性和方法,但有时候一个接口里可能没有你想要的方法和属性,可能在这个类所实现接口的另 一个接口里,这就涉及到从一个接口转到这个类所实现接口的另一个接口里,对于类所实现的一系列接口里,接口间是可以相互跳转的。如我想对一个 feature 的属性进行修改,给的就是这个 feature 的 IFeature 接口,我们知道对一个 feature 进行修改必须要把这个 feature 所在的 featureclass 的工作空间设为可编辑,且编 辑结束后要结束编辑,这就要通过这个 IFeatue 接口来获得这个这个 feature 所在的 IFeatureClass 接口和 IWorkspace 接口,我们知道 IFeatue 接口里有一个 object 属性,这个属性返回的是 IObjectClass,而 FeatureClass 这个类实现了 IObjectClass 和 IFeatureClass 这两个接口,这样就可以通过接口跳转从 IObjectClass 转换成 IFeatureClass,这样就可以获得 feature 的 IFeatureClass 接口,其代码(c#)如下: IObjectClass i_objcls=I_FtrCur.Class; IFeatureClass i_ftrcls=(IFeatureClass)i_objcls; Feature 所在的 FeatureClass 的 IFeatureClass 接口有了,还要这个 FeatureClass 所在的工作空间的 IWorkspace 接口,获取这个接口可以通过两个方法 一、通过 IFeatureClass 接口里的 FeatureDataset 属性来获得 IFeatureDataset 接口。 IFeatureDataset 接口里有一个 Workspace 属性返回 IWorkspace 接口,但这种方法有一个特别说明就是这个 FeatureClass 必须是一个 FeatureDataset 的成员, 如果这个 FeatureClass 是一个独立,这个 FeatureDataset 返回的就是一个空值。所以这种方法对 FeatureClass 是一个 FeatureDataset 的成员时是适用的,独立时就 不适用了。 二、通过接口转换。 FeatureClass 实现了多个接口,其中有 IDataset 接口和 IFeatureClass 接口,我们已经有了 IFeatureClass 接口,就可以通过接口跳转来获得 IDataset 接口,在 IDataset 接口里有一个 Workspace 属性返回 IWorkspace 接口,这种方法对于 FeatureClass 是一个 FeatureDataset 的成员和 FeatureClass 是独立的这两种情况都是可 以的。代码如下: IDataset i_ftrDset=(IDataset)i_ftrcls //接口跳转 IFeatureWorkspace i_wks=(IFeatureWorkspace)i_ftrDset.Workspace 34. Geometry 对象浅析 作者:Flyingis ArcEngine Geometry 库定义了基本几何图形的矢量表达形式,顶级的几何图形有 Points、Multipoints、Polylines、Polygons、 Multipatches,Geodatabase 和绘图系统使用这些几何图形来定义其他各种形状的特征和图形,提供了编辑图形的操作方法和地图符号系统符号化特征数据的途径。 Geometry 库中几个核心类和接口构成了 Geometry 对象的基本框架。 GeometryEnvironment GeometryEnvironment 提供了从不同的输入、设置或获取全局变量来创建几何图形的方法,以便控制 geometry 方法的行为。GeometryEnvironment 对象 是一个单例对象。 public IPolyline TestGeometryEnvironment() { ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass(); //Create a projected coordinate system and define its domain, resolution, and x,y tolerance. ISpatialReferenceResolution spatialReferenceResolution = spatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_NAD1983UTM_11N) as ISpatialReferenceResolution; spatialReferenceResolution.ConstructFromHorizon(); ISpatialReferenceTolerance spatialReferenceTolerance = spatialReferenceResolution as ISpatialReferenceTolerance; spatialReferenceTolerance.SetDefaultXYTolerance(); ISpatialReference spatialReference = spatialReferenceResolution as ISpatialReference; //Create an array of WKSPoint structures starting in the middle of the x,y domain of the //projected coordinate system. double xMin; double xMax; double yMin; double yMax; spatialReference.GetDomain(out xMin, out xMax, out yMin, out yMax); double xFactor = (xMin + xMax) * 0.5; double yFactor = (yMin + yMax) * 0.5; WKSPoint[] wksPoints = new WKSPoint[10]; for (int i = 0; i < wksPoints.Length; i++) { wksPoints[i].X = xFactor + i; wksPoints[i].Y = yFactor + i; } IPointCollection4 pointCollection = new PolylineClass(); IGeometryBridge2 geometryBridge = new GeometryEnvironmentClass(); geometryBridge.AddWKSPoints(pointCollection, ref wksPoints); IPolyline polyline = pointCollection as IPolyline; polyline.SpatialReference = spatialReference; return polyline; } new GeometryEnvironmentClass 仅仅是创建了一个指向已存在的 GeometryEnvironmentClass 的引用。注意 IGeometryBridge2 接口的使用,addWKSPoints 方法将 WKSPoint 二维点添加到 PointCollection 中,用于构建 path、ring、polyline、polygon,或增加新点到 Multipoint、TriangleFan、TriangleStrip。在 Geometry 库中,除了 IGeometryBridge2 还有 IGeometryBridge 接口,后者继承了前者,增加了一些编辑功能(添加点、插入点、重置点、分段等)。 GeometryBag GeometryBag 是支持 IGeometry 接口的几何对象引用的集合,任何几何对象都可以通过 IGeometryCollection 接口添加到 GeometryBag 中,但是在使用 拓扑操作的时候,需要注意不同类型的几何类型可能会有相互不兼容的情况。在向 GeometryBag 中添加几何对象的时候,GeometryBag 对象需要指定空间参考, 添加到其中的几何对象均拥有和 GeometryBag 对象一样的空间参考。 private IPolygon GeometryBag_Example(IFeatureClass featureClass) { //Check input objects. if (featureClass == null) { return null; } IGeoDataset geoDataset = featureClass as IGeoDataset; ISpatialFilter queryFilter = new SpatialFilterClass(); //Set the properties of the spatial filter here. IGeometry geometryBag = new GeometryBagClass(); //Define the spatial reference of the bag before adding geometries to it. geometryBag.SpatialReference = geoDataset.SpatialReference; //Use a nonrecycling cursor so each returned geometry is a separate object. IFeatureCursor featureCursor = featureClass.Search(queryFilter, false); IGeometryCollection geometryCollection = geometryBag as IGeometryCollection; IFeature currentFeature = featureCursor.NextFeature(); while (currentFeature != null) { //Add a reference to this feature's geometry into the bag. //You don't specify the before or after geometry (missing), //so the currentFeature.Shape IGeometry is added to the end of the geometryCollection. object missing = Type.Missing; geometryCollection.AddGeometry(currentFeature.Shape, ref missing, ref missing); currentFeature = featureCursor.NextFeature(); } // Create the polygon that will be the union of the features returned from the search cursor. // The spatial reference of this feature does not need to be set ahead of time. The // ConstructUnion method defines the constructed polygon's spatial reference to be the same as // the input geometry bag. ITopologicalOperator unionedPolygon = new PolygonClass(); unionedPolygon.ConstructUnion(geometryBag as IEnumGeometry); return unionedPolygon as IPolygon; } Points 一个点包括 X、Y 坐标,同时可以增加 M、Z 值及 ID 属性来扩展点的功能。 Multipoints 点的集合,多点组成 Multipoint 几何类型,使用 multipoint 对象实现了的 IPointCollection 接口可以访问所有的点元素,这些点同样可以拥有 M、Z 值及 ID 属性来获得更多的地理空间内涵。 下面列举一个例子,通过一个已知的 polyline 来定义一个新的 multipart polyline。 public IPolyline ConstructMultiPartPolyline(IPolyline inputPolyline) { IGeometry outGeometry = new PolylineClass(); //Always associate new, top-level geometries with an appropriate spatial reference. outGeometry.SpatialReference = inputPolyline.SpatialReference; IGeometryCollection geometryCollection = outGeometry as IGeometryCollection; ISegmentCollection segmentCollection = inputPolyline as ISegmentCollection; //Iterate over existing polyline segments using a segment enumerator. IEnumSegment segments = segmentCollection.EnumSegments; ISegment currentSegment; int partIndex = 0;; int segmentIndex = 0;; segments.Next(out currentSegment,ref partIndex, ref segmentIndex); while(currentSegment != null) { ILine normal = new LineClass(); //Geometry methods with _Query_ in their name expect to modify existing geometries. //In this case, the QueryNormal method modifies an existing line //segment (normal) to be the normal vector to //currentSegment at the specified location along currentSegment. currentSegment.QueryNormal(esriSegmentExtension.esriNoExtension, 0.5, true, currentSegment.Length / 3, normal); //Since each normal vector is not connected to others, create a new path for each one. ISegmentCollection newPath = new PathClass(); object missing = Type.Missing; newPath.AddSegment(normal as ISegment, ref missing, ref missing); //The spatial reference associated with geometryCollection will be assigned to all incoming paths and segments. geometryCollection.AddGeometry(newPath as IGeometry, ref missing, ref missing); segments.Next(out currentSegment,ref partIndex, ref segmentIndex); } //The geometryCollection now contains the new, multipart polyline. return geometryCollection as IPolyline; } ISegment 接口的 QueryNormal 方法用来在弧段上的某一点生成该弧段的法线,指定其长度,这样就生成了新的 segment,并且多个 path 添加到 geometryCollection 中,以 IPolyline 的形式返回。 Polylines Polylines 是有序 path 组成的集合,可以拥有 M、Z 和 ID 属性值。Polyline 对象的 IPointCollection 接口包含了所有节点的复制,IGeometryCollection 接 口可以获取 polyline 的 paths,ISegmentCollection 接口可以获取 polyline 的 segments。 Polyline 结构图 Polygons Polygon 是一系列 rings 组成的集合,可以拥有 M、Z 和 ID 属性值。每一个 ring 由一个或多个 segment 组成,Polygon 或 ring 对象的 IPointCollection 接 口包含了所有节点的复制,IGeometryCollection 接口可以获取 polygon 的 rings, ISegmentCollection 接口可以获取 polygon 的 segments。 Polygon 结构图 Multipatch Multipatch 用于描述 3D 面状几何类型,由一系列的矢量三角形构成,如果其中的 part 是一个 ring,那么它必须是封闭的,第一个节点和最后一个节点 相同,另外每个 part 所包含节点的顺序非常重要,Inner Rings 在 Outer Rings 之后,代表单个表面 patch 的一系列 rings 必须由第一个 ring 开始。 在 9.0 以后的开发包中,使用 IGeneralMultiPatchCreator 创建新的 Multipatch,IGeometryMaterial 进行材质贴图。 public IMultiPatch CreateMultipatch() { //Prepare the geometry material list. IGeometryMaterial texture = new GeometryMaterialClass(); texture.TextureImage = "C:\\Temp\\MyImage.bmp"; IGeometryMaterialList materialList = new GeometryMaterialListClass(); materialList.AddMaterial(texture); //Create the multipatch. IGeneralMultiPatchCreator multiPatchCreator = new GeneralMultiPatchCreatorClass(); multiPatchCreator.Init(4, 1, false, false, false, 4, materialList); //Set up part. //Could also use a Ring or a TriangleFan. multiPatchCreator.SetPatchType(0, esriPatchType.esriPatchTypeTriangleStrip); multiPatchCreator.SetMaterialIndex(0, 0); multiPatchCreator.SetPatchPointIndex(0, 0); multiPatchCreator.SetPatchTexturePointIndex(0, 0); //Set real-world points. WKSPointZ upperLeft = new WKSPointZ(); WKSPointZ lowerLeft = new WKSPointZ(); WKSPointZ upperRight = new WKSPointZ(); WKSPointZ lowerRight = new WKSPointZ(); upperLeft.X = 0; upperLeft.Y = 0; upperLeft.Z = 0; upperRight.X = 300; upperRight.Y = 0; upperRight.Z = 0; lowerLeft.X = 0; lowerLeft.Y = 0; lowerLeft.Z = -100; lowerRight.X = 300; lowerRight.Y = 1; lowerRight.Z = -100; multiPatchCreator.SetWKSPointZ(0, ref upperRight); multiPatchCreator.SetWKSPointZ(1, ref lowerRight); multiPatchCreator.SetWKSPointZ(2, ref upperLeft); multiPatchCreator.SetWKSPointZ(3, ref lowerLeft); //Set texture points. //Set the texture coordinates for a panel. WKSPoint textureUpperLeft = new WKSPoint(); WKSPoint textureLowerLeft = new WKSPoint(); WKSPoint textureUpperRight = new WKSPoint(); WKSPoint textureLowerRight = new WKSPoint(); textureUpperLeft.X = 0; textureUpperLeft.Y = 0; textureUpperRight.X = 1; textureUpperRight.Y = 0; textureLowerLeft.X = 0; textureLowerLeft.Y = 1; textureLowerRight.X = 1; textureLowerRight.Y = 1; multiPatchCreator.SetTextureWKSPoint(0, ref textureUpperRight); multiPatchCreator.SetTextureWKSPoint(1, ref textureLowerRight); multiPatchCreator.SetTextureWKSPoint(2, ref textureUpperLeft); multiPatchCreator.SetTextureWKSPoint(3, ref textureLowerLeft); IMultiPatch multiPatch = multiPatchCreator.CreateMultiPatch() as IMultiPatch; return multiPatch; } 35. AE 开发中的一些基本方法(1)数据连接 1.连接 SDE 的方法: Public Function openSDEWorkspace(Server As String, Instance As String, User As String, _ Password As String, Optional Database As String = "", _ Optional version As String = "SDE.DEFAULT") As IWorkspace On Error GoTo EH Set openSDEWorkspace = Nothing Dim pPropSet As IPropertySet Dim pSdeFact As IWorkspaceFactory Set pPropSet = New PropertySet With pPropSet .SetProperty "SERVER", Server .SetProperty "INSTANCE", Instance .SetProperty "DATABASE", Database .SetProperty "USER", User .SetProperty "PASSWORD", Password .SetProperty "VERSION", version End With Set pSdeFact = New SdeWorkspaceFactory Set openSDEWorkspace = pSdeFact.Open(pPropSet, 0) Exit Function EH: MsgBox Err.Description, vbInformation, "openSDEWorkspace" End Function '///**************************************************************************************\\\ ' 功能: ' 连接 SDEgeodatabase. ' 参数: ' Server 服务器名称 ' Instance SDE 事例名称 ' User 用户名 ' Password 密码 ' Database 数据库名称 ' version 存放路径 '\\\**************************************************************************************/// '____________________________________________________________________ 2.连接 Access 的即 personalGeodataBase 的方法: Function OpenPGEO(connString As String) As IWorkspace On Error GoTo EH Dim pWS As IWorkspace Dim pWorkspaceFactory As IWorkspaceFactory Set OpenPGEO = Nothing Set pWorkspaceFactory = New AccessWorkspaceFactory Set pWS = pWorkspaceFactory.OpenFromFile(connString, 1) Set OpenPGEO = pWS Exit Function EH: MsgBox Err.Description, vbInformation, "openAccessWorkspace" End Function 示冽:Set WKSpace = OpenPGEO("d:\phk.mdb") 3. '///***************************************************************************\\\ '从 WorkSpace 取出一个 FeatureClass 并添加到一个 IFeatureLayer 返回 ' 2006.1.19 CBH '\\\***************************************************************************/// Public Function getFCfSDE(FclsName As String ,WKSpace As IWorkspace ) As IFeatureLayer '///************************************************************************\\\ '此处要改为从 SDE 中取数据 Dim pFWKSpace As IFeatureWorkspace Dim pFGLayer As IFeatureLayer Dim pFGClass As IFeatureClass Dim pVersionedObject As IVersionedObject Dim pVersion As IVersion Set pFWKSpace = WKSpace Set pFGClass = pFWKSpace.OpenFeatureClass(Trim(FclsName)) ' Set pVersionedObject = pFGClass 'Registering a stand alone feature class as versioned ' Set pVersion = pVersionedObject.version '' MsgBox pVersion.VersionName ' pVersionedObject.RegisterAsVersioned (True) Set pFGLayer = New FeatureLayer Set pFGLayer.FeatureClass = pFGClass Set getFCfSDE = pFGLayer '\\\************************************************************************/// End Function 通过上面 3 个基本方法,那就可以实现一个基本功能了,就是从任意 GeodataBase 中取出任意一个你需要的矢量数据,并且显示出来.作为 GIS 的应用开发,我想 这写应该是第一步要做的. 那有人就想知道,如何取出一个 珊格的文件,并且显示呢? 我再给出下面 2 个基本方法,那么就也不是什么难事了: 4.打开一个珊格目录的方法: Public Function OpenArcSDERasterCatalog(pWorks As IWorkspace, sRasterCatalogName As String) As IRasterCatalog Dim pWsFact As IWorkspaceFactory Dim pWs As IRasterWorkspaceEx Dim pRasterCatalog As IRasterCatalog Dim pPropertySet As IPropertySet Set pWs = pWorks Set pRasterCatalog = pWs.OpenRasterCatalog(sRasterCatalogName) Set OpenArcSDERasterCatalog = pRasterCatalog Set pWsFact = Nothing Set pWs = Nothing Set pRasterCatalog = Nothing End Function 5.去出一个珊格目录中的所有项并且作为一个 RasterLayer 提交: function getRasterLayerFRCatalog( layerPath As String , WKSpace as IworkSpace )as Ilayer Dim pSDERasterCatlg As IRasterCatalog Dim pLayer As ILayer Dim pGdbRasterCatalogLy As IGdbRasterCatalogLayer Dim pFeature As IFeatureLayer Dim pGEO As IGeoDataset Set pGdbRasterCatalogLy = New GdbRasterCatalogLayer Set pSDERasterCatlg = OpenArcSDERasterCatalog(WKSpace, Trim(layerPath)) pGdbRasterCatalogLy.Setup pSDERasterCatlg Set player = pGdbRasterCatalogLy end function
还剩131页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

sxb17

贡献于2013-06-06

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf