2016年12月12日月曜日

FOSS4Gで電子海図の世界をのぞく2016 延長戦

これは「FOSS4G 二個目だよ Advent Calendar 2016」の12日目の記事です。

1個目のほうでは、OpenCPNというソフトウェアを使えば、電子海図(ENC)を正しく表示できることをお話ししました。

でもやっぱりQGISで見たい


昨年の記事の中で、ENCをQGISで表示させてみましたが、どうも見た目がいまいちな感じなので、「もう少しマシにならないのか??」と思っていたところ、これを実現させている方がいらっしゃいました。

その方のブログ記事はこちら(フランス語)

やり方はこんな感じです。

  1. SVGファイルをQGISにセットしておく。
  2. ogr2ogrを使って、ENCのオブジェクトごとにshapefileに変換して保存する。
  3. あらかじめレイヤーの設定をしたQGISプロジェクトファイル(.qgs)をshapefileと同じフォルダーにコピーし、プロジェクトファイルをQGISで開く(プロジェクトファイルも上記記事からダウンロードできます)。


早速試してみる


まず、手順の1ですが、上記サイトからダウンロードしたzipファイルを展開し、nauticalフォルダーごと、QGISのSVGが入っているフォルダーにコピーします。私の環境では、Windowsでバージョン2.18を使っているので、"C:\Program Files\QGIS 2.18\apps\qgis\svg"の下に置きます。


次に、手順2として、ogr2ogrを使ってENCをshapefileに変換します。
コマンドはこんな感じ(US4HA51M.000というのがENCのファイルです)。エラーが大量にでるので、-skipfailuresオプションをつけるのがミソっぽい。
ogr2ogr -skipfailures . .\US4HA51M.000
実行すると、大量のshapefileが出来上がります。


手順3の前に、プロジェクトファイルの中を見ると、svgファイルの指定のところで、ファイル名がフルパスでべた書きされており、このままだと動きませんので、動作環境に合わせて書き換えます(この辺はもう少しうまいやり方があるのかもしれない)。

書き換えたqgsファイルをGISTに置いておきます。

これでQGISのプロジェクトを開くと…
おお!!

細かいことを言えば改善したい点はたくさんあるのですが、ここまでENCに近い表示ができるのは、ほんとうに素晴らしいです。

というわけで、QGISでENCをもっとご活用ください。

FOSS4Gで電子海図の世界をのぞく2016 - OpenCPNで電子海図を見る

これは、「FOSS4G Advent Calendar 2016」の12日目の記事です。

昨年に引き続き、電子海図のネタです。昨年の記事はこちら
昨年は、「航海用電子海図(ENC)」とは何か、どこで入手できるのか、どうやって見るのか、という話をしました。今年は、OpenCPNというソフトウェアを使ってENCを見る方法に触れていきます。

OpenCPNとは?


昨年も少しだけ触れたのですが、OpenCPNは、ENCを表示する専用のオープンソースソフトウェアです。S-52という、IHOが定めたENCの表示仕様に従っているため、船に搭載されているENC表示装置(ECDIS)とほぼ同じ見た目でENCが表示されます。また、通常、ENCは専用の表示装置やソフトウェアでないと使用できないよう、S-63という仕様に基づいた特殊な暗号化がなされていますが、OpenCPNでは、S-63のENCも表示させることができます。

ほかにも、GPSと接続して現在地を表示したり、AIS(船舶自動識別装置)と接続して周囲にいる船の位置を表示したり、といった機能がついているのですが、この記事では扱いません。

インストール


OpenCPNのサイトにアクセスし、"Download"のタブから、最新のバージョンをダウンロードします。あとは、インストーラーの指示に従ってインストールします。
OpenCPNのウェブサイト

ENCのダウンロード


今回も、無料で簡単に手に入るアメリカのENCを使うことにします。
NOAAのENCダウンロードサイトから、必要なファイルをダウンロードします。このサイトでは、州ごとや海域ごとのENCがzipファイルでまとめられています。今回は、そのうちハワイ州のものを使います。
ENCダウンロードサイト
ダウンロードしたzipファイルを展開し、ENC_ROOTフォルダー以下を任意の場所に置いておきます。
zipファイルを展開したところ

OpenCPNの起動


OpenCPNを起動すると、最初に注意喚起のダイアログが出てきます。要するに、「必ず紙海図などと併用して使ってね」ということです。
注意書き
その後、アメリカの東海岸あたりの地図っぽいものが出てきます。当然ですが、この時点では、まだENCは読み込まれていません。
OpenCPNを起動したところ

