Geometría de múltiples entidades seleccionadas en una geometría

8

Veamos si puedo explicar lo que estoy tratando de hacer. En primer lugar, he desarrollado un complemento para ArcMap que puede tomar una entidad seleccionada (Polígono) en una capa, tomar la geometría de esa entidad y guardarla en una base de datos de SQL Server. Lo que me gustaría hacer es guardar varias entidades seleccionadas, no como geometrías individuales (es decir, una fila por entidad / geometría) sino como una "pieza de geometría" que contiene los polígonos seleccionados. Este es el código que tengo hasta ahora:

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
        }

Como puede ver, puedo obtener todos los índices de las características seleccionadas de la capa seleccionada y obtener la geometría, el desafío es "concatenar" todas las geometrías en una ... espero que tenga sentido :)

¿Alguna sugerencia?

PD ... y si alguno de ustedes tiene una mejor manera de recorrer la idList ... hágamelo saber :)

ACTUALIZAR:

¡Muchas gracias a Petr! ¡Seguí tus instrucciones y funcionó en el primer intento!

Aquí está el código con el que terminé:

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
                }
Claus_L
fuente
Solo como un aparte, ¿has pensado en hacer de este un script arcpy? Es una forma mucho más fácil de hacer las cosas.
Peludo
@ Hairy: no tengo experiencia con arcpy, así que ... :) Puedo decirte que el código anterior es parte de un complemento que enviamos a nuestros clientes. Elegimos el complemento porque queríamos hacer las cosas lo más fáciles posible para nuestros clientes :)
Claus_L
No podría ser más simple que Python, uno de los lenguajes más fáciles que he usado. Se puede enviar como herramienta dentro de una caja de herramientas a sus clientes. En serio estaría mirando esto.
Peludo

Respuestas:

8

Puede usar ITopologicalOperator.ConstructUnion .

Los pasos serían los siguientes:

  1. Crea una instancia de la Polygonclase y envía eso a ITopologicalOperator. Esta instancia de polígono contendrá el resultado.
  2. Como se ITopologicalOperator.ConstructUnionnecesita IEnumGeometrypara especificar las geometrías a la unión (o en sus palabras, concatenar), cree una instancia de GeometryBagclase, que implemente IEnumGeometry.
  3. Lanza la bolsa de geometría para IGeometryCollectionque puedas agregarle tus polígonos de origen.
  4. Pase su bolsa de geometría al ITopologicalOperator.ConstructUnionmétodo en el polígono creado en el paso 1.

En lo que respecta a enumerar la selección, su método de recuperar la lista de ID y obtener la fila para cada ID es MUY ineficiente. El rendimiento es mucho mejor si solo usa el IFeatureSelection.SelectionSet.Search()método. Debería especificar un nullargumento de filtro de consulta al llamar a este método ya que desea todas las características en la selección. El resultado será un cursor que puede enumerar.

Petr Krebs
fuente
¡Muchas gracias por ayudar a un novato en SIG! Trabajó perfecto :)
Claus_L
1
Tuve que configurar el SpatialReferenceen GeometryBagantes de agregar elementos. De lo contrario ConstructUnion, fallaría.
gumo