Come usare IRelationalOperator2 e GeometryBag


9

Voglio usare il metodo IsNear di IRelationalOperator2. La documentazione afferma che GeometryBag supporta l'interfaccia IRelationalOperator2. Ma questo non funziona e si traduce in un'eccezione "... impossibile eseguire il cast dell'oggetto COM ... Nessuna interfaccia supportata ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

Lo stesso codice funziona bene con IRelationalOperator ma non esiste un metodo IsNear:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

Cosa c'è di sbagliato: il codice, la documentazione o è un bug? "geometria" è una geometria di tipo geometrico esriGeometryBag e contiene alcune polilinee. Ho usato il cast diretto per ottenere l'eccezione .NET.


Ho dimenticato di dire che uso 10.0 SP2
Georg Haefele il

1
Questo problema esiste ancora in ArcGis 10.1 (e anche ArcGis 10.0 SP 5). Sfortunatamente nessuno ha inviato questo bug a ESRI fino ad ora, quindi ho informato il distributore locale e ESRI ha registrato il bug ora. Spero che verrà risolto con il prossimo service pack.
dpalmetz,

Risposte:


6

C'è sicuramente qualcosa di sospetto qui con 10.0 sp2.

Posso lanciare un sacchetto di geometria su IRelationalOperator2, altrimenti questo test direbbe "impossibile eseguire il cast", inoltre otterrei un'eccezione di riferimento null.

Tuttavia, alla prima chiamata a IsNear ricevo l'eccezione.

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

Ecco il test:

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

Ecco un altro test. Notare come posso trasmettere senza eccezioni, ma ottenere un'eccezione InvalidCast quando si chiama 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, ho fatto lo stesso. Il tuo test non sarà mai vero perché in questo momento "relop" ha un valore di {ESRI.ArcGIS.Geometry.GeometryBagClass} con un conteggio di 0. Il "null" o l'eccezione si verifica se si tenta di eseguire il cast di un GeometryBag reale (include dati).
Georg Haefele,

@Georg Ho aggiunto il codice che mostra come posso trasmettere una geometbagclass non vuota a IRelationalOperator2. La cosa sconcertante per me è che un'eccezione InvalidCast non viene generata quando eseguo effettivamente il cast, solo quando chiamo IsNear.
Kirk Kuykendall,

Kirk, grazie per il codice e i tuoi commenti. Posso riprodurre i tuoi risultati. Una cosa strana: dopo il cast effettivo e prima di chiamare IsNear the Locals in Visual Studio mostrano alcuni problemi per "relop" - tutte le voci IGeometry5 hanno un valore di "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx "ha generato un'eccezione di tipo" System.Invalid.CastException ". Ma l'eccezione non viene effettivamente generata. Ciò accade quando si chiama IsNear.
Georg Haefele,

Ho anche provato uno strano comportamento del cast a 10 (non sono sicuro che siano stati installati SP), questa volta con la classe VariantStreamIO. Proverò a isolare e riprodurre il problema. Se questo è un bug, è davvero serio.
Petr Krebs,

0

Immagino che si tratti di un bug con la documentazione poiché GeometryBag è una raccolta di punti / linee / poligoni. Fare alcune operazioni ITopologicalOperator su una raccolta mista e abbinata di tipi di geometria potrebbe essere impossibile. Se hai usato un IGeometryCollection di polilinee penso che la tua soluzione funzionerebbe.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.