Як конвертувати з геометрії SQL Server BLOB в щось інше?


14

У мене є файл даних CSV від третьої сторони, яка є експортованою таблицею SQL Server. Вони просто зробили select * from fooі вивели результат у текстовий файл і надіслали його.

У їхній таблиці стовпчик типу Геометрія, тому у своєму сирому тексті у мене є щось на кшталт "0xE610000010C47 ..." і т. Д. На даний момент я завантажив його в таблицю на SQL Server як nvarchar.

Я очікував, що зможу повернути назад у поле Геометрії на своєму кінці, але це здається не таким простим. STGeomFromWKBне працює, оскільки це насправді не WKB. Я не можу призначити рядок як Geometry, оскільки він скаржиться, що це не WKT.

Отже, чи можна отримати це значення на SQL Server так, ніби це нормальна геометрія BLOB? Чи можу я сказати SQL Server, щоб він ставився до цього як до такого?

Я знайшов це посилання, яке допомогло хоча б відповісти на моє запитання про те, що є у SQL Server, але не зрозуміло мене там: який формат даних даних про геометрію SQLServer 2008


Схоже на WKB (добре відомий бінарний) є опис Esri edndoc.esri.com/arcsde/9.1/general_topics/…, але формат є OGC (Відкритий геопросторовий консорціум), я б подумав, що було б трохи простіше використовувати вбудований функції, як описано на наданому посиланні або в одному з перерахованих msdn.microsoft.com/en-AU/library/bb933960.aspx Я думаю, що проблема полягає в тому, що ви імпортували шістнадцяткову рядок як текст, а не насправді як бінарний - але я можу Допоможіть там, я не мав багато спільного з бекендом SQL. Можливо, ви можете запитати на Super User або DB Admin на stackexchange.
Майкл Стімсон

@Peter Ви коли-небудь знайшли вирішення проблеми?
DPSSpace

Відповіді:


9

Коли ви імпортуєте дані на SQL Server, покладіть їх у стовпець VARBINARY (MAX). Тоді ви зможете закинути це як необхідну геометрію чи географію. Вам потрібно бути обережним, щоб під час імпорту рядок 0xE6 ... не змінювався.

Інший варіант - зробити динамічний запит, щоб отримати вибір. Я прикладаю кілька прикладів перетворення нижче.

-- As a varchar and binary
DECLARE @NV AS NVARCHAR(MAX) = '0xE610000001040E0000002AA57BA76F5446C027B8FD971024654007517714795446C00C42473D1624654094CFCDE3795446C0D3F576B91624654068507E9C7A5446C0D7BE805E18246540F2FC444A7C5446C0E93DDF6019246540B4CA4C697D5446C0D5DF5C0D1A2465401A0923AC7C5446C08183DE3F1A2465407599E1907B5446C0E2A8818B1A24654058B4805A7A5446C0A70261DE1A24654089729F5C775446C072080BDD1B2465401AAC24A8745446C057CB10FE1C2465403D16A5446E5446C05A20FEE21A246540658BA4DD685446C00907FFA3172465402AA57BA76F5446C027B8FD971024654001000000020000000001000000FFFFFFFF0000000003' 
DECLARE @NB AS VARBINARY(MAX) = 0xE610000001040E0000002AA57BA76F5446C027B8FD971024654007517714795446C00C42473D1624654094CFCDE3795446C0D3F576B91624654068507E9C7A5446C0D7BE805E18246540F2FC444A7C5446C0E93DDF6019246540B4CA4C697D5446C0D5DF5C0D1A2465401A0923AC7C5446C08183DE3F1A2465407599E1907B5446C0E2A8818B1A24654058B4805A7A5446C0A70261DE1A24654089729F5C775446C072080BDD1B2465401AAC24A8745446C057CB10FE1C2465403D16A5446E5446C05A20FEE21A246540658BA4DD685446C00907FFA3172465402AA57BA76F5446C027B8FD971024654001000000020000000001000000FFFFFFFF0000000003

-- Failing conversions
SELECT CAST(@NV AS Geometry)
SELECT CAST(CAST(@NV AS VARBINARY(MAX)) AS Geometry)
-- Correct conversion
SELECT CAST(@NB AS Geometry)
EXEC('SELECT CAST(' + @NV + ' AS Geometry)')

