2017年12月21日木曜日

S-101 with FOSS4G (1) ISO8211の解析

これは「FOSS4G Advent Calendar 2017」の21日目の記事です。

はじめに

現在一般的に普及している航海用の電子海図は、国際水路機関(IHO)がS-57という名前で公開している規格に基づくものです。以前にも書いたとおり、S-57で作成されたファイルは、GDAL/OGRでベクターファイルとして読み込むことができ、QGISでも表示することができます。

このS-57に代わる新しい電子海図の規格として、IHOでは、S-101という仕様を作っています(なぜ新しい規格が必要なのか等の背景については、別の記事で書いていますので、そちらをご参照ください)。この記事の執筆時点では、S-101はまだ完成しておらず、IHOのタイムスケジュールによると2019年の後半に初版が出るものとみられます。
S-100系のタイムスケジュール(IHO HSSC9の資料より)

ということで、(まだ誰もデータを作ってないので当たり前といえば当たり前ですが、)今のところGISソフトでS-101データを読み込む仕組みは、私が知る限りはまだ存在しないので、とりあえずQGISでS-101を表示するくらいまではやってみたいなと思い始めました。

QGISでS-101を表示するまでの道のり

言ってはみたものの、ちょっと考えただけでも下記のことをやらなければならず、道のりはかなり長そうなので、まず今回は下記の1だけやってみることにします。
  1. PythonでS-101のデータをISO 8211構造として読めるようにする。 ←今回はこれ
  2. ISO 8211構造をS-100のGFMに近いモデルに変換する。
  3. S-101 Feature Catalogueを使ってenum値などを変換する。
  4. QGISのレイヤーに変換して表示するプラグインを作る。
  5. S-100特有の課題の解決(属性の階層構造、Information Type、各種Associationなど)
  6. (GDAL/OGRで直接扱えるようになるといいなあ)

環境

とりあえず次の環境でやりました。
  • Ubuntu 16.04 LTS (Windows Subsystem for LinuxでWindows 10の上にインストール)
  • Python 2.7.6

データの入手

どの国も正式なデータを作っていませんので、IHOが公開しているテストデータを使うしかありません(これも少し古いのですが、これしかないので仕方ありません)。
こちらからデータをダウンロードし、zipを展開して、適当なデータファイル(拡張子が.000のもの)を拾います。
https://www.iho.int/mtg_docs/com_wg/S-100WG/TSG3/S101TestDatasetsExchangeSet.zip

ファイルの解析

PythonでISO 8211のファイルを扱うライブラリがオープンソースで公開されているので、それを使わせていただくことにします。
https://github.com/freekvw/iso8211

