如何使用IRelationalOperator2和GeometryBag


9

我想使用IRelationalOperator2的IsNear方法。该文档说,GeometryBag支持IRelationalOperator2接口。但这是行不通的,并导致异常 “ ...无法强制转换COM对象...不支持此类接口...”

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

相同的代码可以与IRelationalOperator一起正常工作,但是没有IsNear方法:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

有什么问题-代码,文档还是错误?“ geometry”是几何类型为esriGeometryBag的几何,包含一些折线。我使用直接转换来获取.NET异常。


我忘了说我使用的是10.0 SP2
Georg Haefele 2011年

1
ArcGis 10.1(以及ArcGis 10.0 SP 5)中仍然存在此问题。不幸的是,到目前为止,还没有人将此错误发送给ESRI,因此我通知了本地发行商,ESRI现在注册了该错误。我希望它将在下一个Service Pack中得到修复。
dpalmetz 2012年

Answers:


6

10.0 sp2肯定有什么不对劲。

我可以将几何包投射到IRelationalOperator2上,否则此测试将显示“无法投射”,再加上一个空引用异常。

但是,在第一次调用IsNear时,出现了异常。

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

这是测试:

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

这是另一个测试。请注意,如何在没有异常的情况下进行转换,但是在调用IsNear时会收到InvalidCast异常。

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

柯克,我也一样。您的测试将永远是不正确的,因为此时“ relop”的值为{ESRI.ArcGIS.Geometry.GeometryBagClass},计数为0。如果您尝试投射真实的GeometryBag(包括数据)。
Georg Haefele 2011年

@Georg我添加了代码,展示了如何将非空geometrybagclass强制转换为IRelationalOperator2。让我感到困惑的是,当我实际执行强制转换时,不会抛出InvalidCast异常-仅在调用IsNear时才会发生。
Kirk Kuykendall,

柯克,谢谢你的代码和你的评论。我可以复制您的结果。一件奇怪的事:在实际转换之后,在调用IsNear之前,Visual Studio中的Locals显示“重排”问题-所有IGeometry5-Entries的值均为“(((ESRI.ArcGIS.Geometry.GeometryBagClass)(relop))。IGeometry5_xxxx '扔类型的异常‘System.Invalid.CastException’但例外是不实际抛出这种情况叫IsNear时。
格奥尔格·Haefele的

这次使用VariantStreamIO类时,我还经历了10点时的奇怪转换行为(不确定是否安装了任何SP)。我将尝试隔离并重现该问题。如果这是一个错误,那确实是一个严重的错误。
Petr Krebs

0

我猜这是文档中的一个错误,因为GeometryBag是点/线/多边形的集合。在混合和匹配的几何类型集合上执行一些ITopologicalOperator操作可能是不可能的。如果我使用折线的IGeometryCollection,尽管我认为您的解决方案会起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.