9.2 空間拓撲運算


9.2.  空間拓撲運算

9.2.1.   ITopologicalOperator接口

通過一系列基於一個或者多個幾何圖形中點間的邏輯比較,然后返回另外一些幾何圖形,這個過程就是空間幾何圖形的拓撲運算。

空間幾何圖形的拓撲運算包括裁切(Clip)、凸多邊形(Convex hull)、切割(Cut)、差分(Difference)、交集(Intersect)、對稱差分(又稱為異或,Symmetric difference)和並集(Union)等,這些拓撲運算在ITopologicalOperator接口中定義,在GeometryBag、Multipoint、Point、Polygon、Polyline類中實現。

注意ITopologicalOperator接口的方法僅僅能使用在高級幾何對象上,即Point、Multipoint、Polyline和Polygon;如果要在低級的幾何對象上如Segment、Path或Ring上使用,則需要先組合為高級別幾何對象才行。

 

ITopologicalOperator::Boundary可以返回一個幾何對象的邊界,邊界的維度比源對象要低一維。

ITopologicalOperator::Buffer可以給一個高級別幾何對象產生一個緩沖區,無論是點、多邊形還是多義線,他們的緩沖區都是一個具有面積的幾何對象。

ITopologicalOperator::Clip方法可以將一個幾何對象使用一個包絡線來進行裁切,裁切的結果為幾何對象被包絡線包圍的部分。

ITopologicalOperator::ConstructUnion方法可以將一個幾何對象的枚舉(包含了多個幾何對象的枚舉值)與同維度的單個幾何對象合並,這種方法在大量幾何對象合並的時候是非常有效的;Union方法則可以合並兩個同維度的單個幾何對象,合並后的兩個單個幾何對象將變成一個幾何對象。

ITopologicalOperator::ConvexHull方法可以產生一個幾何圖形的最小的邊框凸多邊形。

ITopologicalOperator::Cut方法指定一條切割曲線和一個幾何圖形,經過切割運算后把幾何圖形分為左右兩部分,左右兩部分是相對曲線的方向而言;注意,點和多點是不能被切割的,而折線和多邊形只有與切割曲線相交時才能進行切割運算。

ITopologicalOperator::Difference方法可以產生兩個幾何對象的差集。如A是源對象,B是參與運算的幾何對象,則C是A減去A與B的交集后剩下的部分;而SymmetricDifference(對稱差分)方法則是將A與B的並集減去A與B的交集部分。

ITopologicalOperator::Intersection則可以返回兩個維度幾何形體對象的交集,即兩個對象重合部分。

 

參與空間拓撲運算的幾何形體,必須是拓撲上簡單的(topologically simple),否則會產生esriGeometryError536錯誤。

當幾何形體自上次驗證之后並未發生變化,那么IsKnowSimple屬性返回True;而IsSimple才是實際上驗證幾何形體是不是拓撲上簡單的。因此在使用IsSimple之前檢驗IsKnownSimple是更有效的,特別是在循環里,如下代碼:

IEnumGeometry pEnumGeom;
pEnumGeom = pGeometryBag as IEnumGeometry;
ITopologicalOperator pTopoOp;
pTopoOp = pEnumGeom.Next() as ITopologicalOperator;
while ( pTopoOp != null)
{ 
    //首先驗證IsKnownSimple因為它速度更快
    //在枚舉特別大的時候這樣更節約時間
    if (!( pTopoOp.IsKnownSimple))
    {
        if (!( pTopoOp.IsSimple))
            pTopoOp.Simplify();
    }
    pTopoOp = pEnumGeom.Next()as ITopologicalOperator;
}

 

ITopologicalOperator::Simplify方法可以讓一個幾何對象變得在拓撲上一致,例如在一個PointCollection中,它可以讓所有的重合點(即兩個點擁有相同坐標值)被移除(出發擁有不同的屬性);對於SegmentCollection,它將移除重合的線段,而相交的線段會變成非相交的線段(即在相交點處產生一個頂點);對於Polygon而言,所有相交的環將被移除,所有的內外的方向將被修正,未封閉的環將被封閉,如圖

 

9.2.2.   開發實例 -- 緩沖區查詢

pActiveView = axMapControl1.ActiveView;
pMap = axMapControl1.Map;
IFeatureLayer pFeatureLayer = pMap.get_Layer(1) as IFeatureLayer;
IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
//鼠標點擊Map的點
IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
//對點對象做緩沖區運算
ITopologicalOperator pTopo;
pTopo = pPoint as ITopologicalOperator;
IGeometry pBuffer;
pBuffer = pTopo.Buffer(4);
IGeometry pGeometry = pBuffer.Envelope;
//創建空間過濾器
ISpatialFilter pSpatialFilter;
pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.Geometry = pGeometry;
//綁定空間過濾關系
switch (pFeatureClass.ShapeType)
{
    case esriGeometryType.esriGeometryPoint:
        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
        break;
    case esriGeometryType.esriGeometryPolyline:
        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
        break;
    case esriGeometryType.esriGeometryPolygon:
        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
        break;
}
IFeatureSelection pFeatureSelection;
pFeatureSelection = pFeatureLayer as IFeatureSelection;
pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
ISelectionSet pFeatSet;
pFeatSet = pFeatureSelection.SelectionSet;
ICursor pCursor;
pFeatSet.Search(null, true, out pCursor);
IFeatureCursor pFeatureCursor = pCursor as IFeatureCursor;
IFeature pFeature = pFeatureCursor.NextFeature();
//遍歷所有符合要求的要素,將它們加入要素選擇集中
while (pFeature != null)
{
    //將當前的圖層加入當前圖層的要素選擇集
    pMap.SelectFeature(pFeatureLayer, pFeature);
    pFeature = pFeatureCursor.NextFeature();
}
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM