寻找 SqlGeometryBuilder 的对立面:如何分解 SqlGeometry?
Looking for the opposite of SqlGeometryBuilder: How can I decompose a SqlGeometry?
我知道如何使用SqlGeometryBuilder
编写SqlGeometry
,例如:
// 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
,它几乎就是一个不透明的对象,并使用 [= 检查其组成部分(例如,构成其边界的线段,以及这些线的端点) 14=] methods methods (STNumPoints
, STPointN
, STNumCurves
, STCurveN
, STBoundary
, etc.) 感觉有点麻烦。
Microsoft.SqlServer.Types
或 .NET Framework Class 库中是否有与 SqlGeometryBuilder
逻辑相反的东西,即我可以用来 分解的东西a SqlGeometry
成其组成部分?我想我正在寻找的东西可能会使用访问者模式。
Microsoft.SqlServer.Types
API确实以the SqlGeometry.Populate(IGeometrySink110)
method.[=25的形式提供与SqlGeometryBuilder
相反的功能=]
此方法接受实现 the IGeometrySink110
interface 的对象,其定义与 SqlGeometryBuilder
的定义非常相似。该方法将 "replay" 在 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
.
时执行的原始步骤
我知道如何使用SqlGeometryBuilder
编写SqlGeometry
,例如:
// 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
,它几乎就是一个不透明的对象,并使用 [= 检查其组成部分(例如,构成其边界的线段,以及这些线的端点) 14=] methods methods (STNumPoints
, STPointN
, STNumCurves
, STCurveN
, STBoundary
, etc.) 感觉有点麻烦。
Microsoft.SqlServer.Types
或 .NET Framework Class 库中是否有与 SqlGeometryBuilder
逻辑相反的东西,即我可以用来 分解的东西a SqlGeometry
成其组成部分?我想我正在寻找的东西可能会使用访问者模式。
Microsoft.SqlServer.Types
API确实以the SqlGeometry.Populate(IGeometrySink110)
method.[=25的形式提供与SqlGeometryBuilder
相反的功能=]
此方法接受实现 the IGeometrySink110
interface 的对象,其定义与 SqlGeometryBuilder
的定义非常相似。该方法将 "replay" 在 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
.