Ищите противоположность SqlGeometryBuilder: Как я могу разложить SqlGeometry?
Я знаю как составитьSqlGeometry
с помощью SqlGeometryBuilder
, например:
// using Microsoft.SqlServer.Types;
SqlGeometryBuilder geometryBuilder = new SqlGeometryBuilder();
geometryBuilder.SetSrid(…);
geometryBuilder.BeginGeometry(OpenGisGeometryType.Polygon);
geometryBuilder.BeginFigure(0, 0);
geometryBuilder.AddLine(…);
…
geometryBuilder.EndFigure();
geometryBuilder.EndGeometry();
SqlGeometry geometry = geometryBuilder.ConstructedGeometry;
Когда SqlGeometry
построен, это в значительной степени непрозрачный объект, и проверка его составных частей (например, сегментов линий, из которых состоит его граница, и конечных точек этих линий) с использованием ST…
методы методы (STNumPoints
, STPointN
, STNumCurves
, STCurveN
, STBoundary
и т. д.) мне немного тяжеловато.
Есть ли что-то в Microsoft.SqlServer.Types
или библиотека классов.NET Framework, которая является логической противоположностью SqlGeometryBuilder
то есть то, что я мог бы использовать для разложенияSqlGeometry
в составные части? Я полагаю, что то, что я ищу, может использовать шаблон посетителей.
1 ответ
Microsoft.SqlServer.Types
API does offer functionality opposite to SqlGeometryBuilder
, in the form of the SqlGeometry.Populate(IGeometrySink110)
метод.
This method accepts an object implementing the IGeometrySink110
interface, whose definition very closely mirrors that of SqlGeometryBuilder
, The method will "replay" the method calls that were used on a SqlGeometryBuilder
in order to construct the SqlGeometry
,
Например, учитывая SqlGeometry geometry
as shown in the question above, as well as the following IGeometrySink110
реализация:
class ConsoleGeometrySink : IGeometrySink110
{
public void SetSrid(int srid)
{
Console.WriteLine($"SetSrid(srid: {srid})");
}
public void BeginGeometry(OpenGisGeometryType type)
{
Console.WriteLine($"BeginGeometry(type: {type})");
}
public void BeginFigure(double x, double y, double? z, double? m)
{
Console.WriteLine($"BeginFigure(x: {x}, y: {y}, z: {z}, m: {m})");
}
public void AddCircularArc(double x1, double y1, double? z1, double? m1,
double x2, double y2, double? z2, double? m2)
{
Console.WriteLine($"AddCircularArc(x1: {x1}, y1: {y1}, z1: {z1}, m1: {m1}, " +
$"x2: {x2}, y2: {y2}, z2: {z2}, m2: {m2})");
}
public void AddLine(double x, double y, double? z, double? m)
{
Console.WriteLine($"AddLine(x: {x}, y: {y}, z: {z}, m: {m})");
}
public void EndFigure()
{
Console.WriteLine($"EndFigure()");
}
public void EndGeometry()
{
WriteLine($"EndGeometry()");
}
}
призвание geometry.Populate(new ConsoleGeometrySink())
выведет следующее:
SetSrid(srid: …)
BeginGeometry(type: Polygon)
BeginFigure(x: 0, y: 0, z: , m: )
AddLine(…)
…
EndFigure()
EndGeometry()
which mirrors exactly the original steps performed to build the SqlGeometry
,