[GIS] How to find polygon neighbors by rook and queen contiguity in a feature class

arcmaparcobjectsc

I have a feature class containing several polygons. I would like to find all polygons that have a common border to a polygon of my choice. This can be done with the ISpatialFilter and esriSpatialTouches. This is known as the queen contiguity. However, the rook contiguity does not contain the polygons, which have only a point in common. It seems that this is something I can not figure out with the DE-9IM.

My idea is to test all polygons which touches my selected polygon with the Intersect method from the ITopologicalOperator interface and see if the result is from the type Point. If this is the case I have to remove this polygon.

Is there a better way to achieve this?

Best Answer

The following code works for me.

private IDictionary<int, List<int>> BuildDictioninaryOfRookContiguity()
    {
        IDictionary<int, List<int>> neighborDictionary = new Dictionary<int, List<int>>();

        using (ComReleaser comReleaser = new ComReleaser())
        {
            IFeatureCursor featureCursor = (IFeatureCursor)_featureClass.Search(null, false);

            comReleaser.ManageLifetime(featureCursor);

            IFeature currentFeature;
            while ((currentFeature = featureCursor.NextFeature()) != null)
            {
                ISpatialFilter spatialFilter = new SpatialFilterClass();
                spatialFilter.Geometry = currentFeature.Shape;
                spatialFilter.GeometryField = _featureClass.ShapeFieldName;
                spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;

                ISelectionSet selectionSet = _featureClass.Select(spatialFilter,
                    esriSelectionType.esriSelectionTypeIDSet,
                    esriSelectionOption.esriSelectionOptionNormal, null);

                ITopologicalOperator topologicalOperator = (ITopologicalOperator) currentFeature.Shape;

                List<int> neighborIDs = new List<int>(selectionSet.Count);

                IEnumIDs enumIDs = selectionSet.IDs;

                int ID = enumIDs.Next();

                while (ID != -1)
                {
                    IPointCollection pointCollection = (IPointCollection) topologicalOperator.Intersect(_featureClass.GetFeature(ID).Shape, esriGeometryDimension.esriGeometry0Dimension);

                    if(!(pointCollection.PointCount == 1))
                        neighborIDs.Add(ID);

                    ID = enumIDs.Next();
                }

                neighborDictionary.Add(currentFeature.OID, neighborIDs);                 
            }
        }

        return neighborDictionary;
    }
Related Question