2

I am working on some .NET code that processes lots of polygon geometries at the vertex level. In order to reduce COM interop overhead, I want to call IGeometryBridge2.GetPoints once instead of calling IPointCollection.Point repeatedly:

// using ESRI.ArcGIS.Geometry;
static IPoint[] GetVertices(this IPolygon singlepartPolygon)
{
    var pointCollection = (IPointCollection4)singlepartPolygon;
    var points = new IPoint[pointCollection.PointCount];
    var geometryBridge = (IGeometryBridge2)new GeometryEnvironment();
    geometryBridge.GetPoints(pointCollection, 0, ref points);
    return points;
}

geometryBridge.GetPoints(…) throws a NotImplementedException.

(I have tried initialising the points array with empty Point instances before calling GetPoints, but this didn't make any difference. I tried geometryBridge.QueryPoints(…), too, and this failed with a different exception.)

Am I doing something wrong, or is this more likely to be a bug?

stakx
  • 1,161
  • 1
  • 11
  • 31
  • 2
    The doc implies it only works for multipoint, which kinda defeats the purpose of interface based programming. Maybe a leaky abstraction? – Kirk Kuykendall Feb 03 '13 at 04:30
  • Did you try QueryGeometries? – Kirk Kuykendall Feb 03 '13 at 04:36
  • 1
    I have found the best way to reduce COM interop overhead during vertex-heavy operations is to use the WKS structure related methods, like QueryWKSPoints, SetWKSPoints, InsertWKSPoints etc. Depends on your scenario, but the performance gain should be greater. – Petr Krebs Feb 03 '13 at 12:27
  • Not sure if it matters but try GeometryEnvironmentClass() instead of GeometryEnvironment(). That is the .NET runtime callable wrapper (RCW) for the GeometryEnvironment COM type: http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000151000000 – blah238 Feb 03 '13 at 14:06
  • @blah238: I've tried this, with no difference. – stakx Feb 03 '13 at 14:08
  • 2
    new GeometryEnvironment() is exactly the same as new GeometryEnvironmentClass(). GeometryEnvironment (which is an interface) is decorated with the CoClass attribute: CoClass(typeof(GeometryEnvironmentClass)), so that the compiler knows which class you are instantating. This is how the .NET COM type library importer converts types (for better compatibility with legacy languages and environments). – Petr Krebs Feb 04 '13 at 12:07
  • Ah, so ESRI didn't just make up that scheme? Good to know. – blah238 Feb 05 '13 at 01:06

1 Answers1

1

IGeometryBridge.QueryPoints() works for me at ArcGIS 10.1 SP1:

static IPoint[] GetVertices2(this IPolygon singlepartPolygon)
{
    var pointCollection = (IPointCollection4)singlepartPolygon;
    var points = new IPoint[pointCollection.PointCount];
    for (int i = 0; i < points.Length; i++)
    {
        points[i] = new PointClass();
    }
    var geometryBridge = (IGeometryBridge)new GeometryEnvironmentClass();
    geometryBridge.QueryPoints(pointCollection, 0, ref points);
    return points;
}
blah238
  • 35,793
  • 7
  • 94
  • 195
  • This could be due to SP1. Does it also work without the for loop, i.e. if you don't initialise the array? – stakx Feb 03 '13 at 16:31
  • It doesn't throw an exception, but the array elements are all null. – blah238 Feb 03 '13 at 16:33
  • I used LINQPad to test this, BTW, here is my query: https://gist.github.com/4702432. Tested against both .NET 3.5 and .NET 4.0. – blah238 Feb 03 '13 at 16:38
  • This answer talks about QueryPoints. Does this mean that GetPoints also didn't work for you? (Or did your Gist code which uses GetPoints work?) – stakx Feb 03 '13 at 16:38
  • 1
    Correct, as Kirk mentioned it is not implemented for anything but Multipoint geometries. – blah238 Feb 03 '13 at 16:39
  • 1
    The Gist includes both methods (QueryPoints and GetPoints) so you can test them. – blah238 Feb 03 '13 at 16:43