Skip to content

Commit

Permalink
Don't write extent in header for single point and empty geometries
Browse files Browse the repository at this point in the history
refers to #11
  • Loading branch information
FObermaier committed Oct 31, 2024
1 parent 2370d8f commit ce67971
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 22 deletions.
46 changes: 25 additions & 21 deletions src/NetTopologySuite.IO.GeoPackage/GeoPackageGeoWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,9 @@ public void Write(Geometry geom, Stream stream)
using (var writer = new BinaryWriter(stream))
{
int byteOrder = (int)ByteOrder.LittleEndian;
int ordinates = 0;
switch (HandleOrdinates)
{
case Ordinates.None:
ordinates = 0;
break;
case Ordinates.XY:
ordinates = 1;
break;
case Ordinates.XYZ:
ordinates = 2;
break;
case Ordinates.XYM:
ordinates = 3;
break;
case Ordinates.XYZM:
ordinates = 4;
break;
}

int ordinates = GetExtentOrdinates(geom);

int isEmpty = geom.IsEmpty ? 1 : 0;
byte flags = (byte)(byteOrder + (ordinates << 1) + (isEmpty << 4));
var header = new GeoPackageBinaryHeader
Expand Down Expand Up @@ -117,12 +101,32 @@ public void Write(Geometry geom, Stream stream)
}

// NOTE: GeoPackage handles SRID in its own header. It would be invalid here.
const bool dontHandleSRID = false;
var wkbWriter = new WKBWriter(ByteOrder.LittleEndian, dontHandleSRID, emitZ, emitM);
const bool handleSRID = false;
var wkbWriter = new WKBWriter(ByteOrder.LittleEndian, handleSRID, emitZ, emitM);
wkbWriter.Write(geom, stream);
}
}

private int GetExtentOrdinates(Geometry geom)
{
if (geom.IsEmpty || geom.OgcGeometryType == OgcGeometryType.Point)
return 0;

switch (HandleOrdinates)
{
case Ordinates.XY:
return 1;
case Ordinates.XYZ:
return 2;
case Ordinates.XYM:
return 3;
case Ordinates.XYZM:
return 4;
}

return 0;
}

/// <summary>
/// Serializes a given <see cref="Geometry"/> to a new byte array.
/// </summary>
Expand Down
39 changes: 39 additions & 0 deletions test/NetTopologySuite.IO.SpatiaLite.Test/Issue11.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using NetTopologySuite;
using NetTopologySuite.Geometries;
using NetTopologySuite.IO;
using NUnit.Framework;

namespace NetTopologySuite.IO.SpatiaLite.Test;

class Issue11
{
[TestCase("POINT EMPTY", 17)]
[TestCase("POINT(10 10)", 1)]
[TestCase("POINT Z(10 10 1)", 1)]
[TestCase("POINT M(10 10 2)", 1)]
[TestCase("POINT ZM(10 10 1 2)", 1)]
[TestCase("POINT(10 10)", 1)]
[TestCase("LINESTRING EMPTY", 17)]
[TestCase("LINESTRING(10 10, 10 20)", 3)]
[TestCase("LINESTRING Z(10 10 1, 10 20 1)", 3)]
[TestCase("LINESTRING M(10 10 2, 10 20 2)", 3)]
[TestCase("LINESTRING ZM(10 10 1 2, 10 20 1 2)", 3)]
public void TestHeaderFlags(string wkt, byte expectedFlags)
{
var factory = NtsGeometryServices.Instance.CreateGeometryFactory();
var wktReader = new WKTReader() { IsOldNtsCoordinateSyntaxAllowed = false };
var geom = wktReader.Read(wkt);
var writer = new GeoPackageGeoWriter
{
HandleOrdinates = Ordinates.None
};
byte[] s = writer.Write(geom);

Assert.That(s[3], Is.EqualTo(expectedFlags));

var reader = new GeoPackageGeoReader(factory.CoordinateSequenceFactory, factory.PrecisionModel);
var dgeom = reader.Read(s);
Assert.That(dgeom, Is.EqualTo(geom));
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net8</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit ce67971

Please sign in to comment.