`
devgis
  • 浏览: 134838 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

arcgis engine空间运算 engine中空间运算接口ITopologicalOperator与空间关系接口IRelationalOperator

 
阅读更多

engine中空间运算接口ITopologicalOperator与空间关系接口IRelationalOperator

分类:c#engine1426人阅读评论(1)收藏举报

示例:

[c-sharp]view plaincopy
  1. ITopologicalOperatorsourcePolygon=(ITopologicalOperator)outerPolygon;
  2. IPolygonresultPolygon=(IPolygon)sourcePolygon.Difference(cutPolygons);

[c-sharp]view plaincopy
  1. IRelationalOperatorre=(IRelationalOperator)outerPolygon;
  2. if(!re.Contains(inPolygon))
  3. {
  4. thrownewException("abcdefg");
  5. }

在进行这两个接口的运算前要注意下,如果参加运算的两个Geometry对象不是简单对象时,(注1:Simple对象,见下图)(注2:可以用ITopologicalOperator接口的IsSimple函数进行判断)(注3:当使用IPointCollection等接口生成或编辑的Geometry对象比较常出现这种情况),运算有可能会出错,并得不出想要的结果,这时需要对其进行处理:

[c-sharp]view plaincopy
  1. ((ITopologicalOperator)outerPolygon).Simplify();

简单对象的定义及处理

简单对象的定义及处理

附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 Engine求算成本距离

下面写了一个封装了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;
}



示例:

[c-sharp]view plaincopy
  1. ITopologicalOperatorsourcePolygon=(ITopologicalOperator)outerPolygon;
  2. IPolygonresultPolygon=(IPolygon)sourcePolygon.Difference(cutPolygons);

[c-sharp]view plaincopy
  1. IRelationalOperatorre=(IRelationalOperator)outerPolygon;
  2. if(!re.Contains(inPolygon))
  3. {
  4. thrownewException("abcdefg");
  5. }

在进行这两个接口的运算前要注意下,如果参加运算的两个Geometry对象不是简单对象时,(注1:Simple对象,见下图)(注2:可以用ITopologicalOperator接口的IsSimple函数进行判断)(注3:当使用IPointCollection等接口生成或编辑的Geometry对象比较常出现这种情况),运算有可能会出错,并得不出想要的结果,这时需要对其进行处理:

[c-sharp]view plaincopy
  1. ((ITopologicalOperator)outerPolygon).Simplify();

简单对象的定义及处理

简单对象的定义及处理

附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 Engine求算成本距离

下面写了一个封装了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;
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics