SQL ServerジオメトリBLOBから他の何かに変換する方法は?


14

エクスポートされたSQL ServerテーブルであるサードパーティからのCSVデータファイルがあります。彼らは単にselect * from foo結果をテキストファイルに出力し、それを送信しました。

テーブルにはGeometryタイプの列があるので、生のテキストには「0xE610000010C47 ...」などがあります。現時点では、SQL Serverのテーブルにnvarcharとしてロードしています。

私は自分の側でGeometryフィールドに戻ることができると予想していましたが、それはそれほど簡単ではないようです。 STGeomFromWKB実際にはWKBではないため機能しません。文字列をGeometryとしてキャストできません。WKTではないと文句を言うからです。

それでは、この値を通常のGeometry BLOBのようにSQL Serverに取得する方法はありますか?SQL Serverにそのように処理するように指示できますか?

このリンクを見つけて、少なくともSQL Serverの内容に関する質問に答えることができましたが、そこまでは行きませんでした: SQLServer 2008のGeometryデータ型の形式は何ですか


WKB(Well Known Binary)のように見えますが、Esriの説明edndoc.esri.com/arcsde/9.1/general_topics/…がありますが、形式はOGC(Open Geospatial Consortium)です。提供されたリンクまたは記載されているmsdn.microsoft.com/en-AU/library/bb933960.aspxに記載されているように機能するSQLのバックエンドとはあまり関係ありませんでした。おそらく、stackexchangeのスーパーユーザーまたはDB管理者に尋ねることができます。
マイケルスティムソン

@ピーターは、これらのいずれかがあなたの問題の解決策を見つけたことがありますか?
DPSS16年

回答:


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を記述する必要があります。変数の宣言など。

したがって、1つのレコードでWKBを複製する単純な一時テーブルから始めると、次のようになります。

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

これを一時テーブルとして扱い、SQLをラップすると、WKBが含まれる列が作成され、上記のようにvarbinaryに変換できます。

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

どこtemp.wkbは、 CSVからのWKB値を含む、あなたの大きなテーブルの列することができ

最後に、MickyTで説明されている方法を使用して、varbinaryをジオメトリに変換します。

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

ジオメトリと空間結果を返す:

ここに画像の説明を入力してください

編集 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ああそう!テストのためにもう1つスニペットを投稿します...ありがとうございます!!!
DPSS

元のテーブルにGeometry列を追加し、Geometryでその列を更新することは可能でしょうか?
ピーターホースボルモーラー

1
@PeterHorsbøllMøller私はそれが正しい動きだと思う...それが変換されたら。私はそれに取り組み、後で投稿します。
DPSS

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

いいね!!!このすべてを文書化しておくと便利です...いつか便利になります!
DPSS15年

これは便利でした-BI部門の仲間がこの投稿を独自に見つけ、それを使用してSQL Server Integration Services(SSIS)がサーバー間でジオメトリをやり取りするようにしました。 !
DPSSpatial
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.