diff --git a/src/Microsoft.SqlServer.Types.RefTests/Microsoft.SqlServer.Types.RefTests.csproj b/src/Microsoft.SqlServer.Types.RefTests/Microsoft.SqlServer.Types.RefTests.csproj
index 5c5b728..004322b 100644
--- a/src/Microsoft.SqlServer.Types.RefTests/Microsoft.SqlServer.Types.RefTests.csproj
+++ b/src/Microsoft.SqlServer.Types.RefTests/Microsoft.SqlServer.Types.RefTests.csproj
@@ -49,6 +49,9 @@
AssemblyLoader.cs
+
+ Geography\WktTests.cs
+
Geometry\DBTests.cs
@@ -96,9 +99,7 @@
1.3.2
-
-
-
+
\ No newline at end of file
diff --git a/src/Microsoft.SqlServer.Types.Tests/Geography/WktTests.cs b/src/Microsoft.SqlServer.Types.Tests/Geography/WktTests.cs
new file mode 100644
index 0000000..4e5ef0b
--- /dev/null
+++ b/src/Microsoft.SqlServer.Types.Tests/Geography/WktTests.cs
@@ -0,0 +1,78 @@
+using Microsoft.SqlServer.Types.Tests.Geometry;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Microsoft.SqlServer.Types.Tests.Geography
+{
+ [TestClass]
+ [TestCategory("SqlGeography")]
+ [TestCategory("WKT")]
+ public class WktTests
+ {
+
+ [TestMethod]
+ [WorkItem(13)]
+ public void UserSubmittedIssue_WKT2()
+ {
+ using (var conn = new System.Data.SqlClient.SqlConnection(DBTests.ConnectionString))
+ {
+ conn.Open();
+ var id = SqlGeography.Parse("LINESTRING (-122.36 47.656, -122.343 47.656)");
+
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.CommandText = "SELECT @p";
+ var p = cmd.CreateParameter();
+ cmd.Parameters.Add(p);
+
+ p.UdtTypeName = "geography";
+ p.ParameterName = "@p";
+ p.Value = id;
+
+ Assert.AreEqual(id.ToString(), cmd.ExecuteScalar().ToString());
+ }
+ }
+ }
+
+ [TestMethod]
+ [WorkItem(13)]
+ public void UserSubmittedIssue_WKT3()
+ {
+ using (var conn = new System.Data.SqlClient.SqlConnection(DBTests.ConnectionString))
+ {
+ conn.Open();
+ var id = SqlGeography.Parse("LINESTRING (-122.36 47.656, -122.343 47.656)");
+ var l = id.STPointN(1).Long;
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.CommandText = "SELECT Cast(geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326) as geography)";
+
+ Assert.AreEqual(id.ToString(), cmd.ExecuteScalar().ToString());
+ }
+ }
+ }
+
+ [TestMethod]
+ [WorkItem(14)]
+ public void UserSubmittedIssue_WKT4()
+ {
+ using (var conn = new System.Data.SqlClient.SqlConnection(DBTests.ConnectionString))
+ {
+ conn.Open();
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.CommandText = "SELECT Cast(geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326) as geography)";
+ var result = cmd.ExecuteScalar();
+ Assert.IsInstanceOfType(result, typeof(SqlGeography));
+ SqlGeography g = (SqlGeography)result;
+ Assert.AreEqual("LineString", g.STGeometryType());
+ Assert.AreEqual(2, g.STNumPoints());
+ Assert.AreEqual(47.656, g.STPointN(1).Lat.Value);
+ Assert.AreEqual(-122.360, g.STPointN(1).Long.Value);
+ Assert.AreEqual(47.656, g.STPointN(2).Lat.Value);
+ Assert.AreEqual(-122.343, g.STPointN(2).Long.Value);
+ Assert.AreEqual("LINESTRING (-122.36 47.656, -122.343 47.656)", cmd.ExecuteScalar().ToString());
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.SqlServer.Types.Tests/Geometry/DBTests.cs b/src/Microsoft.SqlServer.Types.Tests/Geometry/DBTests.cs
index 5876af3..47b8a56 100644
--- a/src/Microsoft.SqlServer.Types.Tests/Geometry/DBTests.cs
+++ b/src/Microsoft.SqlServer.Types.Tests/Geometry/DBTests.cs
@@ -22,29 +22,38 @@ public class DBTests : IDisposable
private System.Data.SqlClient.SqlConnection conn;
private static string path;
+ private static object lockObj = new object();
static DBTests()
{
- path = Path.Combine(new FileInfo(typeof(DBTests).Assembly.Location).Directory.FullName, "UnitTestData.mdf");
- CreateSqlDatabase(path);
- using (var conn = new System.Data.SqlClient.SqlConnection(connstr + path))
+ Init();
+ }
+ public static void Init()
+ {
+ lock(lockObj)
+ if(path == null)
{
- conn.Open();
- var cmd = conn.CreateCommand();
- cmd.CommandText = OgcConformanceMap.DropTables;
- cmd.ExecuteNonQuery();
- cmd.CommandText = OgcConformanceMap.CreateTables;
- cmd.ExecuteNonQuery();
- cmd.CommandText = OgcConformanceMap.CreateRows;
- cmd.ExecuteNonQuery();
- conn.Close();
+ path = Path.Combine(new FileInfo(typeof(DBTests).Assembly.Location).Directory.FullName, "UnitTestData.mdf");
+ CreateSqlDatabase(path);
+ using (var conn = new System.Data.SqlClient.SqlConnection(connstr + path))
+ {
+ conn.Open();
+ var cmd = conn.CreateCommand();
+ cmd.CommandText = OgcConformanceMap.DropTables;
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = OgcConformanceMap.CreateTables;
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = OgcConformanceMap.CreateRows;
+ cmd.ExecuteNonQuery();
+ conn.Close();
+ }
}
}
public static string ConnectionString => connstr + path;
-
public DBTests()
{
+ Init();
conn = new System.Data.SqlClient.SqlConnection(ConnectionString);
conn.Open();
}
diff --git a/src/Microsoft.SqlServer.Types.Tests/Geometry/WktTests.cs b/src/Microsoft.SqlServer.Types.Tests/Geometry/WktTests.cs
index 55cd8fa..79af238 100644
--- a/src/Microsoft.SqlServer.Types.Tests/Geometry/WktTests.cs
+++ b/src/Microsoft.SqlServer.Types.Tests/Geometry/WktTests.cs
@@ -3,10 +3,10 @@
namespace Microsoft.SqlServer.Types.Tests.Geometry
{
[TestClass]
+ [TestCategory("SqlGeometry")]
+ [TestCategory("WKT")]
public class WktTests
{
- public object StreamExtensions { get; private set; }
-
[TestMethod]
public void TestNullToString()
{
@@ -45,6 +45,7 @@ public void TestLineStringToString()
var str = g.ToString();
Assert.AreEqual("LINESTRING (0 1 1, 3 2 2, 4 5)", str);
}
+
[TestMethod]
public void TestLineStringFromString()
{
@@ -78,6 +79,23 @@ public void TestLineStringFromString()
Assert.IsTrue(p3.M.IsNull);
}
-
+ [TestMethod]
+ [WorkItem(13)]
+ public void UserSubmittedIssue_WKT1()
+ {
+ using (var conn = new System.Data.SqlClient.SqlConnection(DBTests.ConnectionString))
+ {
+ conn.Open();
+ var id = SqlGeometry.Parse("LINESTRING (100 100, 20 180, 180 180)");
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.CommandText = "SELECT @p";
+ var p =cmd.Parameters.Add("@p", System.Data.SqlDbType.Udt);
+ p.UdtTypeName = "geometry";
+ p.Value = id;
+ Assert.AreEqual(id.ToString(), cmd.ExecuteScalar().ToString());
+ }
+ }
+ }
}
}
diff --git a/src/Microsoft.SqlServer.Types.Tests/Microsoft.SqlServer.Types.Tests.csproj b/src/Microsoft.SqlServer.Types.Tests/Microsoft.SqlServer.Types.Tests.csproj
index b3bbe29..04df44b 100644
--- a/src/Microsoft.SqlServer.Types.Tests/Microsoft.SqlServer.Types.Tests.csproj
+++ b/src/Microsoft.SqlServer.Types.Tests/Microsoft.SqlServer.Types.Tests.csproj
@@ -27,8 +27,4 @@
-
-
-
-
diff --git a/src/Microsoft.SqlServer.Types/SqlGeography.cs b/src/Microsoft.SqlServer.Types/SqlGeography.cs
index fd7a010..a1cfeeb 100644
--- a/src/Microsoft.SqlServer.Types/SqlGeography.cs
+++ b/src/Microsoft.SqlServer.Types/SqlGeography.cs
@@ -416,7 +416,7 @@ public static SqlGeography STGeomFromText(SqlChars geometryTaggedText, int srid)
{
if (geometryTaggedText.IsNull)
return SqlGeography.Null;
- var data = Wkt.WktReader.Parse(geometryTaggedText.ToString(), Wkt.WktReader.CoordinateOrder.LatLong);
+ var data = Wkt.WktReader.Parse(geometryTaggedText.ToString(), Wkt.CoordinateOrder.LatLong);
return new SqlGeography(data, srid);
}
@@ -433,7 +433,7 @@ public static SqlGeography Parse(SqlString s)
{
if (s.IsNull)
return SqlGeography.Null;
- var data = Wkt.WktReader.Parse(s.ToString(), Wkt.WktReader.CoordinateOrder.LatLong);
+ var data = Wkt.WktReader.Parse(s.ToString(), Wkt.CoordinateOrder.LatLong);
return new SqlGeography(data, 4326);
}
@@ -495,6 +495,6 @@ public SqlBytes Serialize()
}
}
- public override string ToString() => WktWriter.Write(_geometry);
+ public override string ToString() => Wkt.WktWriter.Write(_geometry, Wkt.CoordinateOrder.LatLong);
}
}
\ No newline at end of file
diff --git a/src/Microsoft.SqlServer.Types/SqlGeometry.cs b/src/Microsoft.SqlServer.Types/SqlGeometry.cs
index 3c20f98..807ca0a 100644
--- a/src/Microsoft.SqlServer.Types/SqlGeometry.cs
+++ b/src/Microsoft.SqlServer.Types/SqlGeometry.cs
@@ -412,7 +412,7 @@ public static SqlGeometry STGeomFromText(SqlChars geometryTaggedText, int srid)
{
if (geometryTaggedText.IsNull)
return SqlGeometry.Null;
- var data = Wkt.WktReader.Parse(geometryTaggedText.ToString(), Wkt.WktReader.CoordinateOrder.XY);
+ var data = Wkt.WktReader.Parse(geometryTaggedText.ToString(), Wkt.CoordinateOrder.XY);
return new SqlGeometry(data, srid);
}
@@ -432,7 +432,7 @@ public static SqlGeometry Parse(SqlString s)
{
if (s.IsNull)
return SqlGeometry.Null;
- var data = Wkt.WktReader.Parse(s.ToString(), Wkt.WktReader.CoordinateOrder.XY);
+ var data = Wkt.WktReader.Parse(s.ToString(), Wkt.CoordinateOrder.XY);
return new SqlGeometry(data, 0);
}
@@ -449,6 +449,6 @@ public void Write(BinaryWriter w)
_geometry.Write(w);
}
- public override string ToString() => WktWriter.Write(_geometry);
+ public override string ToString() => Wkt.WktWriter.Write(_geometry, Wkt.CoordinateOrder.XY);
}
}
diff --git a/src/Microsoft.SqlServer.Types/Wkt/WktReader.cs b/src/Microsoft.SqlServer.Types/Wkt/WktReader.cs
index 3dd9ebf..cdf0659 100644
--- a/src/Microsoft.SqlServer.Types/Wkt/WktReader.cs
+++ b/src/Microsoft.SqlServer.Types/Wkt/WktReader.cs
@@ -5,6 +5,12 @@
namespace Microsoft.SqlServer.Types.Wkt
{
+ internal enum CoordinateOrder
+ {
+ XY,
+ LatLong
+ }
+
internal class WktReader
{
private int length = 0;
@@ -23,12 +29,6 @@ internal class WktReader
List _shapes;
CoordinateOrder _order;
- public enum CoordinateOrder
- {
- XY,
- LatLong
- }
-
private WktReader(string str)
{
if (string.IsNullOrEmpty(str))
diff --git a/src/Microsoft.SqlServer.Types/Wkt/WktWriter.cs b/src/Microsoft.SqlServer.Types/Wkt/WktWriter.cs
index a2a4f08..110b593 100644
--- a/src/Microsoft.SqlServer.Types/Wkt/WktWriter.cs
+++ b/src/Microsoft.SqlServer.Types/Wkt/WktWriter.cs
@@ -4,7 +4,7 @@
using System.Text;
using System.Globalization;
-namespace Microsoft.SqlServer.Types
+namespace Microsoft.SqlServer.Types.Wkt
{
///
/// Converts geometries to and from Well-Known Text.
@@ -17,11 +17,11 @@ internal static class WktWriter
///
/// Geometry
/// Well-Known Text
- public static string Write(ShapeData g)
+ public static string Write(ShapeData g, CoordinateOrder order)
{
if (g.IsNull)
return "Null";
- return Write(g, g.HasZ, g.HasM);
+ return Write(g, g.HasZ, g.HasM, order);
}
///
@@ -31,14 +31,14 @@ public static string Write(ShapeData g)
/// Include Z values
/// Include M values
/// Well-Known Text
- public static string Write(ShapeData g, bool includeZ, bool includeM)
+ public static string Write(ShapeData g, bool includeZ, bool includeM, CoordinateOrder order)
{
StringBuilder sb = new StringBuilder();
- WriteGeometry(g, sb, includeZ, includeM);
+ WriteGeometry(g, sb, includeZ, includeM, order);
return sb.ToString();
}
- private static void WriteGeometry(ShapeData geometry, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteGeometry(ShapeData geometry, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
var type = geometry.Type;
sb.Append(type.ToString().ToUpperInvariant());
@@ -49,57 +49,57 @@ private static void WriteGeometry(ShapeData geometry, StringBuilder sb, bool inc
}
else sb.Append(" (");
if (type == OGCGeometryType.Point)
- WritePoint(geometry, sb, includeZ, includeM);
+ WritePoint(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.LineString)
- WriteLineString(geometry, sb, includeZ, includeM);
+ WriteLineString(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.Polygon)
- WritePolygon(geometry, sb, includeZ, includeM);
+ WritePolygon(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.MultiPoint)
- WriteMultiPoint(geometry, sb, includeZ, includeM);
+ WriteMultiPoint(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.MultiLineString)
- WriteMultiLineString(geometry, sb, includeZ, includeM);
+ WriteMultiLineString(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.MultiPolygon)
- WriteMultiPolygon(geometry, sb, includeZ, includeM);
+ WriteMultiPolygon(geometry, sb, includeZ, includeM, order);
else if (type == OGCGeometryType.GeometryCollection)
- WriteGeometryCollection(geometry, sb, includeZ, includeM);
+ WriteGeometryCollection(geometry, sb, includeZ, includeM, order);
else
throw new ArgumentException("Invalid Geometry Type");
sb.Append(")");
}
- private static void WritePoint(ShapeData point, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WritePoint(ShapeData point, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
- WriteCoordinate(point.GetPointN(1), sb, includeZ, includeM);
+ WriteCoordinate(point.GetPointN(1), sb, includeZ, includeM, order);
}
- private static void WriteMultiPoint(ShapeData points, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteMultiPoint(ShapeData points, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
for (int i = 0; i < points.NumPoints; i++)
{
if (i > 0) sb.Append(",");
- WriteCoordinate(points.GetPointN(i+1), sb, includeZ, includeM);
+ WriteCoordinate(points.GetPointN(i+1), sb, includeZ, includeM, order);
}
}
- private static void WriteLineString(ShapeData line, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteLineString(ShapeData line, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
- WriteCoordinateCollection(GetVertices(line), sb, includeZ, includeM);
+ WriteCoordinateCollection(GetVertices(line), sb, includeZ, includeM, order);
}
- private static void WriteMultiLineString(ShapeData lines, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteMultiLineString(ShapeData lines, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
sb.Append('(');
for (int i = 0; i < lines.NumGeometries; i++)
{
if (i > 0) sb.Append("),(");
- WriteCoordinateCollection(GetVertices(lines.GetRing(i)), sb, includeZ, includeM);
+ WriteCoordinateCollection(GetVertices(lines.GetRing(i)), sb, includeZ, includeM, order);
}
sb.Append(")");
}
- private static void WritePolygon(ShapeData polygon, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WritePolygon(ShapeData polygon, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
- WritePolygonContents(polygon, sb, includeZ, includeM);
+ WritePolygonContents(polygon, sb, includeZ, includeM, order);
}
private static IEnumerable GetVertices(ShapeData g)
@@ -107,52 +107,55 @@ private static IEnumerable GetVertices(ShapeData g)
return Enumerable.Range(1, g.NumPoints).Select(s => g.GetPointN(s));
}
- private static void WritePolygonContents(ShapeData polygon, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WritePolygonContents(ShapeData polygon, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
sb.Append('(');
- WriteCoordinateCollection(GetVertices(polygon.GetRing(0)), sb, includeZ, includeM);
+ WriteCoordinateCollection(GetVertices(polygon.GetRing(0)), sb, includeZ, includeM, order);
for (int i = 0; i < polygon.NumInteriorRing; i++)
{
sb.Append("),(");
- WriteCoordinateCollection(GetVertices(polygon.GetRing(i + 1)), sb, includeZ, includeM);
+ WriteCoordinateCollection(GetVertices(polygon.GetRing(i + 1)), sb, includeZ, includeM, order);
}
sb.Append(')');
}
- private static void WriteMultiPolygon(ShapeData polys, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteMultiPolygon(ShapeData polys, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
sb.Append('(');
for (int i = 0; i < polys.NumGeometries; i++)
{
if (i > 0) sb.Append("),(");
- WritePolygonContents(polys.GetGeometryN(i+1), sb, includeZ, includeM);
+ WritePolygonContents(polys.GetGeometryN(i+1), sb, includeZ, includeM, order);
}
sb.Append(')');
}
- private static void WriteGeometryCollection(ShapeData geoms, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteGeometryCollection(ShapeData geoms, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
for (int i = 0; i < geoms.NumGeometries; i++)
{
if (i > 0) sb.Append(",");
- WriteGeometry(geoms.GetGeometryN(i+1), sb, includeZ, includeM);
+ WriteGeometry(geoms.GetGeometryN(i+1), sb, includeZ, includeM, order);
}
}
- private static void WriteCoordinateCollection(IEnumerable coords, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteCoordinateCollection(IEnumerable coords, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
bool firstItem = true;
foreach(var c in coords)
{
if (firstItem) firstItem = false;
else sb.Append(", ");
- WriteCoordinate(c, sb, includeZ, includeM);
+ WriteCoordinate(c, sb, includeZ, includeM, order);
}
}
- private static void WriteCoordinate(PointZM coord, StringBuilder sb, bool includeZ, bool includeM)
+ private static void WriteCoordinate(PointZM coord, StringBuilder sb, bool includeZ, bool includeM, CoordinateOrder order)
{
- sb.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}", coord.X, coord.Y);
+ if(order == CoordinateOrder.XY)
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}", coord.X, coord.Y);
+ else
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}", coord.Y, coord.X);
if (includeZ)
{
if (!double.IsNaN(coord.Z))