ENCの表示


画面左上にあるツールバーから、スパナの絵のボタン(Option)をクリックします。

"Options"ダイアログにて、"Charts"を選択し、"Add Directory"をクリックして、先ほど展開したENC_ROOTフォルダーを指定します。
オプション設定画面
"OK"を押してダイアログを閉じます。この状態で、マウスドラッグなどで地図をハワイあたりまで動かすと、ENCが表示されるようになります。画面右上の"Meters"は、水深などの数値の単位がメートルであることを示します。

このままではわかりづらいですが、ズームインしていくと、より細かい海図が表示されるようになります(ENCは縮尺に応じて最大5段階のデータが存在します)。
ワイキキビーチ付近の海図(オプションで水深表示も有効にしています)

Android版を試す


OpenCPNにはAndroid版があるようなので(昨年はなかったので最近できたのでしょう)、こちらも試してみます。インストール自体は難しいことはなく、Google Playで"opencpn"で検索してヒットしたOpenCPNアプリをインストールすればOKです(無料版と有料版の2種類あるようなので注意)。
なお、ENCのファイルはあらかじめAndroid上に置いておきます(今回はSDカードの中に入れました)。

OpenCPNアプリのインストール

起動すると、先ほどと同じ警告の後、このように地図が表示されます(ちょっと陸地が欠けているような…)。
起動したところ

で、画面左上のスパナのボタンをタップし、先ほどと同じ要領でENC_ROOTのフォルダーを指定すると、海図が表示されるようになります。
ENCのデータが表示された
3年前のスマートフォンでも割とさっくり動きます。設定画面などのUIがかなり操作しづらいのが難点ですが、ここが改善されれば、かなり使えるのではないかと。


今回はここまでなのですが、最後に…

そういえば海図のオープンデータ化はどうなっているのか?


平成27年12月4日の「第11回電子行政オープンデータ実務者会議」にて、海図のオープンデータ化についての話が出てきました。その後の動きとして、平成28年4月5日に「電子行政オープンデータ実務者会議 第4回公開支援ワーキンググループ 及び 第4回利活用推進ワーキンググループ 合同会合」が開かれ、海図に関しても触れられたようですが、法律も絡んできますし、海図には安全にかかわる重要な情報が含まれているため、どうも公開には慎重になっているような印象を受けました。まだまだ道のりは遠いかも…。

2016年11月6日日曜日

courseraのMachine Learningの復習(week 2)

week 1の復習はこちら

パラメータが複数個の線形回帰


パラメータが$n$個存在するとき、線形回帰の仮説関数は、式(1)の通りとなる。

\begin{equation}
h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + ... + \theta_n x_n
\end{equation}

ここで、$\theta$および$x$を下のような行列で表現すると($x_0$は式を単純化できるように便宜的に追加したもので、値は常に1とする)、
\begin{equation}
\theta = \begin{bmatrix}\theta_0 \\ \theta_1 \\ \theta_2 \\ \vdots \\ \theta_n \end{bmatrix}, x = \begin{bmatrix} x_0 \\ x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}
\end{equation}
仮説関数は式(3)のように表現できる。
\begin{equation}
h_\theta(x) = \theta^T x
\end{equation}

コスト関数は、式(4)の通りになる。表現方法が変わっただけで、内容はweek 1と特に変わらない。
\begin{equation}
J(\theta) = \frac{1}{2m}\sum_{i=1}^m (h_\theta(x^{(i)})-y^{(i)})^2
\end{equation}

再急降下法の式は、次のように一般化される($j=1..n$)。
\[
\theta_j := \theta_j - \alpha\frac{1}{m}\sum_{i=1}^m ((h_\theta(x^{(i)})-y^{(i)})x^{(i)}_j)
\]
$\theta_0$については、$x_0 = 1$であるため、結局最後の$x^{(i)}_j$の部分が消えて、week 1の式と同等になる。


パラメータ値の調整


Feature Scalingと、Mean Normalizationという2つの手法がある。これらを使うことで、gradient descentを早く収束させられる。
Feature Scalingでは、パラメータの値を(そのパラメータの最大値 - そのパラメータの最小値)で割ることによって、パラメータの値を概ね-1から1の間に収めようとする。
Mean Normalizationでは、パラメータの値から、そのパラメータの平均値を引くことによって、そのパラメータの平均値概ね0になるように調整する。

