#sql #json #sql-server #arcgis
#sql #json #sql-сервер #arcgis
Вопрос:
У меня есть столбец SQL Server, который содержит массив JSON (последовательность координат точек), которые составляют форму многоугольника. Это правильно отформатированный JSON, который представляет собой массив точек. Я хочу преобразовать этот массив JSON в столбец вычисляемой геометрии. Приведенный ниже пример представляет собой ОДНУ запись, но мне нужно, чтобы столбец был вычислен, поскольку я получаю эти данные в реальном времени в базу данных.
[
{"X":-135.4993896484375,"Y":40.8944206237793},
{"X":-135.49931335449219,"Y":40.89435958862305},
{"X":-135.4993667602539,"Y":40.89413070678711},
{"X":-135.49922180175781,"Y":40.8939094543457},
{"X":-135.49891662597656,"Y":40.89371109008789},
{"X":-135.49922180175781,"Y":40.89352035522461},
{"X":-135.49994659423828,"Y":40.89336013793945},
{"X":-135.5006332397461,"Y":40.893218994140625},
{"X":-135.50110626220703,"Y":40.892738342285156},
{"X":-135.4993896484375,"Y":40.8944206237793}
]
Мой новый столбец может называться Shape или что-нибудь еще. Как мне проанализировать это и объединить его с STPolyFromText, чтобы перенести это в новый вычисляемый столбец?
Ответ №1:
create or alter function dbo.jsonpolygon(@j nvarchar(max))
returns geometry
as
begin
declare @geom geometry;
select
@geom = 'POLYGON((' string_agg(concat(v.X, ' ', v.Y), ',') within group (order by j.[key]) '))'
from openjson(case when isjson(@j) = 1 then @j end) as j
cross apply openjson(case when isjson(j.value) = 1 then j.value end)
with
(
X varchar(100),
Y varchar(100)
) as v;
return(@geom);
end
go
create table xyz -- table
(
json nvarchar(max),
geom as dbo.jsonpolygon(json)
)
go
insert into xyz(json)
values(
'[
{"X":-135.4993896484375,"Y":40.8944206237793},
{"X":-135.49931335449219,"Y":40.89435958862305},
{"X":-135.4993667602539,"Y":40.89413070678711},
{"X":-135.49922180175781,"Y":40.8939094543457},
{"X":-135.49891662597656,"Y":40.89371109008789},
{"X":-135.49922180175781,"Y":40.89352035522461},
{"X":-135.49994659423828,"Y":40.89336013793945},
{"X":-135.5006332397461,"Y":40.893218994140625},
{"X":-135.50110626220703,"Y":40.892738342285156},
{"X":-135.4993896484375,"Y":40.8944206237793}
]'
), ('12345'), ('[12345]');
/* this will break the calculated column
insert into t(json)
values(
'[
{"X":-135.4993896484375,"Y":40.8944206237793}
]'
)
*/
select *
from xyz;
go
drop table xyz
go
drop function dbo.jsonpolygon
go
Комментарии:
1. Спасибо! Будет ли это работать с использованием столбца? Я использовал значения XY в качестве примера для одной ячейки, но на самом деле у меня тысячи записей, и мне нужна возможность просто ввести имя столбца.
2. ..@zanzibarjack . да, это будет работать для таблицы, вы можете добавить столбец вычисляемой геометрии. Если вы уверены, что все строки json вернут допустимый полигон, то все, что вам нужно сделать, это:
alter table tableX add geomY as dbo.jsonpolygon(jsoncolumnZ)
, просто замените TableX и geomYamp; jsoncolumnY соответствующими именами (нужное вам имя таблицы и вычисляемого столбца, имя столбца, в котором хранятся данные json). Можно сделать функцию менее подверженной ошибкам: для полигона требуется не менее 4 точек, а начальная точка == конечная точка, и вы могли бы включить это в функцию dbo.jsonpolygon() .