Skip to content

Commit

Permalink
Enable round-tripping unsupported types
Browse files Browse the repository at this point in the history
Discussed in NetTopologySuite#18
  • Loading branch information
bricelam committed May 27, 2021
1 parent 5f51421 commit 9c81eba
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using NetTopologySuite.IO.Properties;
using NetTopologySuite.IO.Serialization;

namespace NetTopologySuite.Geometries
{
internal class UnsupportedGeometry : Geometry
{
private readonly OpenGisType _shapeType;

public UnsupportedGeometry(OpenGisType shapeType, Geography geography)
: base(GeometryFactory.Default)
{
_shapeType = shapeType;
Geography = geography;
}

public Geography Geography { get; }

private NotSupportedException Unsupported()
=> new NotSupportedException(string.Format(Resources.UnexpectedGeographyType, _shapeType));

#region Unsupported overrides

public override double Area => throw Unsupported();
public override Geometry Boundary => throw Unsupported();
public override Dimension BoundaryDimension => throw Unsupported();
public override Point Centroid => throw Unsupported();
public override Coordinate Coordinate => throw Unsupported();
public override Coordinate[] Coordinates => throw Unsupported();
public override Dimension Dimension => throw Unsupported();
public override string GeometryType => throw Unsupported();
public override Point InteriorPoint => throw Unsupported();
public override bool IsEmpty => throw Unsupported();
public override bool IsRectangle => throw Unsupported();
public override bool IsSimple => throw Unsupported();
public override bool IsValid => throw Unsupported();
public override double Length => throw Unsupported();
public override int NumGeometries => throw Unsupported();
public override int NumPoints => throw Unsupported();
public override OgcGeometryType OgcGeometryType => throw Unsupported();

protected override SortIndexValue SortIndex => throw Unsupported();

public override void Apply(ICoordinateFilter filter) => throw Unsupported();
public override void Apply(ICoordinateSequenceFilter filter) => throw Unsupported();
public override void Apply(IGeometryComponentFilter filter) => throw Unsupported();
public override void Apply(IGeometryFilter filter) => throw Unsupported();
public override bool Contains(Geometry g) => throw Unsupported();
public override Geometry ConvexHull() => throw Unsupported();
public override bool Covers(Geometry g) => throw Unsupported();
public override bool Crosses(Geometry g) => throw Unsupported();
public override double Distance(Geometry g) => throw Unsupported();
public override bool Equals(object o) => throw Unsupported();
public override bool EqualsExact(Geometry other, double tolerance) => throw Unsupported();
public override bool EqualsTopologically(Geometry g) => throw Unsupported();
public override Geometry GetGeometryN(int n) => throw Unsupported();
public override int GetHashCode() => throw Unsupported();
public override double[] GetOrdinates(Ordinate ordinate) => throw Unsupported();
public override bool Intersects(Geometry g) => throw Unsupported();
public override bool IsWithinDistance(Geometry geom, double distance) => throw Unsupported();
public override void Normalize() => throw Unsupported();
public override bool Overlaps(Geometry g) => throw Unsupported();
public override IntersectionMatrix Relate(Geometry g) => throw Unsupported();
public override bool Relate(Geometry g, string intersectionPattern) => throw Unsupported();
public override Geometry Reverse() => throw Unsupported();
public override string ToString() => throw Unsupported();
public override bool Touches(Geometry g) => throw Unsupported();

protected override int CompareToSameClass(object o) => throw Unsupported();
protected override int CompareToSameClass(object o, IComparer<CoordinateSequence> comp) => throw Unsupported();
protected override Envelope ComputeEnvelopeInternal() => throw Unsupported();
protected override Geometry CopyInternal() => throw Unsupported();
protected override bool IsEquivalentClass(Geometry other) => throw Unsupported();

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ private Geometry ToGeometry(Geography geography)
geometries.Remove(shapeIndex);
break;

case OpenGisType.CircularString:
case OpenGisType.CompoundCurve:
case OpenGisType.CurvePolygon:
case OpenGisType.FullGlobe:
return new UnsupportedGeometry(shape.Type, geography);

default:
throw new ParseException(string.Format(Resources.UnexpectedGeographyType, shape.Type));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ private Geography ToGeography(Geometry geometry)
{
return new Geography { SRID = -1 };
}
if (geometry is UnsupportedGeometry unsupportedGeometry)
{
return unsupportedGeometry.Geography;
}

var geometries = new Queue<(Geometry, int)>();
geometries.Enqueue((geometry, -1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using System.Globalization;
using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Implementation;
using NetTopologySuite.IO.Properties;
using Xunit;
using Point = NetTopologySuite.Geometries.Point;

namespace NetTopologySuite.IO
{
Expand Down Expand Up @@ -161,40 +161,17 @@ public void HandleOrdinates_works()
Assert.Equal("POINT (1 2)", new WKTWriter(4).Write(point));
}

[Fact]
public void Read_throws_when_circular_string()
{
var ex = Assert.Throws<ParseException>(
() => Read("0000000002040300000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000040000000000000000001000000020000000001000000FFFFFFFF0000000008"));

Assert.Equal(string.Format(Resources.UnexpectedGeographyType, "CircularString"), ex.Message);
}

[Fact]
public void Read_throws_when_compound_curve()
{
var ex = Assert.Throws<ParseException>(
() => Read("0000000002040400000000000000000000000000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F0000000000000840000000000000000001000000030000000001000000FFFFFFFF0000000009020000000203"));

Assert.Equal(string.Format(Resources.UnexpectedGeographyType, "CompoundCurve"), ex.Message);
}

[Fact]
public void Read_throws_when_curve_polygon()
{
var ex = Assert.Throws<ParseException>(
() => Read("000000000204050000000000000000000040000000000000F03F000000000000F03F00000000000000400000000000000000000000000000F03F000000000000F03F00000000000000000000000000000040000000000000F03F01000000020000000001000000FFFFFFFF000000000A"));

Assert.Equal(string.Format(Resources.UnexpectedGeographyType, "CurvePolygon"), ex.Message);
}

[Fact]
public void Read_throws_when_full_globe()
[Theory]
[InlineData("0000000002040300000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000040000000000000000001000000020000000001000000FFFFFFFF0000000008")]
[InlineData("0000000002040400000000000000000000000000000000000000000000000000F03F00000000000000000000000000000040000000000000F03F0000000000000840000000000000000001000000030000000001000000FFFFFFFF0000000009020000000203")]
[InlineData("000000000204050000000000000000000040000000000000F03F000000000000F03F00000000000000400000000000000000000000000000F03F000000000000F03F00000000000000000000000000000040000000000000F03F01000000020000000001000000FFFFFFFF000000000A")]
[InlineData("E61000000224000000000000000001000000FFFFFFFFFFFFFFFF0B")]
public void Can_round_trip_unsupported_types(string bytes)
{
var ex = Assert.Throws<ParseException>(
() => Read("E61000000224000000000000000001000000FFFFFFFFFFFFFFFF0B"));
var geometry = Read(bytes);

Assert.Equal(string.Format(Resources.UnexpectedGeographyType, "FullGlobe"), ex.Message);
Assert.IsType<UnsupportedGeometry>(geometry);
Assert.Equal(bytes, SqlServerBytesWriterTest.Write(geometry));
}

private Geometry Read(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public void Types_still_unknown(string wkt)
() => reader.Read(wkt));
}

private string Write(
public static string Write(
Geometry geometry,
Ordinates handleOrdinates = Ordinates.XYZM,
bool isGeography = false)
Expand Down

0 comments on commit 9c81eba

Please sign in to comment.