まとめると、それぞれのパラメータの値を、次のように調整する。
\begin{equation}
x^{(i)}_j = \frac{x^{(i)}_j - mean(x_j)}{max(x_j) - min(x_j)}
\end{equation}


learning rateの選定


$\alpha$の値は、0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, ... というように調整していくのがいいらしい。


Normal Equation


最小の$\theta$を求める方法として、再急降下法のほかに、次の式を解く方法があり、これがNormal Equationと呼ばれる。
\begin{equation} \theta = (X^T X)^{-1} X^T y \end{equation}
どうやらgradient descentの式からこれを導出できるようなのだが、詳しいことは今後調べていく。
このあたりの記事が参考になるかもしれない。
Qiita - 線形回帰のNormal Equation(正規方程式)について

パラメータの数が10,000を超えるような場合には、normal equationではなくgradient descentを使ったほうがよいとのこと。

2016年10月10日月曜日

courseraのMachine Learningの復習 (week 1)

courseraが提供しているMachine Learningのコースを再受講しはじめましたので、せっかくなので、あとで復習できるよう、学習の内容をメモで残していきます。
このコースは、機械学習を理論から実践まで総合的に学習でき、英語が苦にならなければ教材としては最高だと思います。

ちなみに、bloggerで数式を使うやり方は、ここを参考にさせてもらいました。


線形回帰(linear regression)のモデル


もっとも単純な線形回帰では、1つの入力変数$x$と出力$y$をトレーニングデータとして与え、未知の$x$に対してなるべく正確に$y$を算出できるよう学習させる。

学習したモデル(このモデルのことを「仮説関数」(hypothesis function)と呼ぶ)は、式(1)のような1次式になり、グラフで表すと傾きと切片を持った直線になる。
\begin{equation}
y=\theta_0+\theta_1x
\end{equation}
線形回帰では、この$\theta_0$(切片)と$\theta_1$(傾き)の調整を行うことになる。

コスト関数(cost function)


コスト関数は、仮説関数に$x$を与えたときに得られる$y$がどれだけ実際の$y$と乖離しているかを求めるための関数である。コスト関数の計算結果を$J$とすると、線形回帰の目的は、この$J$を最小化することである。

コスト関数は式(2)のようになる。$h_\theta(x)$は仮説関数、$m$はトレーニングデータの数を表す。\begin{equation}
J(\theta_0, \theta_1) = \frac{1}{2m}\sum_{i=1}^m (h_\theta(x_i)-y_i)^2
\end{equation}
要するに、やってることは、全トレーニングデータの誤差の2乗の平均を求め、それを2で割っている。なぜ2で割るのかについては、ここを参考にする限り、後でこの式を微分するときにこの2が消えるので計算がやりやすくなる、ということらしい。

1変数のコスト関数は、$\theta_0$, $\theta_1$, $J$の3つを軸にとったグラフで表現すると、ボウルのような形になる。

最急降下法(gradient descent)


最急降下法(gradient descent)によって、コスト関数の値が小さくなるよう少しずつ$\theta_0$と$\theta_1$を調整していく。計算式は次のとおり。これを収束するまで続ける。
\[
\theta_0 := \theta_0 - \alpha\frac{1}{m}\sum_{i=1}^m (h_\theta(x_i)-y_i) \\
\theta_1 := \theta_1 - \alpha\frac{1}{m}\sum_{i=1}^m ((h_\theta(x_i)-y_i)x_i)
\]
$\alpha$はlearning rateと呼ばれ、この値が調整幅を決める。$\alpha$が大きくなるほど、スピードは上がるが、収束とは逆の方向に進んでしまう可能性がある。$\alpha$を小さくすれば、確実に収束する方向に向かえるが、スピードが落ちる。

上の式でやっていることは、コスト関数に対し、現在地点における$\theta_0$軸と$\theta_1$軸のそれぞれの傾きを求め、傾きが落ちている方向に$\theta_0$と$\theta_1$を移動させている。
コスト関数の偏微分がなぜ上の式になるのかについては、これを読むとわかるかもしれない。

2016年6月9日木曜日

ArcGIS Runtime for .NETを使ってS57 ENCを表示させる

前にツイートしましたが、
ということで、サンプルコードを公開します。 (ArcGIS Runtime for .NETのインストールなどは、チュートリアルを参照してください) 実行してズームインしてみると、こんな感じで表示されてます。

