xbikuna / nettopologysuite

Automatically exported from code.google.com/p/nettopologysuite
0 stars 0 forks source link

WKBWriter, extra bytes being added to Polygon geometry #147

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create NetTopologySuite.Geometries.Polygon
2. Use NetTopologySuite.IO.WKBWriter to write geometry to byte array
3. Compare byte array of WKBWriter to bytes generated using another method.

What is the expected output? What do you see instead?
Compare SQL Server Binary Output for a geometry vs. NTS WKBWriter Binary Output 
which adds extra bytes.

See below for details.

What version of the product are you using? On what operating system?
Windows 7, VisualStudio 2010, C#, .NET 4.0

Please provide any additional information below.

----SQL Server Express 2012--

DECLARE
@WKT varchar(255) = 'POLYGON ((-94.16 42.25, -94.15 42.26, -94.14 42.25, -94.16 
42.25))',
@WKB varbinary(max),
@SRID int = 0,
@Geometry1 geometry,
@Geometry2 geometry
SET @Geometry1 = geometry::STGeomFromText(@WKT, @SRID)
SET @WKB = @Geometry1.STAsBinary()
SELECT
@Geometry1.STAsText(),
@WKB

Binary Output:
0x010300000001000000040000000AD7A3703D8A57C000000000002045409A999999998957C0E17A
14AE47214540295C8FC2F58857C000000000002045400AD7A3703D8A57C00000000000204540

--C# ---

//Geom is same as above, full code sample below.

WKBWriter writer = new 
NetTopologySuite.IO.WKBWriter(GeoAPI.IO.ByteOrder.LittleEndian,false,false, 
false);           
byte[] wkb = writer.Write(geom);

Binary Output:
0x010300000001000000040000000AD7A3703D8A57C000000000002045409A999999998957C0E17A
14AE47214540295C8FC2F58857C000000000002045400AD7A3703D8A57C000000000002045400000
0000

This causes an the error: "The well-known binary (WKB) input is not valid." 
when trying to read the WKB stored in a varbinary(max) field and using SQL 
Server STGeomFromWKB functions to read back to WKT.

Removing 4 bytes prior to writing to the database will create a valid geometry. 
It looks like 4 bytes are being added when the WKBWriter is used
to write a Polygon geometry. This doesn't happen when writing Points or 
LineStrings.

     public ActionResult AddPractice(SDC_ClientProject project) {
            try
            {

                var sr_102100 = ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator;
                var sr_4326 = ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84;
                ICoordinateTransformation trans = new CoordinateTransformationFactory().CreateFromCoordinateSystems(sr_102100, sr_4326);

                IGeometryFactory gfactory = GeometryFactory.Default;

                NetTopologySuite.IO.GeoJsonReader reader = new NetTopologySuite.IO.GeoJsonReader();
                StringReader sr = new StringReader(project.GeomAsJSON);
                var geomjson = new GeoJsonSerializer();
                var json = (JObject) geomjson.Deserialize(new Newtonsoft.Json.JsonTextReader(sr));

                NetTopologySuite.Geometries.Geometry geom;

                var geomtype = json.Value<string>("type");
                switch (geomtype) { 
                    case "Point":
                        geom = reader.Read<NetTopologySuite.Geometries.Point>(project.GeomAsJSON);            
                        IPoint pgeom = GeometryTransform.TransformPoint(gfactory,(IPoint)geom, trans.MathTransform);
                        geom = (Point)pgeom;
                        break;
                    case "LineString":
                        geom = reader.Read<NetTopologySuite.Geometries.LineString>(project.GeomAsJSON);
                        ILineString lgeom = GeometryTransform.TransformLineString(gfactory,(ILineString)geom, trans.MathTransform);
                        geom = (LineString)lgeom;
                        break;
                    case "Polygon":
                        geom = reader.Read<NetTopologySuite.Geometries.Polygon>(project.GeomAsJSON);
                        IPolygon tgeom = GeometryTransform.TransformPolygon(gfactory,(IPolygon)geom,trans.MathTransform);
                        geom = (Polygon)tgeom;
                        break;
                    default:
                        throw new InvalidOperationException();
                }

                WKBWriter writer = new NetTopologySuite.IO.WKBWriter(GeoAPI.IO.ByteOrder.LittleEndian,false,false, false);           
                byte[] wkb = writer.Write(geom);
                Array.Copy(wkb,wkb,wkb.Length - 4);
                Array.Resize(ref wkb, wkb.Length - 4);

                //Not needed only, visualize the bytes.
                //var wkbhex = WKBWriter.ToHex(wkb);
                //project.GeomAsJSON = wkbhex;

                project.GeomAsWKB = wkb;
            }
            catch (NetTopologySuite.Utilities.AssertionFailedException err) {
                System.Console.WriteLine(err);
            }

Original issue reported on code.google.com by raptick on 19 Apr 2013 at 7:59

GoogleCodeExporter commented 8 years ago
Fixed as of rev 1043

Original comment by felix.ob...@netcologne.de on 24 Jun 2013 at 11:48