Skip to content

Commit 729c8cb

Browse files
committed
Hande M ordinates
resolves #24
1 parent 2799f79 commit 729c8cb

File tree

4 files changed

+83
-49
lines changed

4 files changed

+83
-49
lines changed

src/NetTopologySuite.IO.Oracle/OracleGeometryReader.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ public Geometry Read(SdoGeometry geom)
7777
{
7878
return null;
7979
}
80-
retVal.SRID = srid;
81-
8280
return retVal;
8381
}
8482

@@ -94,7 +92,7 @@ private Geometry Create(GeometryFactory factory, int gType, SdoPoint point, doub
9492
}
9593
else
9694
{
97-
dim = Math.Min(gType / 1000, 3);
95+
dim = Math.Min(gType / 1000, 4);
9896
}
9997

10098
if (dim == 0)
@@ -182,7 +180,7 @@ private static List<Coordinate> Coordinates(int dim, int lrs, int gtemplate, dou
182180
return pt;
183181
}
184182

185-
int len = dim + lrs;
183+
int len = dim;
186184

187185
if ((len == 0 && ordinates.Length != 0) || (len != 0 && ((ordinates.Length % len) != 0)))
188186
{
@@ -204,11 +202,16 @@ private static List<Coordinate> Coordinates(int dim, int lrs, int gtemplate, dou
204202
switch (len)
205203
{
206204
case 2:
207-
pts.Add(new CoordinateZ(ordinates[offset], ordinates[offset + 1], double.NaN));
205+
pts.Add(new Coordinate(ordinates[offset], ordinates[offset + 1]));
208206
break;
209207
case 3:
210-
pts.Add(new CoordinateZ(ordinates[offset], ordinates[offset + 1],
211-
ordinates[offset + 2]));
208+
if (lrs == 0)
209+
pts.Add(new CoordinateZ(ordinates[offset], ordinates[offset + 1], ordinates[offset + 2]));
210+
else
211+
pts.Add(new CoordinateM(ordinates[offset], ordinates[offset + 1], ordinates[offset + 2]));
212+
break;
213+
case 4:
214+
pts.Add(new CoordinateZM(ordinates[offset], ordinates[offset + 1], ordinates[offset + 2], ordinates[offset + 3]));
212215
break;
213216
}
214217

@@ -598,7 +601,7 @@ private Point CreatePoint(GeometryFactory factory, int dim, int lrs, double[] el
598601
return null;
599602
}
600603

601-
int len = (dim + lrs);
604+
int len = dim;
602605
int start = (sOffset - 1) / len;
603606
int eOffset = StartingOffset(elemInfo, elemIndex + 1); // -1 for end
604607

src/NetTopologySuite.IO.Oracle/OracleGeometryWriter.cs

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,10 @@ private static int ProcessPolygon(Polygon polygon, int dimension, List<double> e
236236
elemInfoList.Add(1);
237237

238238
var exteriorRingCoords = polygon.ExteriorRing.CoordinateSequence;
239-
pos += Algorithm.Orientation.IsCCW(exteriorRingCoords)
239+
pos += AddOrdinates(exteriorRingCoords, dimension, ordinateList, LinearRingOrientation.CounterClockwise);
240+
/* Algorithm.Orientation.IsCCW(exteriorRingCoords)
240241
? AddOrdinates(exteriorRingCoords, dimension, ordinateList)
241-
: AddOrdinatesInReverse(exteriorRingCoords, dimension, ordinateList);
242+
: AddOrdinatesInReverse(exteriorRingCoords, dimension, ordinateList);*/
242243

243244
int interiorRingCount = polygon.NumInteriorRings;
244245
for (int i = 0; i < interiorRingCount; i++)
@@ -248,9 +249,10 @@ private static int ProcessPolygon(Polygon polygon, int dimension, List<double> e
248249
elemInfoList.Add(1);
249250

250251
var interiorRingCoords = polygon.GetInteriorRingN(i).CoordinateSequence;
251-
pos += Algorithm.Orientation.IsCCW(interiorRingCoords)
252+
pos += AddOrdinates(interiorRingCoords, dimension, ordinateList, LinearRingOrientation.Clockwise);
253+
/*Algorithm.Orientation.IsCCW(interiorRingCoords)
252254
? AddOrdinatesInReverse(interiorRingCoords, dimension, ordinateList)
253-
: AddOrdinates(interiorRingCoords, dimension, ordinateList);
255+
: AddOrdinates(interiorRingCoords, dimension, ordinateList);*/
254256
}
255257

256258
return pos;
@@ -300,20 +302,28 @@ private static int ProcessMultiPolygon(MultiPolygon multiPolygon, int dimension,
300302
return pos;
301303
}
302304

303-
private static int AddOrdinates(CoordinateSequence sequence, int dimension, List<double> ords)
304-
{
305-
int numOfPoints = sequence.Count;
306-
for (int i = 0; i < numOfPoints; i++)
305+
//private enum RingOrientation
306+
307+
private static int AddOrdinates(CoordinateSequence sequence, int dimension, List<double> ords,
308+
LinearRingOrientation orientation = LinearRingOrientation.DontCare)
309+
{
310+
switch (orientation)
307311
{
308-
ords.Add((double)sequence.GetX(i));
309-
ords.Add((double)sequence.GetY(i));
310-
if (dimension == 3)
311-
{
312-
ords.Add((double)sequence.GetZ(i));
313-
}
312+
case LinearRingOrientation.CounterClockwise:
313+
if (!Algorithm.Orientation.IsCCW(sequence)) sequence = sequence.Reversed();
314+
break;
315+
case LinearRingOrientation.Clockwise:
316+
if (Algorithm.Orientation.IsCCW(sequence)) sequence = sequence.Reversed();
317+
break;
314318
}
315319

316-
return numOfPoints * dimension;
320+
for (int i = 0; i < sequence.Count; i++)
321+
{
322+
for(int j = 0; j < sequence.Dimension; j++)
323+
ords.Add(sequence.GetOrdinate(i, j));
324+
}
325+
326+
return sequence.Count * dimension;
317327
}
318328

319329
private static int AddOrdinatesInReverse(CoordinateSequence sequence, int dimension, List<double> ords)
@@ -322,28 +332,25 @@ private static int AddOrdinatesInReverse(CoordinateSequence sequence, int dimens
322332

323333
for (int i = numOfPoints - 1; i >= 0; i--)
324334
{
325-
ords.Add((double)sequence.GetX(i));
326-
ords.Add((double)sequence.GetY(i));
327-
if (dimension == 3)
328-
{
329-
ords.Add((double)sequence.GetZ(i));
330-
}
335+
for (int j = 0; j < sequence.Dimension; j++)
336+
ords.Add(sequence.GetOrdinate(i, j));
331337
}
332338

333339
return numOfPoints * dimension;
334340
}
335341

336342
private static int GType(Geometry geom, out int dimension)
337343
{
338-
dimension = Dimension(geom);
339-
return dimension * 1000 + (int)Template(geom);
344+
DimensionAndMeasure(geom, out dimension, out int measure);
345+
return dimension * 1000 + measure * 100 + (int)Template(geom);
340346
}
341347

342-
private static int Dimension(Geometry geom)
348+
private static void DimensionAndMeasure(Geometry geom, out int dimension, out int measure)
343349
{
344-
var sdd = new SpatialDimensionDeterminator();
350+
var sdd = new DimensionAndMeasureDeterminator();
345351
geom.Apply(sdd);
346-
return sdd.NumSpatialDimensions;
352+
dimension = sdd.Dimension;
353+
measure = sdd.Measure;
347354
}
348355

349356
private static SdoGTemplate Template(Geometry geom)
@@ -382,14 +389,22 @@ private static SdoGTemplate Template(Geometry geom)
382389
}
383390
}
384391

385-
private class SpatialDimensionDeterminator : IEntireCoordinateSequenceFilter
392+
private class DimensionAndMeasureDeterminator : IEntireCoordinateSequenceFilter
386393
{
387394
public void Filter(CoordinateSequence sequence)
388395
{
389-
NumSpatialDimensions = sequence.Dimension - sequence.Measures;
396+
bool hasMeasure = sequence.Measures > 0;
397+
Dimension = Math.Min(sequence.Dimension, 4);
398+
if (hasMeasure)
399+
Measure = Dimension;
400+
390401
Done = true;
391402
}
392-
public int NumSpatialDimensions { get; private set; } = 2;
403+
404+
public int Dimension { get; private set; } = 2;
405+
406+
public int Measure { get; private set; } = 0;
407+
393408
public bool Done { get; private set; }
394409
public bool GeometryChanged => false;
395410
}

test/NetTopologySuite.IO.Oracle.Test/IntegrationTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public void OneTimeSetUp()
4747
[TestCase("POINT(10 10)")]
4848
[TestCase("POINT Z(10 10 0)")]
4949
[TestCase("POINT Z(10 10 20)")]
50+
[TestCase("POINT M(10 10 30)")]
51+
[TestCase("POINT ZM(10 10 20 30)")]
5052
[TestCase("MULTIPOINT(11 12, 20 20)")]
5153
[TestCase("MULTIPOINT Z(11 12 12, 20 20 20)")]
5254
[TestCase("LINESTRING(10 10,20 20,50 50,34 34)")]

test/NetTopologySuite.IO.Oracle.Test/OracleTest.cs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class OracleTest
1010
{
1111

1212
private static readonly OracleGeometryReader or = new OracleGeometryReader(NtsGeometryServices.Instance);
13-
private static readonly WKTReader wr = new WKTReader { IsOldNtsCoordinateSyntaxAllowed = false };
14-
13+
private static readonly WKTReader wr = new WKTReader { IsOldNtsCoordinateSyntaxAllowed = false, };
14+
private static readonly WKTWriter ww = new WKTWriter(4);
1515
/// <summary>
1616
///
1717
/// </summary>
@@ -37,7 +37,13 @@ public void CCWTestsOnPolygon()
3737
[TestCase("POINT(10 10)", -1)]
3838
[TestCase("POINT(10 10)", 4326)]
3939
[TestCase("POINT Z(10 10 0)", -1)]
40+
[TestCase("POINT Z(10 10 0)", 4326)]
4041
[TestCase("POINT Z(10 10 20)", -1)]
42+
[TestCase("POINT Z(10 10 20)", 4326)]
43+
[TestCase("POINT M(10 10 30)", -1)]
44+
[TestCase("POINT M(10 10 30)", 4326)]
45+
[TestCase("POINT ZM(10 10 20 30)", -1)]
46+
[TestCase("POINT ZM(10 10 20 30)", 4326)]
4147
[TestCase("MULTIPOINT(11 12)", -1)]
4248
[TestCase("MULTIPOINT(11 12, 20 20)", -1)]
4349
[TestCase("MULTIPOINT Z(11 12 12, 20 20 20)", -1)]
@@ -62,20 +68,18 @@ public void CCWTestsOnPolygon()
6268
[TestCase("GEOMETRYCOLLECTION(POINT(10 10),MULTIPOINT(11 12, 20 20))", -1)]
6369
public void BasicConversion(string wkt, int srid)
6470
{
71+
wr.DefaultSRID = srid;
6572
var geom = wr.Read(wkt);
66-
string parsed = geom.AsText();
67-
var regeom = wr.Read(parsed);
68-
string reparsed = regeom.AsText();
73+
Assert.That(geom.SRID, Is.EqualTo(srid));
6974

70-
geom.SRID = srid;
71-
regeom.SRID = srid;
75+
string parsed = ww.Write(geom);
7276

73-
Assert.That(geom.EqualsExact(regeom));
74-
Assert.That(reparsed, Is.EqualTo(parsed));
77+
var t = new OracleGeometryWriter().Write(geom);
78+
var geomRead = or.Read(t);
7579

76-
var t = new OracleGeometryWriter().Write(regeom);
77-
var regeom3 = or.Read(t);
78-
Assert.That(geom.EqualsExact(regeom3));
80+
Assert.That(geomRead.EqualsExact(geom), Is.True);
81+
Assert.That(geomRead.SRID, Is.EqualTo(geom.SRID));
82+
Assert.That(ww.Write(geomRead), Is.EqualTo(parsed));
7983
}
8084

8185
/// <summary>
@@ -100,5 +104,15 @@ public void CollectionConversion(string wkt, string wktresult, int srid)
100104
Assert.That(result.EqualsExact(regeom));
101105
}
102106

107+
[Test]
108+
public void TestIssue23()
109+
{
110+
var rdr = new WKTReader();
111+
rdr.DefaultSRID = 4326;
112+
var geom = rdr.Read("GEOMETRYCOLLECTION(POINT(1 1), LINESTRING(2 2, 3 3), POLYGON((4 4, 4 6, 6 6, 6 4, 4 4)))");
113+
var t = new OracleGeometryWriter().Write(geom);
114+
Assert.That(true);
115+
}
116+
103117
}
104118
}

0 commit comments

Comments
 (0)