PythonからSpatiaLiteへの接続

今回は、PythonからSpatiaLiteデータベースへ接続し空間検索を実施します。

作業手順

今回の作業手順を以下に示します。
1.シェープファイルの入手
国土数値情報のサイト、統計GISのサイトからシェープファイルを入手します。
2.シェープファイルのインポート
今回は、”spatialite_tools”(CLI)を使ってシェープファイルをSpatiaLiteデータベースへインポートします。
3.SpatiaLiteの環境構築
前回の記事を参考に、SpatiaLiteの環境を構築します。
4.Pythonプログラムによる検索
PythonプログラムからSpatiaLiteへ接続して検索を行います。

シェープファイルの入手

以下の国土数値情報ダウンロードサービスからバス停留所(点)のシェープファイルを入手します。

ダウンロードするファイルの情報は、以下となります。

  • 分類:4.交通>バス停留所>東京
  • ファイル名:P11-10_13_GML.zip

次に、統計GISのサイトから国勢調査の小地域データ(以降、町丁目データ)を入手します。

ダウンロードするファイルの情報は、以下となります。

  • 分類:世界測地系緯度経度・Shapefile
  • ファイル名:A002005212015DDSWC13.zip

ファイルを解凍すると、以下のようになります。

D:\data\bus>dir
2012/07/17 13:17 93,545,052 P11-10_13-jgd-g_BusStop.dbf
2012/07/17 13:17 264,588 P11-10_13-jgd-g_BusStop.shp
2012/07/17 13:17 75,668 P11-10_13-jgd-g_BusStop.shx

2018/05/02 18:49 2,795,804 h27ka13.dbf
2018/05/02 18:49 147 h27ka13.prj
2018/05/02 18:49 9,153,524 h27ka13.shp
2018/05/02 18:49 48,180 h27ka13.shx

黄色網掛けの3ファイルがバス停データ、その他の4ファイルが町丁目データです。

シェープファイルのインポート

spatialite_toolの入手

前回の記事では、GUIツール”spatialite_gui”を使ってインポートしましたが、今回はCLIツール”spatialite_tool”を使ってインポートします。
”spatialite_tool”は、こちらのサイトからダウンロードします。
ダウンロードサイトの”current stable version”からOSのビット数(x86、x64)を選択します。

SpatiaLiteダウンロードサイトの画面

表示されるファイル名一覧から”spatialite_tool-4.3.0a-win-x86.7z”(32ビットの場合)をダウンロードして解凍し、パスを設定すれば完了です。

シェープファイルのインポート

バス停データをインポートします。テーブル名(-t)、文字コード(-c)、SRID(-s)を指定します。

>spatialite_tool -i -shp P11-10_13-jgd-g_BusStop -d test.sqlite -t busstop -c Shift_Jis -s 4326 -2
SQLite version: 3.8.11.1
SpatiaLite version: 4.3.0a
Inserted 9446 rows into ‘busstop’ from ‘P11-10_13-jgd-g_BusStop.shp’

同様に、町丁目データもインポートします。

>spatialite_tool -i -shp h27ka13 -d test.sqlite -t area -c Shift_Jis -s 4326 -2
SQLite version: 3.8.11.1
SpatiaLite version: 4.3.0a
Inserted 6010 rows into ‘area’ from ‘h27ka13.shp’

インポートしたデータをQGISで表示すると、以下のようになります。

インポートした町丁目、バス停を表示した地図

SpatiaLiteの環境構築

プログラムに必要な空間拡張モジュール(mod_spatialite)を導入します。
基本的には、こちらのサイトからファイル”mod_spatialite-4.3.0a-win-x86.7z”をダウンロードして展開しパスを通すだけです。なお、64ビット環境でもこのファイルの利用をお勧めします。

SpatiaLiteの環境構築については、以下の記事に詳しく書いてありますので、参考にしてください。

プログラムの作成

ここまでで準備が完了しましたので、プログラムを作成しましょう。
PythonからSpatiaLiteデータベースへアクセス(=SQLiteへのアクセス)するためには、”sqlite3″モジュールのインポートが必要です。Python3系からは、”sqlite3″が標準開発環境に含まれていますので、”pip install”での追加インストールは不要です。

以下にSELECT文にて検索を行うプログラムを例示します。

import sqlite3

def searchBusstop( inAddressName ,inDbPath ):
    # SpatiaLiteとの接続
    con = sqlite3.connect( inDbPath )
    # 拡張モジュールの読み込み
    con.enable_load_extension(True)
    cur = con.cursor()
    cur.execute("SELECT load_extension('mod_spatialite')")
    #cur.execute("SELECT InitSpatialMetaData(1);")
    # 検索の実行
    cur.execute("select a.s_name ,b.P11_001 from area a ,busstop b " +
                "where a.s_name like ? and Contains(a.Geometry ,b.Geometry)" ,("%" + inAddressName + "%",))
    # データの取得
    for row in cur.fetchall():
        print( row )
    # 後処理
    cur.close()
    con.close()

if __name__ == '__main__':
    searchBusstop("三田" ,"D:\\data\\bus\\test.sqlite")

プログラムは、21行目のメイン処理と、3行目から始まるsearchBusstop関数に分かれます。
searchBusstop関数では、SpatiaLiteデータベースのファイル名を指定して接続し空間拡張モジュールを読み込み(5~9行目)ます。次にクエリを実行(12行目)して検索結果を取得、表示する(15行目)とという流れです。
10行目の空間メタデータの初期化は、データベース作成時のみ必要なのでコメントアウトしています。
22行目のメイン処理は、searchBusstop関数に住所名とファイル名を指定して呼び出します。
結果は配列で返却され、以下のように表示されます。

>python busstop.py
(‘三田1丁目’, ‘中ノ橋’)
(‘三田1丁目’, ‘赤羽橋駅’)
(‘三田1丁目’, ‘三田一’)
(‘三田1丁目’, ‘赤羽橋駅前’)
(‘三田2丁目’, ‘慶応義塾大’)
(‘三田2丁目’, ‘芝三西’)
(‘三田2丁目’, ‘慶応義塾大前’)
(‘三田2丁目’, ‘慶応義塾東門’)
(‘三田3丁目’, ‘三田三’)
(‘三田4丁目’, ‘三田四’)
(‘三田5丁目’, ‘魚籃坂下’)
(‘三田5丁目’, ‘三田五’)
(‘三田1丁目’, ‘ウェスティンホテル東京’)
(‘三田2丁目’, ‘茶屋坂’)

1項目目が検索条件として指定した住所名(”三田”を含む住所)、2項目目が該当住所内のバス停名になります。

まとめ

今回は、以下を検証しました。

・spatialite_toolを使ったシェープファイルのインポート
・PythonプログラムからSpatiaLiteデータベースへのアクセス

基本的な内容でしたが、とても簡単に接続できました。