Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
airbreather committed Jul 16, 2020
2 parents 23afedb + 07a3148 commit 1ec0b46
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public override Geometry Read(ref Utf8JsonReader reader, Type typeToConvert, Jso
break;
case "coordinates":
coordinateData = StjParsedCoordinates.Parse(ref reader, _geometryFactory);
reader.ReadToken(JsonTokenType.EndArray);
reader.Read();
break;
case "bbox":
var env = ReadBBox(ref reader, options);
Expand Down Expand Up @@ -126,7 +126,7 @@ public override Geometry Read(ref Utf8JsonReader reader, Type typeToConvert, Jso
switch (geometryType)
{
case GeoJsonObjectType.Point:
geometry = coordinateData.ToPoint();
geometry = coordinateData.ToPoint(_geometryFactory);
break;
case GeoJsonObjectType.LineString:
geometry = coordinateData.ToLineString(_geometryFactory);
Expand All @@ -141,7 +141,7 @@ public override Geometry Read(ref Utf8JsonReader reader, Type typeToConvert, Jso
geometry = coordinateData.ToMultiLineString(_geometryFactory);
break;
case GeoJsonObjectType.MultiPolygon:
geometry = coordinateData.ToMultiPolygon();
geometry = coordinateData.ToMultiPolygon(_geometryFactory);
break;
case GeoJsonObjectType.GeometryCollection:
if (geometries == null)
Expand Down Expand Up @@ -188,6 +188,10 @@ public override void Write(Utf8JsonWriter writer, Geometry value, JsonSerializer
Write(writer, value.GetGeometryN(i), options);
writer.WriteEndArray();
}
else if (value.IsEmpty)
{
writer.WriteNull("coordinates");
}
else
{
writer.WritePropertyName("coordinates");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ internal readonly struct StjParsedCoordinates

private static readonly GeoJsonObjectType[] SupportedTypesForMultiPolygon = { GeoJsonObjectType.MultiPolygon };

private static readonly GeoJsonObjectType[] SupportedTypesForEmpty = { GeoJsonObjectType.Point, GeoJsonObjectType.LineString, GeoJsonObjectType.Polygon, GeoJsonObjectType.MultiPoint, GeoJsonObjectType.MultiLineString, GeoJsonObjectType.MultiPolygon };

private readonly object _obj;

private StjParsedCoordinates(object obj)
Expand All @@ -41,6 +43,11 @@ public static StjParsedCoordinates Parse(ref Utf8JsonReader reader, GeometryFact
return new StjParsedCoordinates(ParsePoint(ref reader, factory));
}

if (reader.TokenType == JsonTokenType.EndArray)
{
return default;
}

reader.AssertToken(JsonTokenType.StartArray);
reader.ReadOrThrow();

Expand Down Expand Up @@ -71,7 +78,7 @@ public ReadOnlySpan<GeoJsonObjectType> SupportedTypes
switch (_obj)
{
case null:
return default;
return SupportedTypesForEmpty;

case Point _:
return SupportedTypesForPoint;
Expand All @@ -92,45 +99,94 @@ public ReadOnlySpan<GeoJsonObjectType> SupportedTypes
}
}

public Point ToPoint()
public Point ToPoint(GeometryFactory factory)
{
return _obj as Point ??
throw new InvalidOperationException("Point is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreatePoint();

case Point point:
return point;

default:
throw new InvalidOperationException("Point is not supported (check SupportedTypes before calling any ToX methods)");
}
}

public LineString ToLineString(GeometryFactory factory)
{
return _obj is CoordinateSequence seq
? factory.CreateLineString(seq)
: throw new InvalidOperationException("LineString is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreateLineString();

case CoordinateSequence seq:
return factory.CreateLineString(seq);

default:
throw new InvalidOperationException("LineString is not supported (check SupportedTypes before calling any ToX methods)");
}
}

public MultiPoint ToMultiPoint(GeometryFactory factory)
{
return _obj is CoordinateSequence seq
? factory.CreateMultiPoint(seq)
: throw new InvalidOperationException("MultiPoint is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreateMultiPoint();

case CoordinateSequence seq:
return factory.CreateMultiPoint(seq);

default:
throw new InvalidOperationException("MultiPoint is not supported (check SupportedTypes before calling any ToX methods)");
}
}

public Polygon ToPolygon(GeometryFactory factory)
{
return _obj is CoordinateSequence[] seqs
? ToPolygon(seqs, factory)
: throw new InvalidOperationException("Polygon is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreatePolygon();

case CoordinateSequence[] seqs:
return ToPolygon(seqs, factory);

default:
throw new InvalidOperationException("Polygon is not supported (check SupportedTypes before calling any ToX methods)");
}
}

public MultiLineString ToMultiLineString(GeometryFactory factory)
{
return _obj is CoordinateSequence[] seqs
? factory.CreateMultiLineString(Array.ConvertAll(seqs, factory.CreateLineString))
: throw new InvalidOperationException("MultiLineString is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreateMultiLineString();

case CoordinateSequence[] seqs:
return factory.CreateMultiLineString(Array.ConvertAll(seqs, factory.CreateLineString));

default:
throw new InvalidOperationException("MultiLineString is not supported (check SupportedTypes before calling any ToX methods)");
}
}

public MultiPolygon ToMultiPolygon()
public MultiPolygon ToMultiPolygon(GeometryFactory factory)
{
return _obj is MultiPolygon multiPolygon
? multiPolygon
: throw new InvalidOperationException("MultiPolygon is not supported (check SupportedTypes before calling any ToX methods)");
switch (_obj)
{
case null:
return factory.CreateMultiPolygon();

case MultiPolygon multiPolygon:
return multiPolygon;

default:
throw new InvalidOperationException("MultiPolygon is not supported (check SupportedTypes before calling any ToX methods)");
}
}

private static Point ParsePoint(ref Utf8JsonReader reader, GeometryFactory factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<!-- MAJOR, MINOR, and PATCH are defined according to SemVer 2.0.0. -->
<NtsMajorVersion Condition=" '$(NtsMajorVersion)' == '' ">2</NtsMajorVersion>
<NtsMinorVersion Condition=" '$(NtsMinorVersion)' == '' ">0</NtsMinorVersion>
<NtsPatchVersion Condition=" '$(NtsPatchVersion)' == '' ">3</NtsPatchVersion>
<NtsPatchVersion Condition=" '$(NtsPatchVersion)' == '' ">4</NtsPatchVersion>
</PropertyGroup>

<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ namespace NetTopologySuite.IO.GeoJSON4STJ.Test.Converters
{
public class GeometryConverterTest : SandDTest<Geometry>
{
[TestCase("Point")]
[TestCase("LineString")]
[TestCase("Polygon")]
[TestCase("MultiPoint")]
[TestCase("MultiLineString")]
[TestCase("MultiPolygon")]
public void TestReadWithEmptyCoordinatesArray(string type)
{
string geoJson = @$"{{ ""type"" : ""{type}"", ""coordinates"": [] }}";
var options = DefaultOptions;
var geom = Deserialize(geoJson, options);

Assert.That(geom != null);
Assert.That(geom.IsEmpty);
}

[Test]
public void TestReadPoint2D()
{
Expand Down Expand Up @@ -118,16 +134,26 @@ public void TestReadGeometryCollection()
Assert.That(geom.NumGeometries, Is.EqualTo(3));
}


[TestCase("POINT EMPTY")]
[TestCase("POINT Z EMPTY")]
[TestCase("POINT (1 2)")]
[TestCase("POINT Z (1 2 3)")]
[TestCase("LINESTRING EMPTY")]
[TestCase("LINESTRING Z EMPTY")]
[TestCase("LINESTRING (1 2, 2 2)")]
[TestCase("LINESTRING Z (1 2 0, 2 2 0)")]
[TestCase("POLYGON EMPTY")]
[TestCase("POLYGON Z EMPTY")]
[TestCase("POLYGON ((0 0, 10 10, 0 10, 0 0))")]
[TestCase("POLYGON Z ((0 0 1, 10 10 1, 0 10 1, 0 0 1))")]
[TestCase("POLYGON ((0 0, 10 10, 0 10, 0 0), (1 2, 1 9, 8 9, 1 2))")]
[TestCase("POLYGON Z ((0 0 1, 10 10 1, 0 10 1, 0 0 1), (1 2.4 1, 1 9 1, 7.6 9 1, 1 2.4 1))")]

[TestCase("MULTIPOINT EMPTY")]
[TestCase("MULTIPOINT Z EMPTY")]
[TestCase("MULTILINESTRING EMPTY")]
[TestCase("MULTILINESTRING Z EMPTY")]
[TestCase("MULTIPOLYGON EMPTY")]
[TestCase("MULTIPOLYGON Z EMPTY")]
public void TestWriteReadWkt(string wkt)
{
var wktReader = new WKTReader(NtsGeometryServices.Instance.CreateGeometryFactory(4326));
Expand All @@ -141,7 +167,8 @@ public void TestWriteReadWkt(string wkt)
geomD = Deserialize(ms, options);

}
Assert.That(geomS.EqualsTopologically(geomD));

Assert.That(geomS.IsEmpty ? geomD.IsEmpty : geomS.EqualsTopologically(geomD));
}
}
}

0 comments on commit 1ec0b46

Please sign in to comment.