Verwendung von IRelationalOperator2 und GeometryBag

9

Ich möchte die IsNear-Methode von IRelationalOperator2 verwenden. Die Dokumentation besagt, dass GeometryBag die IRelationalOperator2-Schnittstelle unterstützt. Dies funktioniert jedoch einfach nicht und führt zu einer Ausnahme "... COM-Objekt kann nicht umgewandelt werden ... Keine solche Schnittstelle unterstützt ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

Der gleiche Code funktioniert gut mit IRelationalOperator, aber es gibt keine IsNear-Methode:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

Was ist falsch - der Code, die Dokumentation oder ist es ein Fehler? "Geometrie" ist eine Geometrie vom Geometrietyp esriGeometryBag und enthält einige Polylinien. Ich habe die gerade Besetzung verwendet, um die .NET-Ausnahme zu erhalten.

Georg Haefele
quelle
Ich habe vergessen zu sagen, dass ich 10.0 SP2
Georg Haefele
1
Dieses Problem besteht weiterhin in ArcGis 10.1 (und auch in ArcGis 10.0 SP 5). Leider hat bis jetzt niemand diesen Fehler an ESRI gesendet, daher habe ich den lokalen Händler informiert und ESRI hat den Fehler jetzt registriert. Ich hoffe, dass es mit dem nächsten Service Pack behoben wird.
Dpalmetz

Antworten:

6

Mit 10.0 sp2 ist hier definitiv etwas faul los.

Ich kann einen Geometriebeutel in IRelationalOperator2 umwandeln, andernfalls würde dieser Test "nicht umsetzbar" bedeuten, und ich würde eine Nullreferenzausnahme erhalten.

Beim ersten Aufruf von IsNear erhalte ich jedoch die Ausnahme.

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

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

Hier ist ein weiterer Test. Beachten Sie, wie ich ohne Ausnahme umwandeln kann, aber beim Aufrufen von IsNear eine InvalidCast-Ausnahme erhalten kann.

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
quelle
Kirk, ich habe das Gleiche getan. Ihr Test wird niemals wahr sein, da "relop" zu diesem Zeitpunkt den Wert {ESRI.ArcGIS.Geometry.GeometryBagClass} mit einer Anzahl von 0 hat. Die "Null" oder die Ausnahme tritt auf, wenn Sie versuchen, einen echten GeometryBag (Includes) zu erstellen Daten).
Georg Haefele
@Georg Ich habe Code hinzugefügt, der zeigt, wie ich eine nicht leere Geometriebeutelklasse in IRelationalOperator2 umwandeln kann. Das Rätselhafte für mich ist, dass eine InvalidCast-Ausnahme nicht ausgelöst wird, wenn ich die Besetzung tatsächlich mache - nur beim Aufrufen von IsNear.
Kirk Kuykendall
Kirk, danke für den Code und deine Kommentare. Ich kann Ihre Ergebnisse reproduzieren. Eine seltsame Sache: Nach der tatsächlichen Besetzung und vor dem Aufruf von IsNear zeigen die Locals in Visual Studio einige Probleme für "relop" - alle IGeometry5-Einträge haben den Wert "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx 'hat eine Ausnahme vom Typ' System.Invalid.CastException 'ausgelöst. Die Ausnahme wird jedoch nicht ausgelöst. Dies geschieht beim Aufruf von IsNear.
Georg Haefele
Ich hatte auch ein seltsames Cast-Verhalten bei 10 (nicht sicher, ob SPs installiert waren), diesmal mit der VariantStreamIO-Klasse. Ich werde versuchen, das Problem zu isolieren und zu reproduzieren. Wenn dies ein Fehler ist, ist es in der Tat ein schwerwiegender.
Petr Krebs
0

Ich würde vermuten, dass es ein Fehler in der Dokumentation ist, da ein GeometryBag eine Sammlung von Punkten / Linien / Polygonen ist. Es kann unmöglich sein, einige ITopologicalOperator-Operationen für eine gemischte und angepasste Sammlung von Geometrietypen durchzuführen. Wenn Sie eine IGeometryCollection von Polylinien verwenden würden, würde Ihre Lösung meiner Meinung nach funktionieren.

Steve
quelle