Geometria de vários recursos selecionados em uma geometria

8

Vamos ver se consigo explicar o que estou tentando fazer. Primeiro, desenvolvi um AddIn for ArcMap que pode levar um recurso selecionado (Polygon) a uma camada, pegar a geometria desse recurso e salvá-lo em um banco de dados do SQL Server. O que eu gostaria de fazer é salvar vários recursos selecionados, não como geometrias individuais (ou seja, uma linha por recurso / geometria), mas como uma "peça de geometria" que contém os polígonos selecionados. Este é o código que tenho até agora:

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 você pode ver, posso obter todos os índices dos recursos selecionados da camada selecionada e obter a geometria, o desafio é "concatenar" todas as geometrias em uma só ... espero que faça sentido :)

Alguma sugestão?

PS ... e se algum de vocês tem uma maneira melhor de percorrer o idList ... por favor me avise :)

ATUALIZAR:

MUITO obrigado a Petr! Seguiu suas instruções e funcionou na primeira tentativa!

Aqui está o código que eu acabei com:

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
fonte
Apenas como um aparte, você já pensou em fazer disso um script arcpy? É uma maneira muito mais fácil de fazer as coisas.
Hairy
@ Cabeludo - não tenho experiência com o arcpy, então .... :) Posso dizer que o código acima faz parte de um suplemento que enviamos aos nossos clientes. Nós escolhemos o add-in, porque queríamos fazer as coisas o mais fácil possível para os nossos clientes :)
Claus_L
Não poderia ser mais simples que python, uma das linguagens mais fáceis que já usei. Pode ser enviado como uma ferramenta dentro de uma caixa de ferramentas para seus clientes. Eu seriamente olhando para isso.
18711

Respostas:

8

Você pode usar ITopologicalOperator.ConstructUnion .

As etapas seriam as seguintes:

  1. Crie uma instância da Polygonclasse e faça a conversão para ITopologicalOperator. Esta instância de polígono conterá o resultado.
  2. Desde que ITopologicalOperator.ConstructUnionleva um IEnumGeometrypara especificar as geometrias a serem unidas (ou, em suas palavras, concatenar), crie uma instância da GeometryBagclasse que implementa IEnumGeometry.
  3. Lance o saco de geometria para IGeometryCollectionque você possa adicionar seus polígonos de origem.
  4. Passe sua bolsa de geometria para o ITopologicalOperator.ConstructUnionmétodo no polígono criado na etapa 1.

No que diz respeito à enumeração da seleção, seu método de recuperar a lista de IDs e obter a linha para cada ID é MUITO ineficiente. O desempenho é muito melhor se você apenas usar o IFeatureSelection.SelectionSet.Search()método. Você especificaria um nullargumento de filtro de consulta ao chamar esse método, pois deseja todos os recursos da seleção. O resultado será um cursor que você pode enumerar.

Petr Krebs
fonte
Muito obrigado por ajudar um novato em GIS! Trabalhou perfeito :) #
1138 Claus_L
1
Eu tive que definir SpatialReferenceo GeometryBagantes de adicionar elementos. Caso contrário, ConstructUnionisso falharia.
gumo