IRelationalOperator2 및 GeometryBag 사용 방법


9

IRelationalOperator2의 IsNear 메서드를 사용하고 싶습니다. 문서는 GeometryBag가 IRelationalOperator2 인터페이스를 지원하는 것을 말한다. 그러나 이것은 작동하지 않으며 예외가 발생합니다. "... COM 개체를 캐스팅 할 수 없습니다 ... 해당 인터페이스가 지원되지 않습니다 ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

동일한 코드가 IRelationalOperator에서도 제대로 작동하지만 IsNear 메서드는 없습니다.

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

무엇이 잘못 되었습니까? 코드, 문서 또는 버그입니까? "geometry"는 기하학 유형 esriGeometryBag 의 기하학 이며 일부 폴리 라인을 포함합니다. .NET 예외를 얻기 위해 스트레이트 캐스트를 사용했습니다.



1
이 문제는 여전히 ArcGis 10.1 (및 ArcGis 10.0 SP 5)에도 존재합니다. 안타깝게도 지금까지 아무도이 버그를 ESRI에 보내지 않았으므로 현지 대리점에 알리고 ESRI가 버그를 등록했습니다. 다음 서비스 팩으로 수정되기를 바랍니다.
dpalmetz

답변:


6

10.0 sp2로 확실히 뭔가 비린내가 있습니다.

지오메트리 백을 IRelationalOperator2에 캐스트 할 수 있습니다. 그렇지 않으면이 테스트에서 "캐스팅 할 수 없습니다"라고 표시되고 null 참조 예외가 발생합니다.

그러나 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"의 값이 0으로 카운트 된 {ESRI.ArcGIS.Geometry.GeometryBagClass}의 값을 가지므로 테스트는 사실이 아닙니다. "null"또는 실제 GeometryBag를 캐스팅하려고하면 예외가 발생합니다 (포함 데이터).
Georg Haefele

@Georg 비어 있지 않은 geometrybagclass를 IRelationalOperator2에 캐스팅하는 방법을 보여주는 코드를 추가했습니다. 당황스러운 것은 실제로 캐스팅을 할 때 InvalidCast 예외가 발생하지 않으며 IsNear를 호출 할 때만 발생한다는 것입니다.
Kirk Kuykendall

커크, 코드와 의견에 감사드립니다. 결과를 재현 할 수 있습니다. 한 가지 이상한 점 : 실제로 캐스팅 한 후 IsNear를 호출하기 전에 Visual Studio의 Locals에서 "relop"에 대한 문제가 표시됩니다. 모든 IGeometry5-Entries의 값은 "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx ''System.Invalid.CastException '유형의 예외가 발생했지만 실제로 예외는 발생하지 않습니다. 이것은 IsNear를 호출 할 때 발생합니다.
Georg Haefele

또한 이번에는 VariantStreamIO 클래스를 사용하여 10에서 이상한 캐스트 동작이 발생했습니다 (SP가 설치되어 있는지 확실하지 않음). 나는 문제를 격리하고 재현하려고 노력할 것이다. 이것이 버그라면 실제로 심각한 버그입니다.
Petr Krebs

0

GeometryBag는 점 / 선 / 다각형의 모음이므로 설명서에 버그가 있다고 생각합니다. 혼합되고 일치하는 지오메트리 유형 모음에서 일부 ITopologicalOperator 작업을 수행하는 것은 불가능할 수 있습니다. 폴리 라인의 IGeometryCollection을 사용하면 솔루션이 효과가 있다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.