Гео JSON до SQL география - PullRequest
       22

Гео JSON до SQL география

0 голосов
/ 15 апреля 2020

Я пытаюсь создать географический объект на сервере SQL 2019 из Geo JSON.

Файл Geo JSON действителен. Когда я создаю геометрический объект, он работает. Но когда я изменяю тип данных на географию, возникает много разных проблем проверки, особенно с многоугольниками и многоугольниками с внутренними кольцами.

Исходным файлом является NUTS_RG_60M_2016_4326_LEVL_1.geo json в Geo JSON Zip-файле .

Вот мой SQL код. Я перепробовал много разных вариантов, так что это немного грязно:

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'D:\ref-nuts-2016-60m\NUTS_RG_60M_2016_4326_LEVL_1.geojson', SINGLE_CLOB) as j


SELECT CtrCode AS CtrCode, NutsName AS NutsName, LvlCode AS LvlCode, Fid AS Fid, NutsId AS NutsId , GeoType AS GeoType, 
'POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')' AS PolString, 
(CASE WHEN geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).STIsValid() = 1 THEN geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).ReorientObject() ELSE geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).MakeValid() END).ToString() AS PolStringCorrected,
CASE WHEN geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).STIsValid() = 1 THEN geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).ReorientObject() ELSE geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).MakeValid() END AS Spat, geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).IsValidDetailed() AS Valid,
geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).STIsValid() AS Val ,
geography::STGeomFromText('POLYGON(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')', 4326).MakeValid().EnvelopeAngle() AS Angle 
FROM   
(
     SELECT 
       CtrCode AS CtrCode, NutsName AS NutsName, LvlCode AS LvlCode, Fid AS Fid, NutsId AS NutsId , co.GeoType AS GeoType, d.[Key] AS CtrKey, '(' + STRING_AGG(CAST(Long + ' ' + Lat as varchar(max)), ',') + ')' AS test
    FROM
        OPENJSON(@JSON, '$.features') AS root
        CROSS APPLY OPENJSON (root.value, '$.properties')
        WITH (
           CtrCode nchar(2) '$.CNTR_CODE',
           NutsName nvarchar(200) '$.NUTS_NAME',
           LvlCode int '$.LEVL_CODE',
           Fid nvarchar(6) '$.FID',
           NutsId nvarchar(6) '$.NUTS_ID') AS pr
        CROSS APPLY OPENJSON (root.value, '$.geometry')
        WITH (GeoType nvarchar(200) '$.type') AS co
        CROSS APPLY OPENJSON (root.value, '$.geometry.coordinates')
AS d
        CROSS APPLY OPENJSON (d.value)
        WITH
            (
                Long varchar(100) '$[0]',
                Lat varchar(100) '$[1]'
            ) AS t
WHERE LvlCode = 1 AND GeoType = 'Polygon'
GROUP BY CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType, d.[Key]
) AS l2
GROUP BY CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType
UNION ALL
SELECT CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType, 
'MULTIPOLYGON(' + STRING_AGG(CAST(l1Value AS varchar(max)), ',') + ')' AS PolString, 
(CASE WHEN geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).STIsValid() = 1 THEN geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326) ELSE geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).MakeValid() END).ToString()  AS PolStringCorrected, 
CASE WHEN geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).STIsValid() = 1 THEN geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326) ELSE geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).MakeValid() END AS Spat, 
geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).IsValidDetailed() AS Valid,
geography::STMPolyFromText ('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).STIsValid() AS Val, 
geography::STGeomFromText('MULTIPOLYGON(' + STRING_AGG(CAST(l1Value as varchar(max)), ',') + ')', 4326).MakeValid().EnvelopeAngle() AS Angle 
FROM
(
SELECT CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType, '(' + STRING_AGG(CAST(test AS varchar(max)), ',') + ')' AS l1Value FROM
(
SELECT 
       CtrCode AS CtrCode, NutsName AS NutsName, LvlCode AS LvlCode, Fid AS Fid, NutsId AS NutsId , co.GeoType AS GeoType, d.[Key] AS CtrKey, t.[Key] AS PolKey, '(' + STRING_AGG(CAST(Long + ' ' + Lat as varchar(max)), ',') + ')' AS test
    FROM
        OPENJSON(@JSON, '$.features') AS root
        CROSS APPLY OPENJSON (root.value, '$.properties')
        WITH (
           CtrCode nchar(2) '$.CNTR_CODE',
           NutsName nvarchar(200) '$.NUTS_NAME',
           LvlCode int '$.LEVL_CODE',
           Fid nvarchar(6) '$.FID',
           NutsId nvarchar(6) '$.NUTS_ID') AS pr
        CROSS APPLY OPENJSON (root.value, '$.geometry')
        WITH (GeoType nvarchar(200) '$.type') AS co
        CROSS APPLY OPENJSON (root.value, '$.geometry.coordinates')
AS d
        CROSS APPLY OPENJSON (d.value)

  AS t
  CROSS APPLY OPENJSON (t.value) 
        WITH
            (
                Long varchar(100) '$[0]',
                Lat varchar(100) '$[1]'
            ) 
  AS ha

WHERE LvlCode = 1 AND GeoType = 'Multipolygon'
GROUP BY CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType, d.[Key], t.[Key]
) AS l1
GROUP BY CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType, CtrKey
) AS l2
GROUP BY CtrCode, NutsName, LvlCode, Fid, NutsId, GeoType
ORDER BY NutsId
...