hsuetsugu’s diary

ITの技術的なことに関して主に書きます。Rとpythonとd3.jsとAWSとRaspberryPiあたりを不自由なく使いこなせるようになりたいです。

備忘:Tableauでの地図描画について

最近、TableauというBIツールを使う機会が比較的多いのですが、
d3.js+OpenLayersあたりを使って作るのに比べるといろいろ制約があり、
やりにくかったのでその辺を忘れないうちに記載します。


1.行政区ごとの境界データ(shapeファイル)の取得。
 ・e-stat(http://e-stat.go.jp/SG2/eStatGIS/page/download.html)から、国勢調査(小地域)の最新版を選択
f:id:hsuetsugu:20140710205345p:plain
 ・境界データは、世界測地系緯度経度Shape形式のものを、ひたすらクリックし続けてダウンロードする。
f:id:hsuetsugu:20140710213216p:plain


2.行政区ごとのshapeファイルをひとつにまとめてgeojsonで保存。
 ・QuantumGISを使って、複数のshapeファイルをひとつにまとめる。
  ⇒QGISについては全般的に下記のサイトがわかりやすく、この記事を参考にしました。
   08.いくつかのshapeファイルを一つにまとめる - QGIS入門
 ・ひとつにまとめたshpファイルをgeojsonで保存。
  ⇒「レイヤ」>「名前をつけて保存」から、下記のようにgeojsonで保存する。
f:id:hsuetsugu:20140710213809p:plain


3.Tableauで読み込める形式に変換する。 
 ・ここからがTableauでやるときに面倒なのですが、基本、Tableauは表形式のデータだけを読み込みます。
 ・先ほど保存したgeojsonは、下記のように[経度,緯度]をもっているのですが、

{ "type": "Feature", "id": 0, "properties": { "AREA": 51213.36, "PERIMETER": 1166.647, "H22KA07_": 0, "H22KA07_ID": 0, "KEN": "13", "CITY": "101", "KEN_NAME": "東京都", "SITYO_NAME": null, "GST_NAME": "千代田区", "CSS_NAME": null, "HCODE": 8101, "KIHON1": "0340", "DUMMY1": "-", "KIHON2": "06", "KEYCODE1": "101034006", "KEYCODE2": "101034006", "AREA_MAX_F": "M", "KIGO_D": null, "N_KEN": null, "N_CITY": null, "N_C1": 0, "KIGO_E": null, "KIGO_I": null, "TATE": 0, "DIR": 0, "HIGHT": 50, "JIKAKU": 10, "NMOJI": 6, "MOJI": "外神田6丁目", "SEQ_NO2": 2631, "KSUM": 17, "CSUM": 17, "JINKO": 564, "SETAI": 316, "X_CODE": 139.77049, "Y_CODE": 35.70391, "KCODE1": "0340-06", "KEY_CODE": "13101034006", "H22KA08_": 0, "H22KA08_ID": 0, "H22KA09_": 0, "H22KA09_ID": 0, "H22KA10_": 0, "H22KA10_ID": 0, "H22KA11_": 0, "H22KA11_ID": 0, "H22KA12_": 0, "H22KA12_ID": 0, "H22KA13_": 2632, "H22KA13_ID": 2631, "H22KA14_": 0, "H22KA14_ID": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 139.77187928266403, 35.705090241354576 ], [ 139.77182013172339, 35.704492878707001 ], [ 139.77175195421043, 35.703804353445541 ], [ 139.77172652819823, 35.7036224823404 ], [ 139.77165858532641, 35.702946562120907 ], ・・・

  これをTableauで読み込むためには、行政区ごとに{行政区、ID、経度、緯度}というような形式で縦長に変換する必要があります。
  この辺は、どうやるのが簡単なのか、ストレスなくプログラミングできるくらいの言語が自分には何もないのでよくわからないですが、jsonが扱いやすいpythonで下記のようなコードで変換しました。

for data1 in data['features']:
    list= [] 

    attr = {
    'AREA':data1['properties']['AREA'],
    'KEN': data1['properties']['KEN'],
    'CITY': data1['properties']['CITY'],
    'KEN_NAME':data1['properties']['KEN_NAME'],
    'SITYO_NAME':data1['properties']['SITYO_NAME'],
    'GST_NAME':data1['properties']['GST_NAME'],
    'CSS_NAME':data1['properties']['CSS_NAME'],
    'KIHON1':data1['properties']['KIHON1'],
    'KIHON2':data1['properties']['KIHON2'],
    'MOJI':data1['properties']['MOJI'],
    'KEY_CODE':data1['properties']['KEY_CODE'],
    'KEYCODE1':data1['properties']['KEYCODE1'],
    'KEYCODE2':data1['properties']['KEYCODE2'],
    'JINKO':data1['properties']['JINKO'],
    'SETAI':data1['properties']['SETAI'],
    'N_C1':data1['properties']['N_C1'], 
    'KIGO_E':data1['properties']['KIGO_E']
    } 

    cnt=0
    for data2 in data1['geometry']['coordinates'][0]:
        # print data2
        cord={
        'ID':cnt,
        'X':data2[0],
        'Y':data2[1]
        }
        cord.update(attr)
        cnt=cnt+1
        list.append(cord)


4.Tableauで表示
 ・あとは表示するのは、GUIだけで設定すれば表示できます。
 ・ただし、いくつもレイヤーを重ねていく、という作りではないため、
  例えば行政区ごとの人口ヒートマップに対して、何か場所を示すようなポイントデータを重ねるようなことは現在のバージョンでは難しそうです。
 ・米国なんかはある程度細かい地域について、境界データを内部的にもっているようなのですが、日本についてはいまのところ内部でもっているのは都道府県レベルまでのようです。


ちなみに、d3.jsとOpenLayerだと、人口動態のヒートマップに対して、ポイントデータを下記のように重ねることが可能です。
f:id:hsuetsugu:20140710220236p:plain