Jak korzystać z IRelationalOperator2 i GeometryBag

9

Chcę użyć metody IsNear z IRelationalOperator2. Dokumentacja mówi, że GeometryBag obsługuje interfejs IRelationalOperator2. Ale to po prostu nie działa i powoduje wyjątek „... nie można rzutować obiektu COM ... Nie obsługuje takiego interfejsu ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

Ten sam kod działa poprawnie z IRelationalOperator, ale nie ma metody IsNear:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

Co jest nie tak - kod, dokumentacja czy błąd? „geometria” to geometria typu geometrii esriGeometryBag i zawiera pewne polilinie. Użyłem prostej rzutowania, aby uzyskać wyjątek .NET.

Georg Haefele
źródło
Zapomniałem powiedzieć, że używam 10.0 SP2
Georg Haefele
1
Ten problem nadal występuje w ArcGis 10.1 (a także ArcGis 10.0 SP 5). Niestety do tej pory nikt nie wysłał tego błędu do ESRI, więc poinformowałem lokalnego dystrybutora i ESRI zarejestrował teraz błąd. Mam nadzieję, że zostanie naprawiony w następnym pakiecie serwisowym.
dpalmetz

Odpowiedzi:

6

Na pewno dzieje się tu coś podejrzanego z 10.0 sp2.

Mogę rzucić torbę geometrii na IRelationalOperator2, w przeciwnym razie ten test powie „nie można rzucić”, a ponadto dostanę wyjątek odniesienia o wartości zerowej.

Jednak przy pierwszym wywołaniu IsNear dostaję wyjątek.

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

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

Oto kolejny test. Zwróć uwagę, jak mogę rzucać bez wyjątku, ale otrzymuję wyjątek InvalidCast podczas wywoływania 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
źródło
Kirk, zrobiłem to samo. Twój test nigdy nie będzie prawdziwy, ponieważ w tej chwili „relop” ma wartość {ESRI.ArcGIS.Geometry.GeometryBagClass} z liczbą 0. „Null” lub wyjątek występuje, jeśli spróbujesz rzucić prawdziwy GeometryBag (obejmuje dane).
Georg Haefele
@Georg Do IRelationalOperator2 dodałem kod pokazujący, jak mogę rzucić niepustą klasę geometrybagclass. Zastanawiające jest dla mnie to, że wyjątek InvalidCast nie jest zgłaszany, gdy faktycznie wykonuję rzut - tylko podczas wywoływania IsNear.
Kirk Kuykendall
Kirk, dziękuję za kod i twoje komentarze. Mogę odtworzyć Twoje wyniki. Jedna dziwna rzecz: po faktycznym rzutowaniu i przed wywołaniem IsNear the Locals w Visual Studio pokazują pewne problemy z „relopem” - wszystkie wpisy IGeometry5 mają wartość „((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx „zgłosił wyjątek typu„ System.Invalid.CastException ”. Ale wyjątek tak naprawdę nie jest zgłaszany. Dzieje się tak, gdy wywołuje się IsNear.
Georg Haefele
Doświadczyłem również dziwnego zachowania rzutowania przy 10 (nie jestem pewien, czy jakieś SP zostały zainstalowane), tym razem z klasą VariantStreamIO. Spróbuję wyizolować i odtworzyć problem. Jeśli to błąd, to naprawdę poważny.
Petr Krebs,
0

Domyślam się, że jest to błąd w dokumentacji, ponieważ GeometryBag to zbiór punktów / linii / wielokątów. Wykonanie niektórych operacji ITopologicalOperator na mieszanym i dopasowanym zbiorze typów geometrii może być niemożliwe. Jeśli użyłeś IGeometryCollection polilinii, myślę, że twoje rozwiązanie zadziałałoby.

Steve
źródło