0

我需要存储带有一些多边形的静态空间数据,我将 GeoJson 导入我的 SQL Server 以处理辅助数据,一旦我拥有正确的数据,我将我的数据导出到 Json 中(使用FOR JSON PATH)。

现在由于几何是 CLR 类型,我需要将其转换为字符串以允许导出到 JSON。

SELECT 
    Id, Bounds.ToString() as Bounds 
FROM
    ...
FOR JSON PATH

现在这产生了一个 JSON 文件,其效果是

  [{
    "Id": 1,
    "Bounds": "POLYGON ((93.044663537224707 23.410524583651519, ...
  },
  {
    "Id": 2,
    "Bounds": "MULTIPOLYGON (((93.046192725017278 23.666228900665988...
  },

我需要使用它来播种初始静态数据,这些数据将从中加载,但我不知道如何将字符串几何转换为 NetTopology 几何。

我去了哪里,或者我错过了什么?有没有更好的方法让我播种这些数据?或者有没有办法解析我在 EF Core 中的文本来填充几何?

4

1 回答 1

1

我通过进一步研究找到了答案,并且我也完成了测试,所以我想我会与类似船上的任何人分享。

将字符串解析为 Geometry 的方法是使用GMLReader

但为此我们生成 Gml 而不是字符串

SELECT 
Id, Bounds.AsGml() as Bounds 
FROM
    ...

这会在 SQL Server 上生成 Xml

  <Bounds>
    <Polygon xmlns="http://www.opengis.net/gml">
      <exterior>
        <LinearRing>
          <posList>93.044663537224707 23.410524583651519 92.9467955185...

但这只能解决我的一半问题,我需要生成 JSON 并在播种中使用该 JSON,但如果我灵活地使用 XML,我可以通过 XML 的种子数据导出

SELECT 
  [Id],
  [Bounds].AsGml() as Bounds
  ...
FROM ...
FOR XML PATH

会生成一个带有类似数据的 XML。

<row>
  <Id>1</Id>
  <Bounds>
    <Polygon xmlns="http://www.opengis.net/gml">
      <exterior>
        <LinearRing>
          <posList>93.044663537224707 23.410524583651519 92.9467955185...

所以我决定将生成的 GML 编码为 Base64 以生成 JSON,这个 Base64 将在解析几何以进行播种时被解码。

    CREATE FUNCTION [dbo].[Geometry_Encode_Gml_Base64]
    (
        @value geometry
    )
    RETURNS varchar(max)
    AS
    BEGIN
        DECLARE @source varbinary(max) = convert(varbinary(max), @value.AsGml())
        RETURN cast(N'' as xml).value('xs:base64Binary(sql:variable("@source"))', 'varchar(max)')
    END

并通过执行查询生成 JSON

SELECT 
  [Id],
  dbo.Geometry_Encode_Gml_Base64([Bounds]) as Bounds
  ...
FROM ...
FOR JSON PATH

这会产生 JSON 之类的,

[
  {
    "Id": 1,
    "Bounds": "\/\/48AFAAbwBsAHkAZwBvAG4AIAB4AG0AbABuAHMAPQAiAGgAdAB0AH..."
}, ...

现在,在阅读和播种时,我可以简单地解码 Base64 字符串并使用 GMLReader 读取它

GMLReader gmlReader = new GMLReader(NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326));

Geometry bounds = gmlReader.Read(DecodeBase64(jsonRow.Bounds))

注意:DecodeBase64 应该使用您的数据库用于解码的编码(Unicode/Utf8 等)

警告:我在解码后使用 GMLReader 加载提取的 GML 时遇到问题,因为添加了一些非法字节(SQL Server?)如果您发现相同的问题,请查看如何解决XmlException: Data at root级别无效。第 1 行,位置 1。

于 2020-08-27T18:55:09.380 回答