Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Lets see if I can explain what I'm trying to do. First of all I have developed an AddIn for ArcMap that can take one selected feature (Polygon) on a layer, grab the geometry of that feature, and save it to a SQL Server database. What I would like to do is to save multiple selected features, not as individual geometries (ie. one row per feature/geometry) but as one "piece of geometry" containing the selected polygons. This is the code I have so far:

IFeatureLayer featureLayer = ArcMap.Document.CurrentContentsView.SelectedItem as IFeatureLayer;
        if (featureLayer != null)
        {
            IFeatureSelection featSel = featureLayer as IFeatureSelection;
            IEnumIDs idList = featSel.SelectionSet.IDs;

            int index = idList.Next();
            List<int> indexes = new List<int>();

            while (index != -1)
            {
                indexes.Add(index);
                index = idList.Next();
            }

            IFeatureClass featureClass = featureLayer.FeatureClass;
            IFeature feature = featureClass.GetFeature(indexes[0]);
            IGeometry geometry = feature.Shape as IGeometry;
            // Save to database
        }

As you can see I can get all the indexes of the selected features of the selected layer and get the geometry, the challenge is to "concatenate" all the geometries into one...hope it makes sense :)

Any suggestions?

P.S ...and if any of you have a better way of looping through the idList...please let me know :)

UPDATE:

A BIG thanks to Petr! Followed your instructions and it worked in the first try!

Here's the code I ended up with:

IFeatureSelection featSel = featureLayer as IFeatureSelection;

                if (featSel.SelectionSet.Count > 0)
                {
                    ITopologicalOperator resultPolygon = new Polygon() as ITopologicalOperator;
                    IGeometryCollection geometriesToUnion = new GeometryBag() as IGeometryCollection;

                    ICursor cursor;
                    featSel.SelectionSet.Search(null, false, out cursor);

                    IFeatureCursor featureCursor = cursor as IFeatureCursor;
                    IFeature feature;
                    while ((feature = featureCursor.NextFeature()) != null)
                    {
                        geometriesToUnion.AddGeometry(feature.Shape as IGeometry);
                    }

                    resultPolygon.ConstructUnion(geometriesToUnion as IEnumGeometry);

                    // Save resultPolygon to a database
                }
share|improve this question
    
Just as an aside, have you thought of making this an arcpy script? Its a much easier way of doing things. –  Hairy Dec 15 '11 at 8:49
    
@ Hairy - I have no experience with arcpy, so.... :) I can tell you though that the code above is part of an add-in that we send out to our customers. We chose the add-in because we wanted to make things as easy as possible for our customers :) –  Claus_L Dec 15 '11 at 13:21
    
Couldn't be simpler than python, one of the easiest languages I have ever used. Can be sent as a tool inside a toolbox to your clients. I'd seriously be looking at this. –  Hairy Dec 16 '11 at 8:54
add comment

1 Answer

up vote 4 down vote accepted

You can use ITopologicalOperator.ConstructUnion.

The steps would be as follows:

  1. Create an instance of the Polygon class and cast that to ITopologicalOperator. This polygon instance will contain the result.
  2. Since ITopologicalOperator.ConstructUnion takes an IEnumGeometry to specify the geometries to union (or in your words, concatenate), create an instance of GeometryBag class, which implements IEnumGeometry.
  3. Cast the geometry bag to IGeometryCollection so that you can add your source polygons to it.
  4. Pass your geometry bag to the ITopologicalOperator.ConstructUnion method on the polygon created in step 1.

As far as enumerating the selection is concerned, your method of retrieving list of IDs and getting the row for every single ID is VERY inefficient. Performance is much better if you just use IFeatureSelection.SelectionSet.Search() method. You would specify a null query filter argument when calling this method since you want all the features in the selection. The result will be a cursor which you can enumerate.

share|improve this answer
    
Thanks so much for helping a GIS newbie! Worked perfect :) –  Claus_L Dec 15 '11 at 13:29
1  
I had to set the SpatialReference on the GeometryBag before adding elements. Otherwise the ConstructUnion would fail. –  gumo Oct 1 '12 at 10:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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