I try to add a single buffer around the shape of the selected features. So I step through each selected feature and add it's shape to a GeometryBag
. With ITopologicalOperator2.ConstructUnion
I create a union geometry. But when I use this geometry to add an element, nothing appears after Refresh
.
The code part for adding an element does work, when I directly assign element.Geometry = feature.Shape
. So ConstructUnion
seems to fail here. Any ideas why?
I already found out, that I have to simplify the shapes before adding it to GeometryBag
and to set the SpatialReference
on the GeometryBag
before.
ESRI.ArcGIS.Carto.IGraphicsContainer graphicsContainer = (ESRI.ArcGIS.Carto.IGraphicsContainer)activeView.FocusMap;
ESRI.ArcGIS.Geodatabase.IEnumFeature enumFeature = (ESRI.ArcGIS.Geodatabase.IEnumFeature)map.FeatureSelection;
enumFeature.Reset();
ESRI.ArcGIS.Geodatabase.IFeature feature = enumFeature.Next();
IGeometryBag geoBag = new GeometryBagClass();
geoBag.SpatialReference = activeView.FocusMap.SpatialReference;
IGeometryCollection geometriesToUnion = geoBag as IGeometryCollection;
while (!(feature == null))
{
ITopologicalOperator2 shape = feature.ShapeCopy as ITopologicalOperator2;
shape.IsKnownSimple_2 = false; // see nef001's answer
shape.Simplify();
geometriesToUnion.AddGeometry(shape as IGeometry);
feature = enumFeature.Next();
}
IPolygon poly = new PolygonClass();
resultPolygon.SpatialReference = activeView.FocusMap.SpatialReference; // see Petr Krebs's comment
ITopologicalOperator2 resultPolygon = poly as ITopologicalOperator2;
resultPolygon.ConstructUnion(geometriesToUnion as IEnumGeometry);
IFillShapeElement fillShapeElement = new ESRI.ArcGIS.Carto.PolygonElementClass();
fillShapeElement.Symbol = fillSymbol;
ESRI.ArcGIS.Carto.IElement element = (IElement)fillShapeElement;
topologicalOperator = (ESRI.ArcGIS.Geometry.ITopologicalOperator)resultPolygon;
//element.Geometry = topologicalOperator.Buffer(distance);
element.Geometry = resultPolygon as IGeometry; // To make sure, it's not the Buffering that goes wrong
graphicsContainer.AddElement(element, 0);
Update: To address Petr Krebs suggestions
- I changed the assignment of
geometriesToUnion.AddGeometry
tofeature.ShapeCopy
. - I changed the assignment of
element.Geometry
to resultPolygon instead of the buffer output.
Both didn't help.
- For testing I use a single layer where I select three polygon features. So the are all polygons and have the same SpatialReference.
resultPolygon.IsEmpty
afterConstructUnion
is false.
Update 2
- Regarding Nef001's answer I added
shape.IsKnownSimple_2 = false;
but it didn't change the result.
Update 3
- Regarding Petr's answer I set the spatial reference before
Union()
but it didn't help.
ConstructUnion
? When I directly assignelement.Geometry = feature.Shape
it does work, as I pointed out. (made that more clear in the question) That's why I think it has to be something withConstructUnion
.