diff --git a/MEOS.NET.Tests/ExtendedWkbTests.cs b/MEOS.NET.Tests/ExtendedWkbTests.cs new file mode 100644 index 0000000..8ad4b43 --- /dev/null +++ b/MEOS.NET.Tests/ExtendedWkbTests.cs @@ -0,0 +1,39 @@ +using MEOS.NET.Types; + +namespace MEOS.NET.Tests +{ + /// + /// The extended WKB of a geometry is a buffer whose length MEOS states + /// through a pointer, so the array a caller gets is exactly as long as the + /// data — which the hex form of the same value states independently. + /// + [TestClass] + public class ExtendedWkbTests : MeosTest + { + private const string Line = "SRID=4326;LINESTRING(1 1, 2 2, 3 4)"; + + [TestMethod] + public void TheBufferIsAsLongAsTheHexFormSays() + { + Geo line = Geometry.In(Line, -1)!; + + byte[]? ewkb = line.AsEWKB("ndr"); + string hex = line.AsHexewkb("ndr"); + + Assert.IsNotNull(ewkb); + Assert.AreEqual(hex.Length, ewkb!.Length * 2); + Assert.AreEqual(hex.ToUpperInvariant(), Convert.ToHexString(ewkb)); + } + + [TestMethod] + public void AGeometryRoundTripsThroughItsOwnEWKB() + { + Geo line = Geometry.In(Line, -1)!; + + Geo? read = Geo.FromEWKB(line.AsEWKB("ndr")!, 4326); + + Assert.IsNotNull(read); + Assert.AreEqual(line.ToString(), read!.ToString()); + } + } +} diff --git a/MEOS.NET/Types/Geo.g.cs b/MEOS.NET/Types/Geo.g.cs index 266d0e7..0b31382 100644 --- a/MEOS.NET/Types/Geo.g.cs +++ b/MEOS.NET/Types/Geo.g.cs @@ -18,6 +18,27 @@ internal Geo(IntPtr ptr) : base(ptr) { } public override string ToString() => this.Out(); + public byte[]? AsEWKB(string endian) + { + IntPtr _size = Marshal.AllocHGlobal(sizeof(long)); + try + { + IntPtr _bytes = Meos.GeoAsEwkb(this.Ptr, endian, _size); + if (_bytes == IntPtr.Zero) + { + return null; + } + + byte[] _wkb = new byte[Marshal.ReadInt64(_size)]; + Marshal.Copy(_bytes, _wkb, 0, _wkb.Length); + return _wkb; + } + finally + { + Marshal.FreeHGlobal(_size); + } + } + public string AsEWKT(int precision) => Meos.GeoAsEwkt(this.Ptr, precision);