Come convertire da BLOB geometria di SQL Server in qualcos'altro?


14

Ho un file di dati CSV di una terza parte che è una tabella di SQL Server esportata. Hanno semplicemente fatto un select * from fooe hanno prodotto il risultato in un file di testo e lo hanno inviato.

Nella loro tabella è una colonna di tipo Geometry, quindi nel mio testo non elaborato ho qualcosa come "0xE610000010C47 ...", ecc. Al momento l'ho caricato in una tabella in SQL Server come nvarchar.

Ho anticipato che sarei stato in grado di tornare indietro in un campo Geometria dalla mia parte, ma non sembra essere così facile. STGeomFromWKBnon funziona perché in realtà non è un WKB. Non posso lanciare la stringa come Geometria perché si lamenta che non è un WKT.

Quindi, c'è un modo per ottenere questo valore in SQL Server come se fosse un normale BLOB di Geometria? Posso dire a SQL Server di trattarlo come tale?

Ho trovato questo link che mi ha aiutato almeno a rispondere alla mia domanda su cosa c'è in SQL Server, ma non mi ha portato fino in fondo: qual è il formato del tipo di dati Geometry di SQL Server 2008


Sembra che WKB (Well Known Binary) ci sia una descrizione Esri edndoc.esri.com/arcsde/9.1/general_topics/… ma il formato è OGC (Open Geospatial Consortium) Penso che sarebbe un po 'più facile usare il builtin funziona come descritto sul collegamento fornito o su uno elencato msdn.microsoft.com/en-AU/library/bb933960.aspx Penso che il problema risieda nel fatto che hai importato una stringa esadecimale come testo e non come binario, ma posso Aiutate lì non ho avuto molto a che fare con il backend di SQL. Forse potresti chiedere a Super User o DB Admin su stackexchange.
Michael Stimson,

@Peter hai mai trovato una di queste soluzioni al tuo problema?
DPSSpatial

Risposte:


9

Quando si importano i dati in SQL Server, inserirli in una colonna VARBINARY (MAX). Dovresti quindi essere in grado di lanciare questo come geometria o geografia come richiesto. Dovrai fare attenzione che la stringa 0xE6 ... non venga modificata durante l'importazione.

Un'altra opzione è eseguire una query dinamica per ottenere la selezione. Ho messo un paio di esempi di conversione di seguito.

-- 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

Partendo dalla risposta di @ MickyT, dato che avrai una tabella con i tuoi valori già presenti in WKB (o come la chiamiamo), vorrai scrivere sql che convertirà tutti i record in geometria, piuttosto che dover dichiarare una variabile, ecc. ecc.

Quindi, se inizi con una semplice tabella temporanea che replica il WKB in un record, sarebbe simile al seguente:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

Ora, se lo tratti come una tabella temporanea e ti avvolgi un po 'di SQL, hai una colonna con il WKB e puoi convertirla in varbinary come suggerito sopra:

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

dove temp.wkb può essere la colonna nella tabella più grande contenente i valori WKB dal CSV

Infine, utilizza il metodo descritto da MickyT e converti il ​​varbinary in geometria:

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

Che restituisce geometria e un risultato spaziale:

inserisci qui la descrizione dell'immagine

EDIT da dove viene dichiarato lo SRID? Come ha risposto MickyT, è nel file binario e puoi avvolgere un'altra query sql lì intorno per testare:

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

quale produce ed è corretta nel mio esempio 2877 (piano di stato colorado):

inserisci qui la descrizione dell'immagine


1
SRID è integrato nel binario Geometry. Il binario che viene fornito non è WKB, ma la rappresentazione binaria effettiva della geometria di SQL Servery.
MickyT

@MickyT ah sì! Pubblicherò un altro frammento per testare ... Grazie !!!
DPSSpatial

Sarebbe possibile aggiungere una colonna Geometry alla tabella originale e aggiornare quella colonna con Geometry?
Peter Horsbøll Møller,

1
@ PeterHorsbøllMøller Penso che sia la mossa giusta ... una volta convertita. Ci lavorerò e pubblicherò più avanti.
DPSSpatial

3

Poster originale qui, quando ho provato a completare l'iscrizione non collegava l'accesso per il post originale. Comunque....

Grazie per tutto l'aiuto! Voterò ogni risposta una volta che sarò in grado di farlo e forse se riesco a capire come collegare questo account e quello originale posso contrassegnare una risposta. Inoltre, dopo i tuoi puntatori non riesco a credere di aver perso usando CONVERTinvece di CAST. Lo rende molto più semplice.

Penso che il mio problema principale sia stato di ottenere la "stringa" binaria grezza in qualcosa che potevo usare. Ecco un esempio di come l'ho risolto:

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

sembra buono!!! Bello avere tutto questo documentato ... ti tornerà utile un giorno!
DPSSpatial

questo è tornato utile - un collega nel nostro dipartimento di BI ha trovato questo post in modo indipendente e lo ha utilizzato per far sì che SQL Server Integration Services (SSIS) passasse avanti e indietro la geometria tra i server, che a questo punto non si trova nativamente in SSIS !! !
DPSSpatial
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.