2016年2月16日火曜日

交通ジオメディアサミットの資料だけ拝見

先日、交通ジオメディアサミット ~IT×公共交通 2020年とその先の未来を考える~というイベントが開催されました。GISを本職としている者として、ものすごく興味があったのですが、この時期はどうしても仕事が多忙になるもので参加できず、せめて資料だけでも拝見したいと思っていたところ、ありがたいことに、資料を公開していただけておりました。

「交通ジオメディアサミット ~ IT×公共交通 2020年とその先の未来を考える~」発表資料と反応



資料を拝見する限り、今回は公共交通の中でもバスが話題の中心で、話の方向性として、「バスに関するデータがなかなか出てこない。また、出てきたとしてもフォーマットがバラバラで使いづらい。」という課題があるのが見えました。バスデータのオープンデータ化・標準化が必要というアプローチなのかな。OpenTrans.itなど、これらの問題の解決に向けた具体的な取り組みも興味深く読ませていただきました。

個人的に、オープンデータが地域のバスに関する課題を解消できるのか、まだいまいちピンときていないのが正直なところで、
  • 地域のバスなんて地元住民しかほとんど乗らないんだから、時刻表データをオープンにしなくても、また、経路探索でバスが出てこなくても、そんなに困らないのではないか。
  • データをオープンにしたところで、利用者が増えるわけではないので、利用状況の分析とかやったところで、不採算問題の解消にはつながりにくいのではないか。
  • データのオープン化によって何か地域の課題が浮かびあがる、というイメージが見えてこない。
というのが今の私がぼんやりと抱いている考えだったりするのですが、これはおそらく私自身がこの分野の素人だからそう思うのであって、もっと勉強が必要なのでしょう。
地域の課題を抜きにして考えれば、たとえば京都のバスなんかはオープンデータが発達するとすごく便利になりそうな気がします。電車とバスの乗り継ぎを一度に検索できて、しかも渋滞や遅延なども加味されると、観光効率は各段に上がるのではないかと。

次回はぜひ出席したいです。年度末だけ避けていただければ…。
あと、ナビタイムさんすごく面白いことやってるな。

2016年1月13日水曜日

CartoDBを試す

昨年のFOSS4Gか何かでCartoDBの紹介があってちょっと気になっていたところに、FOSS4G Advent Calendar (二個目)にCartoDBのチュートリアル記事がありましたので、いい機会なので試してみました。

アカウントを作る


CartoDBのサイトにアクセスして、"SIGN UP"をクリックし、アカウントとメールアドレスとパスワードを登録すれば(あと職種と業種をきかれた)、簡単にアカウントを作れます。特に迷うことはないかと。
サインアップし終わったところ


データを作る


チュートリアル記事の通りやりました。データもそちらからお借りしました。詳しくはチュートリアル記事をご参照ください。手抜きですみません。


shpファイル(が入ったzip)をデータセットに追加
shpを追加したところ
ベースマップを変えてみる(赤丸のボタンで、自分の好きなものに変更できます)
地理院タイルの白地図をベースマップにしてみた
属性値をラベルとして表示
データのマージ
SQLクエリー実行
コロプレス表示

QGISで表示する


CartoDB Plugin for QGISを使うとQGIS上でも表示できます(編集もできるっぽいですが試してません)。

まず、CartoDBのプラグインをインストールします。


そうすると、Webツールバーにこんなのが出てきます。
Webツールバー上のCartoDB
まずはCartoDBに接続します。"Add Connection"をクリックし、Connection Managerで"New"をクリックします。

ここでユーザー名とAPIキーを入力します。APIキーはCartoDBのサイトで確認することができます。
ここでユーザー名とAPIキーを入力
保存してConnection Managerに戻り、"Connect"を押すと接続されます。
接続されました
"Add CartoDB Layer"のボタン(ユーザー名のすぐ右のボタン)をクリックし、テーブルを選んでOKをクリックします。
データセットを選択

これでレイヤーがQGISに追加されたはず。
CartoDBのデータセットがQGISにロードされたところ

おわりに

とにかく操作が簡単で、今回くらいの地図であれば、GISにそれほど詳しくなくてもできてしまいそうですね。
今回はごく基本的なところしか試していませんが、ギャラリーには、タイムラインを出して時系列にマップを表示したり、正方形タイル状に表示したり、いろんな表示例を見ることができ、見てて楽しいです。結構奥が深いのかも。