3

ArcObjects provides an interface named IWkb for obtaining a WKB representation of a geometry. Generally, you can cast a geometry object to it:

// WKB representation of POLYGON((0 0,1 0,1 1,0 1,0 0))
byte[] wkb = Convert.FromBase64String("AQMAAAABAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAAAAAAAAAAAAAAAA");

IGeometry g;
int bytesRead;
IGeometryFactory factory = new GeometryEnvironmentClass(wkb, out g, out bytesRead);

System.Diagnostics.Debug.WriteLine(g);
// Output: System.__ComObject
System.Diagnostics.Debug.WriteLine((IWkb)g);
// Output: System.__ComObject
System.Diagnostics.Debug.WriteLine("Yes, the cast is valid");
// Just verifies we got past the cast without error.

However, the signature of IWkb.ExportToWkb doesn't seem to make sense. The docs show takes two parameters:

  • ref int byteCountInOut
  • ref Byte& byteBuffer

There are three things that don't make any sense:

  • I know ref means that it takes an incoming value and might modify that value to also use for output, but sending input for these variables doesn't make sense; I'm trying to get output from them.
  • byteBuffer is of type Byte& according to the docs, but that trailing & doesn't appear to be valid C# syntax.
  • When I look at the generated metadata for the method in Visual Studio, it shows that byteBuffer's declaration is actually out byte byteBuffer. It being an out parameter makes more sense than it being ref, but the fact it's byte makes even less sense. A WKB consists of many bytes, so it needs to be some data type that allows for that.

How is this method supposed to be used? Do I need to use some kind of loop to get one byte at a time; if so, how? Is there a better interface for getting the WKB form of a geometry?

3

You could also use GeometryEnvironment using an IGeometryFactory interface:

/// <summary>
/// Converts geometry into WKB
/// </summary>
/// <param name="geometry">The geometry.</param>
/// <returns>byte array of a WKB geometry</returns>
public static byte[] ToWKB(this IGeometry geometry)
{
    IWkb wkb = geometry as IWkb;
    ITopologicalOperator oper = geometry as ITopologicalOperator;
    oper.Simplify();

    IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
    byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[];
    return b;
}
  • Geez. I even looked on that class and completely missed it. Any particular reason for the Simplify call? – jpmc26 Oct 18 '18 at 19:59
  • I don't remember because it was 6 years ago, but if I had to guess--the CreateWkbVariantFromGeometry probably didn't like non simple geometry that was being passed in. So I simplified it. I originally wrote the code for a 10.1 AddIn--so it might not be needed any longer. – Jay Cummins Oct 18 '18 at 20:14
3

The method seems to use a C like definition for passing arrays where you need to pass a pointer to the first element of an array as well as the number of elements in that array. The documentation may be weird because of how the value is being marshaled to the native COM object in the RCW. It will will likely be marshaled as a pointer to the beginning of your array.

You would then use it like this, I think:

IWkb wkb = g as IWkb;
byte[] bytes = new byte[wkb.WkbSize];
wkb.ExportToWkb(wkb.WkbSize, out b[0]);

Note that the first parameter doesn't have to be passed with the ref keyword (though it's fine if you do). Another oddity, that I've found difficult finding an answer for.

  • Thank you. That does seem to be in line with what I'm seeing elsewhere, even though it is really weird. I'm not even sure if modifying an array that way with C# would work, off hand, but whatever it's doing under the hood seems to work. Talk about going outside the norms of the language. – jpmc26 Oct 18 '18 at 20:01
  • The .NET aspect is just a wrapper for native code which are underlying COM objects. The wrapper may make use of the 'fixed' keyword and unsafe code so that a pointer can be passed. Or at least something similar to that is happening, I don't like digging too much into COM interop if I can help it. – danielm Oct 18 '18 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.