Я пытаюсь создать географический объект на сервере 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