Ищете противоположность 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 на составные части? Я предполагаю, что то, что я ищу, может использовать шаблон посетителя.


person stakx - no longer contributing    schedule 28.11.2016    source источник


Ответы (1)


Microsoft.SqlServer.Types API действительно предлагает функции, противоположные SqlGeometryBuilder, в форме метод SqlGeometry.Populate(IGeometrySink110).

Этот метод принимает объект, реализующий интерфейс IGeometrySink110, определение которого очень близко к интерфейсу SqlGeometryBuilder. Метод «повторяет» вызовы методов, которые использовались для SqlGeometryBuilder, чтобы построить SqlGeometry.

Например, учитывая SqlGeometry geometry, как показано в вопросе выше, а также следующую реализацию 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()

который точно отражает исходные шаги, выполненные для создания файла SqlGeometry.

person stakx - no longer contributing    schedule 28.11.2016