Cómo usar IRelationalOperator2 y GeometryBag

9

Quiero usar el método IsNear de IRelationalOperator2. La documentación dice que GeometryBag es compatible con la interfaz IRelationalOperator2. Pero esto simplemente no funciona y da como resultado una excepción "... no se puede lanzar un objeto COM ... No se admite dicha interfaz ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

El mismo código funciona bien con IRelationalOperator pero no hay un método IsNear:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

¿Qué está mal? ¿El código, la documentación o es un error? "geometry" es una geometría de tipo geometría esriGeometryBag y contiene algunas polilíneas. Usé el elenco directo para obtener la excepción .NET.

Georg Haefele
fuente
Olvidé decir que uso 10.0 SP2
Georg Haefele
1
Este problema todavía existe en ArcGis 10.1 (y también ArcGis 10.0 SP 5). Desafortunadamente, nadie envió este error a ESRI hasta ahora, así que informé al distribuidor local y ESRI lo registró ahora. Espero que se solucione con el próximo service pack.
dpalmetz

Respuestas:

6

Definitivamente hay algo sospechoso aquí con 10.0 sp2.

Puedo lanzar una bolsa de geometría a IRelationalOperator2, de lo contrario esta prueba diría "no se puede lanzar", además obtendría una excepción de referencia nula.

Sin embargo, en la primera llamada a IsNear recibo la excepción.

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

Aquí está la prueba:

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");
}

Aquí hay otra prueba. Observe cómo puedo enviar contenido sin una excepción, pero obtenga una excepción InvalidCast cuando llame a 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
fuente
Kirk, hice lo mismo. Su prueba nunca será verdadera porque en este momento "relop" tiene un valor de {ESRI.ArcGIS.Geometry.GeometryBagClass} con un recuento de 0. El "nulo" o la excepción ocurre si intenta lanzar un GeometryBag real (incluye datos).
Georg Haefele
@ Georgia Agregué un código que muestra cómo puedo lanzar una clase de geometría no vacía a IRelationalOperator2. Lo más sorprendente para mí es que no se produce una excepción InvalidCast cuando realmente realizo el lanzamiento, solo cuando llamo a IsNear.
Kirk Kuykendall
Kirk, gracias por el código y tus comentarios. Puedo reproducir tus resultados. Una cosa extraña: después de la conversión real y antes de llamar a IsNear the Locals en Visual Studio muestra algunos problemas para "relop": todas las entradas IGeometry5 tienen un valor de "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx 'arrojó una excepción de tipo' System.Invalid.CastException '. Pero la excepción no se produce realmente. Esto sucede cuando se llama a IsNear.
Georg Haefele
También experimenté un comportamiento de lanzamiento extraño a las 10 (no estoy seguro si se instalaron SP), esta vez con la clase VariantStreamIO. Intentaré aislar y reproducir el problema. Si esto es un error, de hecho es grave.
Petr Krebs
0

Supongo que es un error con la documentación ya que GeometryBag es una colección de puntos / líneas / polígonos. Hacer algunas operaciones de ITopologicalOperator en una colección mixta y combinada de tipos de geometría podría ser imposible. Si usó una colección de polilíneas IGeometryCollection, creo que su solución funcionaría.

Steve
fuente