示例:
在进行这两个接口的运算前要注意下,如果参加运算的两个Geometry对象不是简单对象时,(注1:Simple对象,见下图)(注2:可以用ITopologicalOperator接口的IsSimple函数进行判断)(注3:当使用IPointCollection等接口生成或编辑的Geometry对象比较常出现这种情况),运算有可能会出错,并得不出想要的结果,这时需要对其进行处理:
简单对象的定义及处理
附1:ITopologicalOperator的一些函数示意:
方法名称 |
说明 |
Boundary |
几何图形对象的边界 |
Buffer |
对几何图形对象进行缓冲区空间拓扑操作 |
Clip |
对几何图形对象进行裁剪空间拓扑操作 |
ConstructUnion |
高效的合并多个枚举几何对象与单个几何对象合并为单个几何对象,这对于大量几何对象的合并非常高效 |
ConvexHull |
构建几何对象的凸边形 |
Cut |
切割几何对象 |
Difference |
一个几何图形减去它与另一个几何图形相交的部分 |
Intersect |
两个同维度几何对象的交集部分 |
Simplify |
使几何对象拓扑一致 |
SymmetricDifference |
对称差分将两个几何图形的并集部分减去两个几何图形交集的部分 |
Union |
合并两个同维度的几何对象为单个几何对象 |
图解:
http://www.gisjc.com/a/ArcGIS_Engine/2010/0425/239.html
附2:IRelationalOperator的一些关系类型:
关系类型 | 描述 |
Contains | 判断一个图形是否包含另外一个图形 |
Within | 判断一个图形是否被另外一个图形所包含。 |
Crosses | 判断两个图形是否在维数较少的那个图形的内部相交 |
Disjoint | 判断两个图形间是否没有相同点 |
Equals | 判断两个图形是否是同一个类型并且在平面上的点是否是相同的位置。如果返回值为真,则它们应该包含(Contains)另外一个图形同时也被另外一个图形所包含(Within)。 |
Overlaps | 判断两个图形的交集是否和其中的一个图形拥有相同的维数,并且他们交集不能和其中任何一个图形相等。该方法只使用与两个Polyline 之间或者两个Polygon 之间。 |
Touch | 判断两个图形的边界是否相交,如果两个图形的交集不为空,但两个图形内部的交集为空,则返回值为真。 |
C#+AE判断点是否在面内
判断点是否在面内,AE提供了两个方法可以简单实现此功能: TopologicalOperator和RelationalOperator.
下面是我自己试验两种方法都可行.
pFeature是一个面.
pTmpPt=pTmpFeature.Shape as IPoint
1、利用ITopologicalOperator接口
ITopologicalOperator pRegionTopo = (ITopologicalOperator)pFeature.Shape;
if (pRegionTopo.Intersect(pTmpPt, esriGeometryDimension.esriGeometry0Dimension) != null)
{
//表示点在面上
}
2、利用 IRelationalOperator接口
IRelationalOperator pRelOpt = pFeature.Shape as IRelationalOperator;
if (pRelOpt.Contains(pTmpPt))
{
//表示面包含点
}
这里需要注意的就是,要保证点和面的空间参考必须一致,否则会出错.
下面写了一个封装了ArcGIS中Cost Distance求算功能的类,这个类的使用方法和ArcGIS Desktop中 Spatial Analyst---Cost Distance的调用方式一致,只需要传递cost surface,
source surface 和输出的栅格文件名。
关键要注意对IRasterAnalysisEnvironment的设置。
class RasterCostDistance { private IRasterLayer costRasterlayer; public RasterCostDistance(IRasterLayer costRasterlayer) { this.costRasterlayer = costRasterlayer; } public IRasterLayer CalCostDistance(IRasterLayer sourceRasterlayer, string outputFileName) { if (System.IO.File.Exists(outputFileName)) { System.IO.File.Delete(outputFileName); } IGeoDataset sourceRaster = sourceRasterlayer.Raster as IGeoDataset; IGeoDataset costRaster = costRasterlayer.Raster as IGeoDataset; IDistanceOp2 distanceOp = new RasterDistanceOpClass(); IRasterAnalysisEnvironment rasAnaEnv = distanceOp as IRasterAnalysisEnvironment; //设置生成图层的工作空间 IWorkspaceFactory wsf = new RasterWorkspaceFactoryClass(); string outputPath = System.IO.Path.GetDirectoryName(outputFileName); string fileName = System.IO.Path.GetFileName(outputFileName); IWorkspace ws = wsf.OpenFromFile(outputPath, 0); rasAnaEnv.OutWorkspace = ws; //设置生成图层的范围 object extent = (object)costRaster.Extent; object missing = System.Reflection.Missing.Value; rasAnaEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref extent, ref missing); //设置生成图层的栅格大小 rasAnaEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvMinOf, ref cellsize);
//进行成本距离的计算 object maxDistance = System.Reflection.Missing.Value; object valueRaster = System.Reflection.Missing.Value; IGeoDataset outputDataset = distanceOp.CostDistance(sourceRaster, costRaster, ref maxDistance, ref valueRaster);
//生成的IRaster是保存在内存中的数据,要保存在硬盘文件中还应使用ISaveas ISaveAs pSaveAs = outputDataset as ISaveAs; pSaveAs.SaveAs(fileName, ws, "IMAGINE Image"); IRasterLayer pCreatRalyr = new RasterLayerClass(); pCreatRalyr.CreateFromFilePath(outputFileName); return pCreatRalyr; } }
在进行join之前,请确认数据库可以连接
try
{
//使用oledb连接数据库,连接到sys.基本信息表
IWorkspaceFactory pWorkspaceFactory = new OLEDBWorkspaceFactory();
IPropertySet pPropSet = new PropertySet();
pPropSet.SetProperty("CONNECTSTRING","Provider=sqloledb;Data Source=" + this.instanceBox.Text + ";Initial Catalog=sys;User Id=sa;Password=sa;");
IWorkspace pWorkspace = pWorkspaceFactory.Open(pPropSet,0);
IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
ITable pForeignTable = pFeatureWorkspace.OpenTable("sys.基本信息表");
//打开已经修复好数据源的temp.mxd
IMapDocument pMapDocument = new MapDocumentClass();
pMapDocument.Open(startPath + @"\temp.mxd",null);
IMap pMap = pMapDocument.get_Map(0);
//获取图层
ILayer pLayer = null;
for (int i = 0; i < pMap.LayerCount; i++)
{
if (pMap.get_Layer(i).Name == "点位")
{
pLayer = pMap.get_Layer(i);
}
}
if (pLayer == null)
{
MessageBox.Show("打开地图文件(.mxd)失败");
return;
}
//join
IFeatureLayer pFLayer = (IFeatureLayer)pLayer;
IFeatureClass pFClass2 = pFLayer.FeatureClass;
IMemoryRelationshipClassFactory pMemRelClassFactory = new MemoryRelationshipClassFactoryClass();
IRelationshipClass pRelaClass = pMemRelClassFactory.Open("TableJoin1",pFClass2,"点位编号",(IObjectClass)pForeignTable,"点位编号","forward","backward",esriRelCardinality.esriRelCardinalityOneToOne);
IDisplayRelationshipClass pDisplayRelationshipC = (IDisplayRelationshipClass)pFLayer;
pDisplayRelationshipC.DisplayRelationshipClass(pRelaClass,esriJoinType.esriLeftOuterJoin);
pMapDocument.Save(false,true);
pMapDocument.Close();
}
catch (System.Exception ex4)
{
MessageBox.Show(ex4.Message);
return;
}
示例:
在进行这两个接口的运算前要注意下,如果参加运算的两个Geometry对象不是简单对象时,(注1:Simple对象,见下图)(注2:可以用ITopologicalOperator接口的IsSimple函数进行判断)(注3:当使用IPointCollection等接口生成或编辑的Geometry对象比较常出现这种情况),运算有可能会出错,并得不出想要的结果,这时需要对其进行处理:
简单对象的定义及处理
附1:ITopologicalOperator的一些函数示意:
方法名称 |
说明 |
Boundary |
几何图形对象的边界 |
Buffer |
对几何图形对象进行缓冲区空间拓扑操作 |
Clip |
对几何图形对象进行裁剪空间拓扑操作 |
ConstructUnion |
高效的合并多个枚举几何对象与单个几何对象合并为单个几何对象,这对于大量几何对象的合并非常高效 |
ConvexHull |
构建几何对象的凸边形 |
Cut |
切割几何对象 |
Difference |
一个几何图形减去它与另一个几何图形相交的部分 |
Intersect |
两个同维度几何对象的交集部分 |
Simplify |
使几何对象拓扑一致 |
SymmetricDifference |
对称差分将两个几何图形的并集部分减去两个几何图形交集的部分 |
Union |
合并两个同维度的几何对象为单个几何对象 |
图解:
http://www.gisjc.com/a/ArcGIS_Engine/2010/0425/239.html
附2:IRelationalOperator的一些关系类型:
关系类型 | 描述 |
Contains | 判断一个图形是否包含另外一个图形 |
Within | 判断一个图形是否被另外一个图形所包含。 |
Crosses | 判断两个图形是否在维数较少的那个图形的内部相交 |
Disjoint | 判断两个图形间是否没有相同点 |
Equals | 判断两个图形是否是同一个类型并且在平面上的点是否是相同的位置。如果返回值为真,则它们应该包含(Contains)另外一个图形同时也被另外一个图形所包含(Within)。 |
Overlaps | 判断两个图形的交集是否和其中的一个图形拥有相同的维数,并且他们交集不能和其中任何一个图形相等。该方法只使用与两个Polyline 之间或者两个Polygon 之间。 |
Touch | 判断两个图形的边界是否相交,如果两个图形的交集不为空,但两个图形内部的交集为空,则返回值为真。 |
C#+AE判断点是否在面内
判断点是否在面内,AE提供了两个方法可以简单实现此功能: TopologicalOperator和RelationalOperator.
下面是我自己试验两种方法都可行.
pFeature是一个面.
pTmpPt=pTmpFeature.Shape as IPoint
1、利用ITopologicalOperator接口
ITopologicalOperator pRegionTopo = (ITopologicalOperator)pFeature.Shape;
if (pRegionTopo.Intersect(pTmpPt, esriGeometryDimension.esriGeometry0Dimension) != null)
{
//表示点在面上
}
2、利用 IRelationalOperator接口
IRelationalOperator pRelOpt = pFeature.Shape as IRelationalOperator;
if (pRelOpt.Contains(pTmpPt))
{
//表示面包含点
}
这里需要注意的就是,要保证点和面的空间参考必须一致,否则会出错.
下面写了一个封装了ArcGIS中Cost Distance求算功能的类,这个类的使用方法和ArcGIS Desktop中 Spatial Analyst---Cost Distance的调用方式一致,只需要传递cost surface,
source surface 和输出的栅格文件名。
关键要注意对IRasterAnalysisEnvironment的设置。
class RasterCostDistance { private IRasterLayer costRasterlayer; public RasterCostDistance(IRasterLayer costRasterlayer) { this.costRasterlayer = costRasterlayer; } public IRasterLayer CalCostDistance(IRasterLayer sourceRasterlayer, string outputFileName) { if (System.IO.File.Exists(outputFileName)) { System.IO.File.Delete(outputFileName); } IGeoDataset sourceRaster = sourceRasterlayer.Raster as IGeoDataset; IGeoDataset costRaster = costRasterlayer.Raster as IGeoDataset; IDistanceOp2 distanceOp = new RasterDistanceOpClass(); IRasterAnalysisEnvironment rasAnaEnv = distanceOp as IRasterAnalysisEnvironment; //设置生成图层的工作空间 IWorkspaceFactory wsf = new RasterWorkspaceFactoryClass(); string outputPath = System.IO.Path.GetDirectoryName(outputFileName); string fileName = System.IO.Path.GetFileName(outputFileName); IWorkspace ws = wsf.OpenFromFile(outputPath, 0); rasAnaEnv.OutWorkspace = ws; //设置生成图层的范围 object extent = (object)costRaster.Extent; object missing = System.Reflection.Missing.Value; rasAnaEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref extent, ref missing); //设置生成图层的栅格大小 rasAnaEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvMinOf, ref cellsize);
//进行成本距离的计算 object maxDistance = System.Reflection.Missing.Value; object valueRaster = System.Reflection.Missing.Value; IGeoDataset outputDataset = distanceOp.CostDistance(sourceRaster, costRaster, ref maxDistance, ref valueRaster);
//生成的IRaster是保存在内存中的数据,要保存在硬盘文件中还应使用ISaveas ISaveAs pSaveAs = outputDataset as ISaveAs; pSaveAs.SaveAs(fileName, ws, "IMAGINE Image"); IRasterLayer pCreatRalyr = new RasterLayerClass(); pCreatRalyr.CreateFromFilePath(outputFileName); return pCreatRalyr; } }
在进行join之前,请确认数据库可以连接
try
{
//使用oledb连接数据库,连接到sys.基本信息表
IWorkspaceFactory pWorkspaceFactory = new OLEDBWorkspaceFactory();
IPropertySet pPropSet = new PropertySet();
pPropSet.SetProperty("CONNECTSTRING","Provider=sqloledb;Data Source=" + this.instanceBox.Text + ";Initial Catalog=sys;User Id=sa;Password=sa;");
IWorkspace pWorkspace = pWorkspaceFactory.Open(pPropSet,0);
IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
ITable pForeignTable = pFeatureWorkspace.OpenTable("sys.基本信息表");
//打开已经修复好数据源的temp.mxd
IMapDocument pMapDocument = new MapDocumentClass();
pMapDocument.Open(startPath + @"\temp.mxd",null);
IMap pMap = pMapDocument.get_Map(0);
//获取图层
ILayer pLayer = null;
for (int i = 0; i < pMap.LayerCount; i++)
{
if (pMap.get_Layer(i).Name == "点位")
{
pLayer = pMap.get_Layer(i);
}
}
if (pLayer == null)
{
MessageBox.Show("打开地图文件(.mxd)失败");
return;
}
//join
IFeatureLayer pFLayer = (IFeatureLayer)pLayer;
IFeatureClass pFClass2 = pFLayer.FeatureClass;
IMemoryRelationshipClassFactory pMemRelClassFactory = new MemoryRelationshipClassFactoryClass();
IRelationshipClass pRelaClass = pMemRelClassFactory.Open("TableJoin1",pFClass2,"点位编号",(IObjectClass)pForeignTable,"点位编号","forward","backward",esriRelCardinality.esriRelCardinalityOneToOne);
IDisplayRelationshipClass pDisplayRelationshipC = (IDisplayRelationshipClass)pFLayer;
pDisplayRelationshipC.DisplayRelationshipClass(pRelaClass,esriJoinType.esriLeftOuterJoin);
pMapDocument.Save(false,true);
pMapDocument.Close();
}
catch (System.Exception ex4)
{
MessageBox.Show(ex4.Message);
return;
}