Geometrie aus mehreren ausgewählten Features in eine Geometrie

8

Mal sehen, ob ich erklären kann, was ich versuche zu tun. Zunächst habe ich ein AddIn für ArcMap entwickelt, mit dem ein ausgewähltes Feature (Polygon) auf einer Ebene übernommen, die Geometrie dieses Features erfasst und in einer SQL Server-Datenbank gespeichert werden kann. Ich möchte mehrere ausgewählte Features speichern, nicht als einzelne Geometrien (dh eine Zeile pro Feature / Geometrie), sondern als ein "Stück Geometrie", das die ausgewählten Polygone enthält. Dies ist der Code, den ich bisher habe:

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
        }

Wie Sie sehen können, kann ich alle Indizes der ausgewählten Features der ausgewählten Ebene und die Geometrie abrufen. Die Herausforderung besteht darin, alle Geometrien zu einer "zu verketten" ... hoffe, es macht Sinn :)

Irgendwelche Vorschläge?

PS ... und wenn einer von euch eine bessere Möglichkeit hat, die IdList zu durchlaufen ... lass es mich wissen :)

AKTUALISIEREN:

Ein großes Dankeschön an Petr! Befolgen Sie Ihre Anweisungen und es hat beim ersten Versuch funktioniert!

Hier ist der Code, mit dem ich gelandet bin:

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
quelle
Haben Sie nebenbei daran gedacht, dieses Skript zu einem Arcpy-Skript zu machen? Es ist eine viel einfachere Art, Dinge zu tun.
Haarige
@ Hairy - Ich habe keine Erfahrung mit arcpy, also .... :) Ich kann Ihnen jedoch sagen, dass der obige Code Teil eines Add-Ins ist, das wir an unsere Kunden senden. Wir haben uns für das Add-In entschieden, weil wir es unseren Kunden so einfach wie möglich machen wollten :)
Claus_L
Könnte nicht einfacher sein als Python, eine der einfachsten Sprachen, die ich je benutzt habe. Kann als Tool in einer Toolbox an Ihre Kunden gesendet werden. Ich würde mir das ernsthaft ansehen.
Haarige

Antworten:

8

Sie können ITopologicalOperator.ConstructUnion verwenden .

Die Schritte wären wie folgt:

  1. Erstellen Sie eine Instanz der PolygonKlasse und wandeln Sie diese in um ITopologicalOperator. Diese Polygoninstanz enthält das Ergebnis.
  2. Da ITopologicalOperator.ConstructUnioneine nimmt IEnumGeometrydie Geometrien zur Vereinigung zu spezifizieren (oder in Ihren Worten, verketten), eine Instanz schaffen GeometryBagKlasse, die implementiert IEnumGeometry.
  3. Gießen Sie den Geometriebeutel IGeometryCollectionso, dass Sie Ihre Quellpolygone hinzufügen können.
  4. Übergeben Sie Ihren Geometriebeutel an die ITopologicalOperator.ConstructUnionMethode des in Schritt 1 erstellten Polygons.

In Bezug auf die Aufzählung der Auswahl ist Ihre Methode zum Abrufen der ID-Liste und zum Abrufen der Zeile für jede einzelne ID SEHR ineffizient. Die Leistung ist viel besser, wenn Sie nur die IFeatureSelection.SelectionSet.Search()Methode verwenden. Sie würden nullbeim Aufrufen dieser Methode ein Abfragefilterargument angeben , da Sie alle Funktionen in der Auswahl haben möchten. Das Ergebnis ist ein Cursor, den Sie aufzählen können.

Petr Krebs
quelle
Vielen Dank, dass Sie einem GIS-Neuling geholfen haben! Perfekt
funktioniert
1
Ich hatte das setzen SpatialReferenceauf dem GeometryBagvor - Elemente hinzufügen. Sonst ConstructUnionwürde das scheitern.
Gumo