Como usar o IRelationalOperator2 e GeometryBag

9

Eu quero usar o método IsNear do IRelationalOperator2. A documentação diz que GeometryBag suporta a interface IRelationalOperator2. Mas isso simplesmente não funciona e resulta em uma exceção "... incapaz de converter o objeto COM ... Nenhuma interface é suportada ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

O mesmo código funciona bem com IRelationalOperator, mas não há método IsNear:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

O que está errado - o código, a documentação ou é um bug? "geometry" é uma geometria do tipo de geometria esriGeometryBag e contém algumas polilinhas. Eu usei o elenco direto para obter a exceção do .NET.

Georg Haefele
fonte
Esqueci de dizer que eu uso 10.0 SP2
Georg Haefele
11
Esse problema ainda existe no ArcGis 10.1 (e também no ArcGis 10.0 SP 5). Infelizmente, ninguém enviou esse bug para a ESRI até agora, então informei o distribuidor local e a ESRI registrou o bug agora. Espero que seja corrigido com o próximo service pack.
dpalmetz 03/09/12

Respostas:

6

Definitivamente, há algo suspeito acontecendo com o 10.0 sp2.

Posso converter um pacote de geometria para IRelationalOperator2, caso contrário, este teste diria "incapaz de converter", além de receber uma exceção de referência nula.

No entanto, na primeira chamada para IsNear, recebo a exceção.

System.InvalidCastException occurred
  Message=Unable to cast COM object of type 'ESRI.ArcGIS.Geometry.GeometryBagClass' to interface type 'ESRI.ArcGIS.Geometry.IRelationalOperator2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{839F5C7E-ED5F-4B3F-8F97-C0A9CC4817EE}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
  Source=ESRI.ArcGIS.Geometry

Aqui está o teste:

private void GBTest(IPoint pnt)
{
    // this line does not fail
    var relop = new GeometryBagClass() as IRelationalOperator2;

    if (relop == null)
        Debug.Print("unable to cast"); // this doesn't print out

    var coll = relop as IGeometryCollection;
    coll.AddGeometry(pnt);
    //((ISpatialIndex)coll).AllowIndexing = true;
    //((ISpatialIndex)coll).Invalidate();

    var pnt2 = ((IClone)pnt).Clone() as IPoint;
    ((ITransform2D)pnt2).Move(100.0, 100.0);
    if (relop.IsNear(pnt2, 1000.0)) // exception here
        Debug.Print("test 1 fail");

    if (!relop.IsNear(pnt2, 10.0))
        Debug.Print("test 2 fail");
}

Aqui está outro teste. Observe como posso transmitir sem uma exceção, mas recebo uma exceção InvalidCast ao chamar IsNear.

private void GBTest(IPoint pnt)
{
    var coll = new GeometryBagClass();
    ((IGeometry)coll).SpatialReference = pnt.SpatialReference;

    coll.AddGeometry(pnt);
    coll.GeometriesChanged();

    var relop = (IRelationalOperator2)coll; // would expect the exception here

    var pnt2 = ((IClone)pnt).Clone() as IPoint;
    ((ITransform2D)pnt2).Move(100.0, 100.0);
    if (relop.IsNear(pnt2, 1000.0)) // exception here
        Debug.Print("test 1 fail");

    if (!relop.IsNear(pnt2, 10.0))
        Debug.Print("test 2 fail");
}
Kirk Kuykendall
fonte
Kirk, eu fiz o mesmo. Seu teste nunca será verdadeiro porque, no momento, "relop" tem um valor de {ESRI.ArcGIS.Geometry.GeometryBagClass} com uma contagem de 0. O "null" ou a exceção acontece se você tentar converter um GeometryBag real (inclui dados).
Georg Haefele 18/08/11
@Georg Adicionei um código mostrando como posso converter uma geometrybagclass não vazia no IRelationalOperator2. A coisa intrigante para mim é que uma exceção InvalidCast não é lançada quando eu realmente faço o elenco - apenas quando chamo IsNear.
precisa saber é o seguinte
Kirk, obrigado pelo código e seus comentários. Eu posso reproduzir Seus resultados. Uma coisa estranha: após o elenco realmente e antes de chamar IsNear, os locais no Visual Studio mostram alguns problemas para "relop" - todas as entradas do IGeometry5 têm um valor de "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx . 'emitiu uma exceção do tipo 'System.Invalid.CastException' Mas a exceção não é realmente jogado Isso acontece quando chamando IsNear..
Georg Haefele
Também experimentei um comportamento estranho de elenco aos 10 anos (não tenho certeza se algum SP foi instalado), desta vez com a classe VariantStreamIO. Vou tentar isolar e reproduzir o problema. Se isso é um bug, é realmente sério.
precisa saber é o seguinte
0

Eu acho que é um erro com a documentação, pois um GeometryBag é uma coleção de pontos / linhas / polígonos. Realizar algumas operações do ITopologicalOperator em uma coleção mista e combinada de tipos de geometria pode ser impossível. Se você usou uma coleção de polilinhas IGeometry, acho que sua solução funcionaria.

Steve
fonte