Como converter de geometria BLOB do SQL Server para outra coisa?


14

Eu tenho um arquivo de dados CSV de terceiros que é uma tabela exportada do SQL Server. Eles simplesmente fizeram select * from fooe enviaram o resultado para um arquivo de texto e o enviaram.

Na tabela deles, há uma coluna do tipo Geometria, portanto, no meu texto bruto, tenho algo como "0xE610000010C47 ..." etc. No momento, carreguei-o em uma tabela no SQL Server como um nvarchar.

Eu previ que seria capaz de voltar ao campo Geometria do meu lado, mas isso não parece ser tão fácil. STGeomFromWKBnão funciona porque na verdade não é um WKB. Não consigo converter a string como Geometry porque ela reclama que não é uma WKT.

Portanto, existe alguma maneira de obter esse valor no SQL Server como se fosse um BLOB de geometria normal? Posso dizer ao SQL Server para tratá-lo como tal?

Encontrei este link que ajudou pelo menos a responder à minha pergunta sobre o que há no SQL Server, mas não me levou até lá: qual é o formato do tipo de dados Geometry do SQLServer 2008


Parece que o WKB (Well Known Binary) existe uma descrição da Esri edndoc.esri.com/arcsde/9.1/general_topics/… mas o formato é OGC (Open Geospatial Consortium). Eu acho que seria um pouco mais fácil usar o builtin funciona como descrito no link fornecido ou em um arquivo msdn.microsoft.com/en-AU/library/bb933960.aspx Eu acho que o problema está no fato de você ter importado uma sequência hexadecimal como texto e não como binária - mas posso ajuda ai eu não tive muito a ver com o back-end do SQL. Talvez você possa perguntar ao superusuário ou ao administrador de banco de dados na stackexchange.
Michael Stimson

@ Peter: você já encontrou alguma dessas soluções para o seu problema?
precisa saber é o seguinte

Respostas:


9

Ao importar os dados para o SQL Server, coloque-os em uma coluna VARBINARY (MAX). Você deve então CASTAR isso como uma geometria ou geografia, conforme necessário. Você precisará ter cuidado para que a sequência 0xE6 ... não seja alterada durante a importação.

Outra opção é fazer uma consulta dinâmica para obter a seleção. Eu coloquei alguns exemplos de conversão abaixo.

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

Com base na resposta do @ MickyT, como você terá uma tabela com seus valores já no WKB (ou o que quer que a chamemos), você gostaria de escrever sql que converterá todos os registros em geometria, em vez de precisar declarar uma variável, etc. etc.

Portanto, se você começar com uma tabela temporária simples que replicaria o WKB em um registro, seria assim:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

Agora, se você tratar isso como uma tabela temporária e envolver um pouco de SQL, terá uma coluna com o WKB e poderá convertê-lo em varbinário, como sugerido acima:

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

em que temp.wkb pode ser a coluna da tabela maior que contém os valores WKB do CSV

Por fim, use o método descrito por MickyT e converta o varbinário em 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

O que retorna geometria e um resultado espacial:

insira a descrição da imagem aqui

EDITAR onde o SRID é declarado? Como o MickyT respondeu, está no binário e você pode agrupar mais uma consulta sql por lá para testar:

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

que produz, e está correto no meu exemplo, 2877 (plano de estado de colorado):

insira a descrição da imagem aqui


1
O SRID está incorporado no binário Geometry. O binário fornecido não é WKB, mas a representação binária real do SQL Servery da Geometria.
MickyT 02/09/2015

@MickyT ah sim! Vou postar mais um trecho para testar ... Obrigado !!!
DPSSpatial

Seria possível adicionar uma coluna Geometria à tabela original e atualizar essa coluna com a Geometria?
Peter Horsbøll Møller 03/09/2015

1
@ PeterHorsbøllMøller Acho que é o movimento certo ... uma vez convertido. Vou trabalhar nisso e postar mais tarde.
amigos estão dizendo sobre dpsspatial

3

Pôster original aqui, quando tentei concluir a inscrição, ele não vinculava o logon da postagem original. De qualquer forma....

Obrigado por toda a ajuda! Eu votarei cada resposta assim que possível e, se puder descobrir como vincular esta conta e a original, posso marcar uma resposta. Além disso, depois de suas dicas, não acredito que perdi o uso em CONVERTvez de CAST. Isso torna muito mais fácil.

Eu acho que meu principal problema foi obter a "string" binária bruta para algo que eu poderia usar. Aqui está uma amostra de como eu o resolvi:

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

parece bom!!! É bom ter tudo isso documentado ... será útil um dia!
amigos estão dizendo sobre dpsspatial

isso foi útil - um funcionário de nosso departamento de BI encontrou esta postagem de forma independente e a usou para fazer com que o SSIS (SQL Server Integration Services) passasse a geometria entre os servidores, que neste momento não é encontrado nativamente no SSIS! !
DPSSpatial
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.