Skip to content

Commit b18dd17

Browse files
Respect handleOrdinates also when writing geometry (#6380)
1 parent 977e835 commit b18dd17

2 files changed

Lines changed: 85 additions & 1 deletion

File tree

src/Npgsql.NetTopologySuite/Internal/NetTopologySuiteTypeInfoResolverFactory.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ sealed class NetTopologySuiteTypeInfoResolverFactory(
2020
class Resolver : IPgTypeInfoResolver
2121
{
2222
readonly PostGisReader _gisReader;
23+
readonly PostGisWriter _gisWriter;
2324
protected readonly bool _geographyAsDefault;
2425

2526
TypeInfoMappingCollection? _mappings;
26-
protected TypeInfoMappingCollection Mappings => _mappings ??= AddMappings(new(), _gisReader, new(), _geographyAsDefault);
27+
protected TypeInfoMappingCollection Mappings => _mappings ??= AddMappings(new(), _gisReader, _gisWriter, _geographyAsDefault);
2728

2829
public Resolver(
2930
CoordinateSequenceFactory? coordinateSequenceFactory,
@@ -37,6 +38,10 @@ public Resolver(
3738

3839
_geographyAsDefault = geographyAsDefault;
3940
_gisReader = new PostGisReader(coordinateSequenceFactory, precisionModel, handleOrdinates);
41+
_gisWriter = new PostGisWriter
42+
{
43+
HandleOrdinates = handleOrdinates
44+
};
4045
}
4146

4247
public PgTypeInfo? GetTypeInfo(Type? type, DataTypeName? dataTypeName, PgSerializerOptions options)

test/Npgsql.PluginTests/NetTopologySuiteTests.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,85 @@ public async Task Write(Ordinates ordinates, Geometry geometry, string sqlRepres
150150
Assert.That(cmd.ExecuteScalar(), Is.True);
151151
}
152152

153+
[Test]
154+
public async Task ReadWithHandleOrdinatesXY_FiltersZCoordinate()
155+
{
156+
// This test verifies that handleOrdinates IS respected during read operations
157+
await using var conn = await OpenConnectionAsync(handleOrdinates: Ordinates.XY);
158+
await using var cmd = conn.CreateCommand();
159+
cmd.CommandText = "SELECT ST_MakePoint(1, 2, 3)"; // Create a 3D point in SQL
160+
161+
var result = (Point)cmd.ExecuteScalar()!;
162+
163+
// The Z coordinate should be filtered out during reading based on handleOrdinates: XY
164+
Assert.That(result.CoordinateSequence.HasZ, Is.False,
165+
"Z coordinate was correctly filtered during read");
166+
Assert.That(result.X, Is.EqualTo(1d));
167+
Assert.That(result.Y, Is.EqualTo(2d));
168+
Assert.That(result.Z, Is.NaN, "Z coordinate should be NaN when filtered out");
169+
}
170+
171+
[Test]
172+
public async Task WriteWithHandleOrdinatesXY_ShouldFilterZCoordinate()
173+
{
174+
// This test verifies that when handleOrdinates is set to XY,
175+
// Z coordinates are correctly filtered out during write operations.
176+
var pointWithZ = new Point(1d, 2d, 3d);
177+
178+
await using var conn = await OpenConnectionAsync(handleOrdinates: Ordinates.XY);
179+
await using var cmd = conn.CreateCommand();
180+
cmd.Parameters.AddWithValue("p1", pointWithZ);
181+
cmd.CommandText = "SELECT ST_Z(@p1::geometry)";
182+
183+
var result = cmd.ExecuteScalar();
184+
185+
// Z coordinate should be filtered out and return NULL
186+
Assert.That(result, Is.EqualTo(DBNull.Value),
187+
"Z coordinate should be filtered during write when handleOrdinates: Ordinates.XY");
188+
}
189+
190+
[Test]
191+
public async Task WriteWithHandleOrdinatesXY_ShouldFilterMCoordinate()
192+
{
193+
// This test verifies that when handleOrdinates is set to XY,
194+
// M coordinates are correctly filtered out during write operations.
195+
var pointWithM = new Point(
196+
new DotSpatialAffineCoordinateSequence([1d, 2d], [double.NaN], [4d]),
197+
GeometryFactory.Default);
198+
199+
await using var conn = await OpenConnectionAsync(handleOrdinates: Ordinates.XY);
200+
await using var cmd = conn.CreateCommand();
201+
cmd.Parameters.AddWithValue("p1", pointWithM);
202+
cmd.CommandText = "SELECT ST_M(@p1::geometry)";
203+
204+
var result = cmd.ExecuteScalar();
205+
206+
// M coordinate should be filtered out and return NULL
207+
Assert.That(result, Is.EqualTo(DBNull.Value),
208+
"M coordinate should be filtered during write when handleOrdinates: Ordinates.XY");
209+
}
210+
211+
[Test]
212+
public async Task WriteWithHandleOrdinatesXYZ_ShouldFilterMCoordinate()
213+
{
214+
// This test verifies that when handleOrdinates is set to XYZ,
215+
// M coordinates are correctly filtered out during write operations.
216+
var pointWithZM = new Point(
217+
new DotSpatialAffineCoordinateSequence([1d, 2d], [3d], [4d]),
218+
GeometryFactory.Default);
219+
220+
await using var conn = await OpenConnectionAsync(handleOrdinates: Ordinates.XYZ);
221+
await using var cmd = conn.CreateCommand();
222+
cmd.Parameters.AddWithValue("p1", pointWithZM);
223+
cmd.CommandText = "SELECT ST_M(@p1::geometry)";
224+
225+
var result = cmd.ExecuteScalar();
226+
227+
// M coordinate should be filtered out and return NULL
228+
Assert.That(result, Is.EqualTo(DBNull.Value),
229+
"M coordinate should be filtered during write when handleOrdinates: Ordinates.XYZ");
230+
}
231+
153232
[Test]
154233
public async Task Array()
155234
{

0 commit comments

Comments
 (0)