Comment utiliser IRelationalOperator2 et GeometryBag

9

Je souhaite utiliser la méthode IsNear de IRelationalOperator2. La documentation indique que GeometryBag prend en charge l'interface IRelationalOperator2. Mais cela ne fonctionne tout simplement pas et entraîne une exception "... impossible de caster un objet COM ... Aucune interface de ce type n'est prise en charge ..."

IRelationalOperator2 relationalOperator = (IRelationalOperator2)geometry;

Le même code fonctionne correctement avec IRelationalOperator mais il n'y a pas de méthode IsNear:

IRelationalOperator relationalOperator = (IRelationalOperator)geometry;

Quel est le problème - le code, la documentation ou est-ce un bug? "geometry" est une géométrie de type géométrie esriGeometryBag et contient des polylignes. J'ai utilisé la distribution directe pour obtenir l'exception .NET.

Georg Haefele
la source
J'ai oublié de dire que j'utilise 10.0 SP2
Georg Haefele
1
Ce problème existe toujours dans ArcGis 10.1 (et également ArcGis 10.0 SP 5). Malheureusement, personne n'a envoyé ce bogue à ESRI jusqu'à présent, j'ai donc informé le distributeur local et ESRI a enregistré le bogue maintenant. J'espère que cela sera corrigé avec le prochain service pack.
dpalmetz

Réponses:

6

Il y a certainement quelque chose de louche ici avec 10.0 sp2.

Je peux lancer un sac de géométrie sur IRelationalOperator2, sinon ce test dirait "incapable de lancer", plus j'obtiendrais une exception de référence nulle.

Cependant, lors du premier appel à IsNear, je reçois l'exception.

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

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

Voici un autre test. Remarquez comment je peux caster sans exception, mais obtenez une exception InvalidCast lors de l'appel à 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
la source
Kirk, j'ai fait de même. Votre test ne sera jamais vrai car à ce moment "relop" a une valeur de {ESRI.ArcGIS.Geometry.GeometryBagClass} avec un compte de 0. Le "null" ou l'exception se produit si vous essayez de lancer un vrai GeometryBag (inclut Les données).
Georg Haefele
@Georg J'ai ajouté du code montrant comment je peux convertir une classe de sacs de géométrie non vide sur IRelationalOperator2. La chose déconcertante pour moi est qu'une exception InvalidCast n'est pas levée lorsque je fais le casting - uniquement lors de l'appel à IsNear.
Kirk Kuykendall
Kirk, merci pour le code et vos commentaires. Je peux reproduire vos résultats. Une chose étrange: après la conversion et avant d'appeler IsNear, les sections locales de Visual Studio présentent des problèmes pour "relop" - toutes les entrées IGeometry5 ont une valeur de "((ESRI.ArcGIS.Geometry.GeometryBagClass) (relop)). IGeometry5_xxxx "a levé une exception de type" System.Invalid.CastException ". Mais l'exception n'est pas réellement levée. Cela se produit lors de l'appel à IsNear.
Georg Haefele
J'ai également connu un comportement de distribution étrange à 10 (je ne sais pas si des SP ont été installés), cette fois avec la classe VariantStreamIO. Je vais essayer d'isoler et de reproduire le problème. S'il s'agit d'un bug, il est en effet sérieux.
Petr Krebs
0

Je suppose que c'est un bug avec la documentation car un GeometryBag est une collection de points / lignes / polygones. Il peut être impossible d'effectuer certaines opérations ITopologicalOperator sur une collection mixte et adaptée de types de géométrie. Si vous avez utilisé un IGeometryCollection de polylignes, je pense que votre solution fonctionnerait.

Steve
la source