0

I am creating a C# addin for ArcGIS Desktop, where one of the functions is to create a feature from the difference between 2 other features.

In the image below, I want to be able to create a new feature from the difference between either the red and blue polygon or the green and blue polygon (the user will be able to select which on they want to work with).enter image description here

I have the following code

        ####ADDED CODE#####
        IQueryFilter qf = new QueryFilterClass();
        qf.WhereClause = "CHANGEREFERENCE = '" + cmbDropdownFeatImp.SelectedItem.ToString() + "'";
        IFeatureCursor featureSUOCursor = fcSUOPending.Search(qf, false);
IFeature featureSUO = featureSUOCursor.NextFeature();

        IFeature mergedSUOFeature = null;
        while (featureSUO != null)
        {
            //MessageBox.Show(featureSUO.get_Value(featureSUO.Fields.FindField("CHANGEREFERENCE")).ToString());
            mergedSUOFeature = featureSUO;

            featureSUO = featureSUOCursor.NextFeature();
        }
        ####ADDED CODE#####
            //select all the highways polygons that are intersected by the selected geometry
            ISpatialFilter spaFil = new SpatialFilterClass();
            spaFil.Geometry = mergedSUOFeature.Shape;
            spaFil.GeometryField = publicHighwaysFC.ShapeFieldName;
            spaFil.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            //query the results from the spatial filter
            IFeatureCursor geomCursor = publicHighwaysFC.Update(spaFil, false);
            IFeature geomFeat = geomCursor.NextFeature();
            //insert the new feature
            IFeatureCursor insertPHCursor = publicHighwaysFC.Insert(true);
            IFeature insertPHFeature;
            IGeometry newPHShape;
            ITopologicalOperator2 topoOp;

            while (geomFeat != null)
            {
                topoOp = mergedSUOFeature.Shape as ITopologicalOperator2;
                newPHShape = topoOp.Difference(geomFeat.Shape);
             //add the feature as a graphic for this example
             .....
             }

If I select the green polygon and run the above code, I get the the difference between that feature and the blue feature as a brand new feature in purple), which works perfectly and what I want enter image description here

However, if I select the red feature (which is a mutipart feature), when the same code is run the following happens enter image description here It seems that the if the feature is a multipart polygon, it does not create a difference. So my question is, what is the best way to get the difference between features regardless of whether it is a multipart feature or a single feature?

  • From the code you have provided nothing appears wrong. The ITopologicalOperator.Difference function does work on multi-part features. Run Repair Geometry and make sure the features spatial references are the same. Otherwise I think you'll need to post some more code if you want better answers. – danielm Aug 28 at 21:23
  • @danielm, the data is in oracle so the repair geometry wont work, all layers have the same spatial reference. As for the code, i've added the bit where the feature i selected. Apart from that the code is as is. – MapMan Aug 29 at 8:56
  • 1
    Are you certain that your geomCursor is returning the blue feature that you think it is? In both the Red and Green case the first polygon selected is likely the rightmost blue feature. esriSpatialRelIntersects indicates any spatial relationship, esriSpatialRelOverlaps may give you a better result. – danielm Aug 29 at 18:04
  • @danielm Yes, you are correct, using the esriSpatialRelIntersects, geomCursor was the rightmost blue feature. Using esriSpatialRelOverlaps, the correct blue feature was returned. – MapMan Aug 30 at 10:54
  • I have moved these comments to an answer. – danielm Aug 30 at 20:02
2

ITopologicalOperator.Difference is behaving correctly. The issue is that the SpatialQuery is not returning the expected feature. The following query returns at least two if not all three blue features in the screenshot above:

ISpatialFilter spaFil = new SpatialFilterClass();
spaFil.Geometry = mergedSUOFeature.Shape;
spaFil.GeometryField = publicHighwaysFC.ShapeFieldName;
spaFil.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

Changing it to this will return the expected feature:

spaFil.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;

The reason is esriSpatialRelIntersects returns features with any spatial relationship (in this case feature edges touching one another). What you want is esriSpatialRelOverlaps which will only return features where the the intersection of two polygons is also a polygon.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.