Ищите противоположность 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,

Другие вопросы по тегам