SQL ServerではじめてのGIS

 本日開催された Database Study Panel vol.1 (ハッシュタグは #dbstudy ) に参加というか視聴させていただきました。

blastengine.connpass.com


その中のお話で、Microsoft SQL ServerLinux版があることを知りました。
docs.microsoft.com


早速試したところ、手元のVM上のUbuntuに、上記サイトの手順でさくっと入れることができました。
マニュアルを軽く眺めると、GIS関連機能が標準で(無料で使用・検証できる express や developerなどでも)使えるようで、これは動かしてみないと、と(パネルディスカッションのお話を聞きながらも、黙々と)試してみた、「最初の第一歩」のお話を書きたいと思います。

インストール

 上記サイトの指示通りに Ubuntu 20.04上にスムーズに入り、動作させることができました。

テーブル定義

 軽くドキュメントみたところ、geometry 型というのはデカルト座標で使うもので、SRSを持つ空間情報型の時は geography 型を使うっぽい感じだったので、その型で定義(まだ理解浅いので誤っているかもしれません)。
 以下の通り、geography型を持つテーブルを定義。

1> CREATE TABLE g1 (id INTEGER, g GEOGRAPHY);
2> go

データの登録

 そもそも geometry と geography があることを分かっていなかったり、ST関数のSTの後ろにアンダースコアがつかなかったり、関数を geography で修飾する必要があったりと、ハマりどころたくさんで試行錯誤の末、以下のようにして登録できました。

1> INSERT INTO g1 VALUES (1, geography::STGeomFromText('POINT(135 35)', 4326));
2> go
(1 rows affected)


1> INSERT INTO g1 VALUES (2, geography::STGeomFromText('LINESTRING(136.12 36.34, 136.12 36.8)', 4326));
2> go
(1 rows affected)

データの確認

 地理情報型のカラムを単純にSELECTしてしまうと、見たい情報が見られないのはMySQLと同じ。ただし、SQL Server では 0xだけ出てきてその後ろは出てくれないんですね。

1> SELECT * FROM g1;
2> go
id          g 
----------- --
          1 0x
          2 0x

(2 rows affected)

 そんなわけで、MySQLで言うところの ST_AsText()を噛ます必要があるわけですが、その使い方もMySQLとは異なりました。カラムに対して後置するようです(カラムのメソッドっぽい書き方)。

1> SELECT id, g.STAsText() FROM g1;
2> go
id                                                                                                                                                                                                                                                                          
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
          1 POINT (135 35)                                                                                                                                                                                                                                                  
          2 LINESTRING (136.12 36.34, 136.12 36.8)                                                                                                                                                                                                                          

(2 rows affected)

その他

 SRSについて、SQL Server では JGD2011(SRS=6668)には対応していないようでした。 JGD2000やWGS84は対応しています。

対応しているSRSについては sys.spatial_reference_systems ビューで確認することができます。定義は以下のとおり。
spatial_reference_id に JGD2011のものである 6668 の値のものが存在していませんでした。

11> exec sp_help 'sys.spatial_reference_systems';
12> go
Name                                                                                                                             Owner                                                                                                                            Type                            Created_datetime       
-------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ------------------------------- -----------------------
spatial_reference_systems                                                                                                        sys                                                                                                                              view                            2022-05-20 13:59:41.520
 
 
Column_name                                                                                                                      Type                                                                                                                             Computed                            Length      Prec  Scale Nullable                            TrimTrailingBlanks                  FixedLenNullInSource                Collation                                                                                                                       
-------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ----------------------------------- ----------- ----- ----- ----------------------------------- ----------------------------------- ----------------------------------- --------------------------------------------------------------------------------------------------------------------------------
spatial_reference_id                                                                                                             int                                                                                                                              no                                            4 10    0     yes                                 (n/a)                               (n/a)                               NULL                                                                                                                            
authority_name                                                                                                                   nvarchar                                                                                                                         no                                          256             yes                                 (n/a)                               (n/a)                               Latin1_General_CI_AI                                                                                                            
authorized_spatial_reference_id                                                                                                  int                                                                                                                              no                                            4 10    0     yes                                 (n/a)                               (n/a)                               NULL                                                                                                                            
well_known_text                                                                                                                  nvarchar                                                                                                                         no                                         8000             yes                                 (n/a)                               (n/a)                               Latin1_General_CI_AI                                                                                                            
unit_of_measure                                                                                                                  nvarchar                                                                                                                         no                                          256             yes                                 (n/a)                               (n/a)                               Latin1_General_CI_AI                                                                                                            
unit_conversion_factor                                                                                                           float                                                                                                                            no                                            8 53    NULL  yes                                 (n/a)                               (n/a)                               NULL                                                                                                                            
 
Identity                                                                                                                         Seed                                     Increment                                Not For Replication
-------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------- ---------------------------------------- -------------------
No identity column defined.                                                                                                                                          NULL                                     NULL                NULL
 
RowGuidCol                                                                                                                      
--------------------------------------------------------------------------------------------------------------------------------
No rowguidcol column defined.                                                                                                   
 
No constraints are defined on object 'sys.spatial_reference_systems', or you do not have permissions.
 
No foreign keys reference table 'sys.spatial_reference_systems', or you do not have permissions on referencing tables.
The object 'sys.spatial_reference_systems' does not have any indexes, or you do not have permissions.


ちなみに、対応SRS数。

1> SELECT COUNT(*) FROM sys.spatial_reference_systems;
2> go
           
-----------
        393

まとめ

 記述方法や、型の基本的な部分にクセはありましたが(というか私の知識がMySQLベースなので、MySQLのほうがクセである可能性はある)、とりあえずデータを入れたり確認したりすることはできるようになりました。
 あとは、MySQLでは「GIS関係の関数が少ないこと」を課題と感じていましたが、SQL Server では如何ほどの関数が使えるのか、また気が向いたら試してみたいと思います。


memo

接続の仕方もかいておかないと、次やろうとした時には忘れちゃってるw

$ sqlcmd -S localhost -U sa -P (パスワードp2p)

(そもそも sqlcmdの中でどんな命令を使えるかも把握しておかないとなぁ。。 カレントスキーマ知ったり切り替えたりする方法も分かっていないし)