このソースをgit cloneで取得して中を見てみると、コマンドラインツール(拡張子なしのiso8211という名前のファイル)が付属しています。どうやらこれで.000の中身を見られそうなので、まずはきちんと読めるかどうか確認してみます。
$ ./iso8211
Interactive command environment
(use exit or `EOF' to exit the environment)
 
iso 8211: file ../AADLULBD01.000
Opening DDF /home/xxxxxxxx/AADLULBD01.000
Warning: In field `CSID' the field controls `1100;&   ' indicate format `I'
         but the actual format controls are `(b11,b14,b11)'
(以下、Warningが大量にでます)
Warningが大量にでますが、読み込めてはいるようです。
中身を少し見てみます。
iso 8211: show record 1
Record 1 at offset 3025
    Leader
        record length              = 8928
        leader id                  = `D'
        base address of field data = 133
        entry map:
            size of field length   = 4
            size of field position = 4
            size of field tag      = 4
    Directory contains 9 entries
    Field 0
        tag  = 'DSID'
        data = b11   'RCNM': 'U:0x0a (10)'
               b14   'RCID': 'U:0x00000001 (1)'
               A     'ENSP': 'S-100 Part 10a'
               A     'ENED': '1.1'
               A     'PRSP': 'INT.IHO.S-101.1.0.0'
               A     'PRED': '1.0.0'
               A     'PROF': '1'
               A     'DSNM': 'AADLULBD01__.000'
               A     'DSTL': ''
               A(8)  'DSRD': '20150706'
               A     'DSLG': 'EN'
               A     'DSAB': ''
               A     'DSED': '1'
               b11   'DSTC': 'U:0x0e (14)'
               b11   'DSTC': 'U:0x12 (18)'
    Field 1
        tag  = 'DSSI'
        data = b48   'DCOX': 'F:0x0000000000000000'
               b48   'DCOY': 'F:0x0000000000000000'
               b48   'DCOZ': 'F:0x0000000000000000'
               b14   'CMFX': 'U:0x00989680 (10000000)'
               b14   'CMFY': 'U:0x00989680 (10000000)'
               b14   'CMFZ': 'U:0x00000064 (100)'
               b14   'NOIR': 'U:0x00000005 (5)'
               b14   'NOPN': 'U:0x000007d6 (2006)'
               b14   'NOMN': 'U:0x000004bc (1212)'
               b14   'NOCN': 'U:0x00000881 (2177)'
               b14   'NOXN': 'U:0x0000026b (619)'
               b14   'NOSN': 'U:0x00000084 (132)'
               b14   'NOFR': 'U:0x000008ff (2303)'
(以下略) 
なんとなくよさそうです。というかこれデータのダンプするのに非常にいいツールなので、業務でも使わせてもらいます。

次に、Pythonのソースコードでデータ構造を扱ってみます。
こんな感じでできそうです。
>>> import iso8211
>>> ddf = iso8211.DDF()
>>> ddf.open("../AADLULBD01.000", "r")  # ファイルを開く
>>> record = ddf[2]  # 3番目のレコードを取得
>>> record.show()
Record 3 at offset 12103
    Leader
        record length              = 62
        leader id                  = `D'
        base address of field data = 41
        entry map:
            size of field length   = 2
            size of field position = 2
            size of field tag      = 4
    Directory contains 2 entries
    Field 0
        tag  = 'IRID'
        data = b11   'RCNM': 'U:0x96 (150)'
               b14   'RCID': 'U:0x00000001 (1)'
               b12   'NITC': 'U:0x00ca (202)'
               b12   'RVER': 'U:0x0001 (1)'
               b11   'RUIN': 'U:0x01 (1)'
    Field 1
        tag  = 'ATTR'
        data = b12   'NATC': 'U:0x008b (139)'
               b12   'ATIX': 'U:0x0001 (1)'
               b12   'PAIX': 'U:0x0000 (0)'
               b11   'ATIN': 'U:0x01 (1)'
               A     'ATVL': '4'
>>> field = record[0]  # 親フィールドを取得
>>> field = record[1]  # 最初の子フィールドを取得
>>> tag = field.tag  # フィールドのタグを取得
>>> print(tag)
ATTR
>>> subfields = field.split()  # フィールドのすべてのサブフィールドを取得
>>> print(subfields)
[('NATC', b12, '\x00\x8b'), ('ATIX', b12, '\x00\x01'), ('PAIX', b12, '\x00\x00'), ('ATIN', b11, '\x01'), ('ATVL', A, '4')]

今回はここまでです。
なお、この段階では、まだファイルをISO 8211として読んでいるだけなので、S-57のENCファイルでもまったく同じことができます。

2017年の振り返り

今年は初めてFOSS4G Tokyoで登壇させていただきました。お世辞にもうまくできたとは言えませんが、コミュニティで発表させていただくという貴重な経験をさせていただいたことは、私にとって何物にも代えがたい財産になりました。OSGeoの関係者のみなさまや、私の話に興味を持ってくださったみなさまに、この場を借りて感謝いたします。

2017年5月6日土曜日

CNTKのチュートリアルを動かしてみる

Microsoftが公開している機械学習フレームワーク「CNTK」を触ってみました。

環境構築

次の環境で試しました。これらのインストールは終わっているものとします。

  • Windows 10 Pro (64bit)
  • Anaconda 4.2.0


Python仮想環境の作成

コマンドプロンプトを起動し、次のコマンドで"cntk"という名前の仮想環境を作成します。Pythonのバージョンは3.5にしておきます。
conda create -n cntk python=3.5

Python仮想環境の起動

activateコマンドで仮想環境を起動します。
activate cntk

CNTKのインストール

CNTKをインストールする前に、いくつかのライブラリをインストールしておきます。
conda install jupyter
conda install matplotlib
conda install scipy
その後、CNTKの本体をインストールします。
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0rc2-cp35-cp35m-win_amd64.whl


サンプルプログラムのダウンロード

次のコマンドでCNTKのサンプルプログラムをダウンロードします(カレントフォルダーにダウンロードされます)
python -m cntk.sample_installer

チュートリアルの起動

Jupyterを起動します。
jupyter notebook
Jupyter Notebook上で、ダウンロードしたサンプルプログラムの中から、Turorialsフォルダーの中のCNTK_101_LogisticRegression.ipynbをクリックして、ノートを表示させます。


2017年5月4日木曜日

GIS関係者に知ってほしい次世代海洋データ標準S-100

はじめに

国際水路機関(IHO)は、2010年に、「S-100」と呼ばれる新しい海洋データ標準をリリースしました。
IHOが現時点で公開している海洋データ標準としては、ほかに「S-57」と呼ばれる仕様があり、電子海図のデータ仕様として広く普及しています。しかし、この仕様は拡張性(データ定義の見直しの都度、仕様をバージョンアップしなければならない)やメンテナンス性(仕様のバージョンアップのたびに、ECDISなどの表示装置側でソフトウェアアップデートが必要になる)などの面で問題があり、これらを改善するためにS-57を全面的に見直して新たな標準を作る、というのがS-100の背景になっています。

S-100の特徴

S-100の大きな特徴として、次の2点をあげておきます。

地理情報の標準への対応

S-100は、地理情報のグローバルスタンダードであるISO19100シリーズをベースに(ところどころS-100独自の拡張を加えて)作られています。多くのデータはGMLファイルとして配布されると思われるので、一般的なGISソフトウェアでも扱いやすくなります。

データフォーマットとデータ定義の分離

S-100では、データ作成のためのフレームワーク(データモデルやファイルフォーマットなど)のみが提供され、具体的なデータの内容を決めるのは、個々のデータ仕様の役割となります。たとえば、「S-101」というデータ仕様では、S-100で定めるデータモデルに基づいて、電子海図ドメインのデータの定義(「海岸線」「航路標識」など)を行います。


このような分離を行うことによって、表示装置でS-100のフレームワークにさえ正しく対応しておけば、データ仕様の変更やデータ仕様そのものの追加があった場合でも、表示装置側のアップデートを行うことなく、仕様の変更に対応できることになります。

S-100の現状

データ仕様の大半はIHOで作成途中ですので、これらのデータが一般に出回るのは、まだまだ先の話になります。
主要なものを下の表に挙げます。
  • S-101(電子海図)…2019年リリース予定
  • S-102(水深)…リリース済
  • S-111(潮流)
  • S-121(境界情報)
  • S-122(MPA:海洋保護区域)…2019年リリース?
  • S-123(無線サービス)
  • S-124(航行警報)
今後どれだけ普及するかは正直わかりませんが、海洋GISデータはすべてS-100ベースのデータになる、という未来もあるかもしれません。

技術的な話

S-100のデータ構造を扱えるライブラリの存在を現時点で確認できていませんが、前述のとおり、S-100はISO19100シリーズが基になっているため、GeoToolsのOpenGIS実装(org.opengisパッケージ)の内容がかなり参考になるはずです。
S-100対応のECDISのSDKがあるようなので、こういうものの中にはおそらく入っているのでしょう。

参考資料

2017年4月15日土曜日

AutoCAD Map 3Dの情報源まとめ

AutoCAD Map 3Dの情報は、AutoCADに比べて圧倒的に少ないですが、見つけたものをまとめておきます。



2017年1月22日日曜日

TensorFlowを試す

GoogleのディープラーニングフレームワークであるTensorFlowを触ってみました。

環境構築

今回は、Windows 10 Professional (64bit)にAnacondaをインストールし、AnacondaでPythonの仮想環境を作って、その上にTensorFlowをインストールしました。


なお、こちらの資料を参考にさせていただきましたが、VirtualBoxのインストールおよびubuntuの仮想マシンの作成は行っておりません。
Windows+VirtualBoxで作るTensorFlow環境

Anacondaのインストール

Anacondaのダウンロードサイトにアクセスし、Python 3.5版の"64-BIT INSTALLER"をダウンロードします。

ダウンロードしたインストーラーを起動し、あとは画面の指示に従ってインストールを進めればOK。パスを通すのを忘れずに。

Python仮想環境の作成

Windowsのコマンドプロンプトを起動し、次のコマンドで"tensorflow"という名前の仮想環境を作成します。
conda create -n tensorflow python=3.5

Python仮想環境の起動

次のコマンドを実行します。これで仮想環境が起動します(プロンプトの左に"(tensorflow)"と表示されるようになります。
activate tensorflow

TensorFlowのインストール

上で作った仮想環境に対して、次のコマンドでインストールできます。思ったより簡単。
pip install tensorflow

コーディング

上記の状態でコマンドプロンプトからpythonを起動し、あとはTensorFlowの"MNIST for Beginners"のチュートリアルを見ながら、1行ずつコーディングしていきます。

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回利活用推進ワーキンググループ 合同会合」が開かれ、海図に関しても触れられたようですが、法律も絡んできますし、海図には安全にかかわる重要な情報が含まれているため、どうも公開には慎重になっているような印象を受けました。まだまだ道のりは遠いかも…。