6

Спираючись на відповідь @ MickyT, оскільки ви будете мати таблицю зі своїми значеннями, які вже сидять у WKB (або як ми це називаємо), ви хочете написати sql, який перетворить усі записи на геометрію, а не потрібно оголосити змінну тощо.

Отже, якщо ви почнете з простої темп-таблиці, яка б повторювала WKB в одному записі, це виглядатиме так:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

Тепер, якщо ви ставитесь до цього як до темп-таблиці і оберніть навколо неї деякий SQL, у вас є стовпець із WKB там, і ви можете перетворити його на варбінар, як було запропоновано вище:

select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp

де temp.wkb може бути стовпцем у вашій більшій таблиці, що містить значення WKB від CSV

Нарешті, використовуйте метод, описаний MickyT, і перетворіть варбінарій на геометрію:

select 
cast(geomconvert.geombinary as geometry) as geom
 from (
select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp
) as geomconvert

Що повертає геометрію та просторовий результат:

введіть тут опис зображення

EDIT, де SRID оголошується? Як відповів MickyT, він знаходиться у двійковому тексті, і ви можете вкласти ще 1 sql запит, щоб перевірити:

select top 1 getsrid.geom.STSrid from (

select 
cast(geomconvert.geombinary as geometry) as geom
 from (
select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp
) as geomconvert

) as getsrid

що дає, і це правильно в моєму прикладі, 2877 (площина штату Колорадо):

введіть тут опис зображення


1
SRID вбудований у двійковий файл Geometry. Бінарний файл, який постачається, не є WKB, а фактичним бінарним поданням геометрії SQL Servery.
MickyT

@MickyT ах так! Я опублікую ще один фрагмент для тестування ... Дякую !!!
DPSSpatial

Чи можна було б додати стовпчик "Геометрія" до початкової таблиці та оновити цей стовпець за допомогою "Геометрії"?
Пітер Хорсбёлл Мёллер

1
@ PeterHorsbøllMøller Я думаю, що це правильний крок ... як тільки він перетворений. Я буду працювати над цим і публікувати згодом.
DPSSpatial

3

Оригінальний плакат тут, коли я намагався закінчити реєстрацію, він не пов'язував реєстрацію оригінальної публікації. У всякому разі….

Дякую за всю допомогу! Коли я можу відповісти, я підтверджу кожну відповідь, і, можливо, якщо зможу зрозуміти, як зв’язати цей рахунок та оригінальний, я можу відзначити відповідь. Крім того, після ваших покажчиків я не можу повірити, що я пропустив використання CONVERTзамість цього CAST. Це значно полегшує.

Я думаю, що моя головна проблема полягала в тому, щоб отримати необроблений бінарний "рядок" до чогось, що я міг би використовувати. Ось зразок того, як я це вирішив:

DECLARE @data TABLE (
  ID nvarchar(1024),
  ImportedGeometry nvarchar(max),
  FinalGeometry geometry
  )

  INSERT INTO @data (ID, ImportedGeometry) values ('1', '0xE6100000010C4703780B24B855C061C3D32B65093540')
  INSERT INTO @data (ID, ImportedGeometry) values ('2', '0xE6100000010C96438B6CE7D359C0BD5296218E853440')

select 
d.ID,
d.ImportedGeometry,
CONVERT(varbinary(max), d.ImportedGeometry, 1) as ConvertedGeometryBin,
(cast(CONVERT(varbinary(max), d.ImportedGeometry, 1) as geometry)) as FinalGeometry
from @data d

UPDATE @data
SET FinalGeometry = (cast(CONVERT(varbinary(max), ImportedGeometry, 1) as geometry))

select 
d.ID,
d.FinalGeometry,
d.FinalGeometry.STAsText(),
d.FinalGeometry.STSrid
from @data d

виглядає добре!!! Добре, щоб все це було задокументовано ... це стане в нагоді одного дня!
DPSSpatial

це було корисно - співробітник нашого відділу BI самостійно знайшов цю посаду та використав її, щоб змусити SQL Server Integration Services (SSIS) передавати геометрію назад і назад між серверами, яких на даний момент не знайдено в SSIS !! !
DPSSpatial
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.