Tableau SDKを利用してCSVから地図を表示する(その１)

# テキストファイルやDBの緯度経度情報を空間ファイルに変換せずにTableauで開く方法 - その１
<img width="693" alt="スクリーンショット 2017-10-16 0.54.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/47064/37535cbd-8ff0-a582-e0c9-ff7203301f5d.png">

## Tableauと緯度経度情報の関係
Tableau 10.2からShape fileやKMLと言った空間ファイルをサポートしました
空間ファイルを利用することで、お手軽・高速にTableau上で扱うことができるようになりました

緯度経度情報が含まれているデータが空間ファイルであれば良いのですが、テキストファイルやDBの場合にライン・ポリゴン形状の緯度経度情報をお手軽・高速にTableau上で扱うには空間ファイルに変換するか、Tableau Extract Data(tde)形式の空間ファイルを必要があります

## 記事の内容
この記事ではTableauと緯度経度情報を取り扱う方法として以下の内容が記載されています
チュートリアルとして、空港の緯度経度情報をTableauで表示するまでを二つのステップに分けて説明いたします

1. Mac OS上でTableau SDK for pythonをインストール
1. Tableau SDK for pythonでテキストファイル(CSV)をTableau Data Extract (TDE) fileに変換

## プログラムの説明
OpenFlights Data(https://openflights.org/data.html)のairports.dat (CSV)をTableau上で表示します
![alt](https://openflights.org/demo/openflights-apdb-2048.png)

## 記事の対象

何らかのコマンドラインプログラムを書いたことがあるTableau User

## 前提
PythonからTableau Extract Data(tde)形式の空間ファイルを作成するには以下の環境が必要になります

- TableauSDK for python
- python 2.7

## この記事の実行環境

この記事は以下の環境で実行しています
- Mac OS X
- Python 2.7.12 (Anaconda 4.2.0 (x86_64))
- Tableau 10.4
- TableauSDK-10300.17.0915.2101

# Tableau SDKのインストール

## zipファイルのダウンロード
[Installing the Tableau SDK](https://onlinehelp.tableau.com/current/api/sdk/en-us/help.htm#SDK/tableau_sdk_installing.htm)からPython版のSDKファイルをダウンロードします
Mac OS Xは、[Mac OS X (64-bit)](https://downloads.tableau.com/tssoftware/Tableau-SDK-Python-OSX-64Bit-10-3-3.tar.gz)を選択しました
※Windows/Mac/Linuxごとにファイルがあります。
<img width="916" alt="スクリーンショット 2017-10-15 17.18.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/47064/28a136f6-d285-6e4f-5207-e3cfd81df02c.png">

## アーカイブの展開
Mac OS XのSafariでダウンロードしたところ、ダウンロードフォルダに"Tableau-SDK-Python-OSX-64Bit-10-3-3.tar.gz"というファイルができました
こちらを"~/work"フォルダ展開します

Mac OS Xの場合はターミナルを開いて以下のコマンドを実行してください
```bash

tar xvzf ~/Downloads/Tableau-SDK-Python-OSX-64Bit-10-3-3.tar.gz -C  ~/work

```
※ファイル名が異なる場合はダウンロードしたSDKのファイル名(*.tar.gz)で読み替えてください

## Tableau  SDKのインストール
解凍フォルダに移動して、 Tableau  SDKをインストールします

pythonのバージョンは以下のコマンドで確認できます

```bash
python --version
Python 2.7.12 :: Anaconda 4.2.0 (x86_64)
```
pythonが2.7ではない場合は、pyenvなどを利用し、python2.7にしてください
https://qiita.com/mogom625/items/b1b673f530a05ec6b423

インストール
```
cd ~/work/TableauSDK-10300.17.0915.2101/
python setup.py build
python setup.py install
sudo python setup.py install
```
※1 出力ログは非表示
※2 sudoは、不要の場合あり



# Tableau SDKを用いてテキストファイルをTDEに変換する
## 作業フォルダ
作業フォルダは"work/tableau_sdk_test"とします
Mac OS Xの場合はターミナルを開いて以下のコマンドを実行してください
```
mkdir ~/work/tableau_sdk_test/
cd ~/work/tableau_sdk_test
```

## 空港の空港の緯度経度情報を入手する
OpenFlights Data(https://openflights.org/data.html)から[airports.dat](https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat)ダウンロードをして、作業フォルダにおきます

## pythonコード

airports.datを保存したフォルダと同じ場所にairport2tde.pyを作成します
内容は以下です

```py:airport2tde.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

###
# @nishiokya 
#
# OpenFlights Data(https://openflights.org/data.html)のairports.dat (CSV)をTableau上で表示できるようになる
#
# Python = 2.7
###

from tableausdk import Type
from tableausdk.Extract import *
import csv,codecs


# Where the origin data comes from
#csvLocation = 'https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat'
csvLocation = 'airports.dat'

# Where the TDE will be written
extractLocation = 'all_airport.tde'

# csv column number for origin/destination coordinates (start count at 0 for the first col in your csv)

#####################################################################
## Process the data and write the TDE
#####################################################################

# 1. ExtractAPIの初期化
ExtractAPI.initialize()

# 2.  TDEファイルの作成
new_extract = Extract(extractLocation)

# 3. TDEファイルのテーブル定義
# https://openflights.org/data.html
table_definition = TableDefinition()
table_definition.addColumn('Airport ID', Type.INTEGER)  # column 0
table_definition.addColumn('Name', Type.UNICODE_STRING)#1
table_definition.addColumn('City', Type.UNICODE_STRING)#2
table_definition.addColumn('Country', Type.UNICODE_STRING)#3
table_definition.addColumn('IATA', Type.UNICODE_STRING)#4
table_definition.addColumn('ICAO', Type.UNICODE_STRING)#5
table_definition.addColumn('geometry', Type.SPATIAL)#6
table_definition.addColumn('Timezone', Type.INTEGER)#7
table_definition.addColumn('DST', Type.UNICODE_STRING)#8
table_definition.addColumn('Tz database time zone', Type.UNICODE_STRING)
table_definition.addColumn('Type', Type.UNICODE_STRING)#10
table_definition.addColumn('Source', Type.UNICODE_STRING)#11

# 4.抽出ファイルがあれば追記、なければ新規
if (new_extract.hasTable('Extract') == False):
  new_table = new_extract.addTable('Extract', table_definition)
else:
  new_table = new_extract.openTable('Extract')

# 5. 新規レコードを作成する
new_row = Row(table_definition)  

# 6. 空港データを読み込んでTDEに抽出
with codecs.open(csvLocation, 'r') as csvfile:
  csvreader = csv.reader(csvfile, delimiter=',')

  
  for row in (csvreader):
    """WKT POINT(LON LAT)"
    https://ja.wikipedia.org/wiki/Well-known_text
    """
    point = 'POINT('+(row[7])+' '+(row[6])+')'
    print (point)
   
    new_row.setInteger(0, int(row[0]))
    new_row.setString(1, row[1].decode('utf-8'))
    new_row.setString(2, row[2].decode('utf-8'))
    new_row.setString(3, row[3].decode('utf-8'))
    new_row.setString(4, row[4])
    new_row.setString(5, row[5])
    new_row.setSpatial(6, point)
    new_row.setInteger(7, int(row[8]))
    new_row.setString(8, row[9])
    new_row.setString(9, row[10])
    new_row.setString(10, row[11])
    new_row.setString(11, row[12])
   
    new_table.insert(new_row)

# 7. TDEファイルの保存
new_extract.close()

# 8. ExtractAPI　のクリーン
ExtractAPI.cleanup()

```
## pythonの実行

Mac OS Xの場合はターミナルを開いて以下のコマンドを実行してください
成功すれば、all_airport.tdeというファイルができるはずです

```
python airport2tde.py
```

## Tableauでの確認
世界中を表示
<img width="693" alt="スクリーンショット 2017-10-16 0.54.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/47064/87031d0b-4994-c95a-b265-093f4751adfc.png">

日本だけ
<img width="756" alt="スクリーンショット 2017-10-16 0.56.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/47064/4a89e44b-5fd8-53d7-ac8e-d149900a5928.png">

デザインは興味ないんで。。。。

# お願い

今回の記事は緯度経度情報を、空間ファイルではなくTDEに変換する手法の使い方を説明しました
ただしTableau SDKによるプログラム作成が必要なので面倒な作業です
CSVファイルやDB内部の緯度経度情報を変換処理を介さずにTableauで表示できたほうがよいですよね？

CSVファイルやDB内部の緯度経度情報をTableauで表示のことを実現したい人が以下のTableau IDEASに要望を出しています　
[Plot WKT fields directly/Tableau Community](https://community.tableau.com/ideas/5494)

Tableauでは、新機能をコミュニティーからの要望が多いものから実現するそうです、もし賛同いただけるようでしたら、１票いれてください

<img width="903" alt="Vote" src="https://qiita-image-store.s3.amazonaws.com/0/47064/5e232b87-4e4d-b203-792e-672d7a325e20.png">

ログインが必要ですが、投票よろしく:bow_tone3:お願いします

# 関連情報
- https://onlinehelp.tableau.com/current/api/sdk/en-us/help.htm
- https://github.com/sarahbat/Examples-using-TableauSDK/tree/master/postgisToTde
- https://community.tableau.com/ideas/5494