Jak przekonwertować BLOB geometrii SQL Server na coś innego?

14

Mam plik danych CSV od strony trzeciej, który jest eksportowaną tabelą SQL Server. Po prostu zrobili select * from fooi wyrzucili wynik do pliku tekstowego i przesłali go.

W ich tabeli znajduje się kolumna typu Geometria, więc w moim surowym tekście mam coś takiego jak „0xE610000010C47 ...” itp. W tej chwili załadowałem go do tabeli w SQL Server jako nvarchar.

Spodziewałem się, że po mojej stronie będę mógł wrócić do pola geometrii, ale nie wydaje się to takie łatwe. STGeomFromWKBnie działa, ponieważ tak naprawdę nie jest to WKB. Nie mogę rzucić sznurka jako geometrii, ponieważ narzeka, że ​​to nie jest WKT.

Czy jest jakiś sposób, aby uzyskać tę wartość do programu SQL Server, tak jakby to był normalny BLOB geometrii? Czy mogę powiedzieć SQL Serverowi, aby traktował go jako taki?

Znalazłem ten link, który pomógł przynajmniej odpowiedzieć na moje pytanie dotyczące tego, co jest w SQL Server, ale nie doprowadził mnie do końca: jaki jest format typu danych geometrii SQLServer 2008

Piotr
źródło
Wygląda na to, że WKB (Well Famous Binary) zawiera opis Esri edndoc.esri.com/arcsde/9.1/general_topics/…, ale format to OGC (Open Geospatial Consortium). Myślę, że nieco łatwiej byłoby użyć wbudowanego funkcje opisane na podany link, lub wymieniony msdn.microsoft.com/en-AU/library/bb933960.aspx myślę problemowe kłamstwa w które zostały zaimportowane ciąg szesnastkowy jako tekst, a nie rzeczywiście jako binarny - ale mogę pomóżcie, że nie miałem wiele wspólnego z backendem SQL. Być może możesz poprosić superużytkownika lub administratora DB o zamianie stosów.
Michael Stimson,
@Peter Czy kiedykolwiek znalazłeś jedno z tych rozwiązań swojego problemu?
DPSSpatial

Odpowiedzi:

9

Podczas importowania danych do programu SQL Server umieść je w kolumnie VARBINARY (MAX). Powinieneś być w stanie CAST to jako Geometria lub Geografia, zgodnie z wymaganiami. Trzeba uważać, aby łańcuch 0xE6 ... nie został zmieniony podczas importu.

Inną opcją jest wykonanie dynamicznego zapytania, aby uzyskać wybór. Poniżej podaję kilka przykładów konwersji.

-- 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)')
MickyT
źródło
6

Opierając się na odpowiedzi @ MickyT, ponieważ będziesz mieć tabelę ze swoimi wartościami już w WKB (lub jakkolwiek to nazwiemy), powinieneś napisać sql, który skonwertuje wszystkie rekordy na geometrię, zamiast konieczności zadeklarować zmienną itp. itd.

Więc jeśli zaczniesz od prostej tabeli tymczasowej, która replikowałaby WKB w jednym rekordzie, wyglądałoby to tak:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

Teraz, jeśli traktujesz to jako tabelę tymczasową i otaczasz trochę SQL, masz tam kolumnę z WKB i możesz przekonwertować ją na varbinary, jak sugerowano powyżej:

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

gdzie temp.wkb może być kolumną w twojej większej tabeli zawierającą wartości WKB z CSV

Na koniec użyj metody opisanej przez MickyT i przekonwertuj varbinary na geometrię:

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

Która zwraca geometrię i wynik przestrzenny:

wprowadź opis zdjęcia tutaj

EDYCJA gdzie deklarowany jest SRID? Jak odpowiedział MickyT, jest w pliku binarnym i możesz owinąć jeszcze jedno zapytanie SQL, aby przetestować:

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

co daje i jest poprawne w moim przykładzie 2877 (płaszczyzna stanu Kolorado):

wprowadź opis zdjęcia tutaj

DPSSpatial
źródło
1
SRID jest wbudowany w plik binarny geometrii. Dostarczony plik binarny to nie WKB, ale rzeczywista reprezentacja binarna Geometrii przez serwer SQL.
MickyT,
@MickyT ah tak! Prześlę jeszcze jeden fragment do przetestowania ... Dziękuję !!!
DPSSpatial
Czy byłoby możliwe dodanie kolumny Geometria do oryginalnej tabeli i zaktualizowanie tej kolumny za pomocą Geometrii?
Peter Horsbøll Møller,
1
@ PeterHorsbøllMøller Myślę, że to właściwy ruch ... po przekształceniu. Popracuję nad tym i piszę później.
DPSSpatial
3

Oryginalny plakat tutaj, kiedy próbowałem dokończyć rejestrację, nie łączyłem logowania do oryginalnego postu. Tak czy inaczej....

Dzięki za wszelką pomoc! Będę głosować za każdą odpowiedzą, gdy będę w stanie, a może jeśli uda mi się dowiedzieć, jak połączyć to konto z oryginalnym, mogę zaznaczyć odpowiedź. Poza tym po twoich wskazówkach nie mogę uwierzyć, że przegapiłem użycie CONVERTzamiast CAST. To znacznie ułatwia.

Myślę, że moim głównym problemem było doprowadzenie surowego binarnego „łańcucha” do czegoś, czego mógłbym użyć. Oto próbka rozwiązania tego problemu:

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
użytkownik57679
źródło
wygląda dobrze!!! Dobrze mieć to wszystko udokumentowane ... przyda się kiedyś!
DPSSpatial
przydało się to - kolega z naszego działu BI niezależnie znalazł ten post i wykorzystał go, aby SQL Server Integration Services (SSIS) przekazywał geometrię tam iz powrotem między serwerami, co w tym momencie nie jest natywnie w SSIS !! !
DPSSpatial