SIMA を GeoJSON に変換する npm パッケージを公開しました

測量データ共通フォーマット SIMA の通称 CSV 版を GeoJSON ファイルに変換できるスクリプトを npm のパッケージとして公開しました。ソースは GitHub置いてあります。

使い方

インストールは npm から簡単にできます。

# sudo npm i -g sima2geojson

SIMA ファイルと SIMA に記録されている座標の平面直角座標の系を EPSG コードで与えると WGS 84 で点の GeoJSON と面の GeoJSON を出力します。 EPSG のコードは epsg.io とかで検索すると出てきます。

測地成果2000の場合は系番号Ⅰが EPSG:2443 で系番号ⅩⅨは EPSG:2461
測地成果2011の場合は系番号Ⅰが EPSG:6669 で系番号ⅩⅨは EPSG:6687

みたいな感じです。

# sima2geojson -S sample.sim -E 6677
→ sample.point.geojson
→ sample.polygon.geojson

試しに3515の点を持ち1035の画地が登録された SIMA データを変換しましたが割と一瞬で GeoJSON が出来てきました。

今のところコマンドライン専用ですが気が向いたら他の JavaScript からインポートして使える形にするかもしれません。

能書き

GeoJSON の RFCで座標参照系を指定する項目が削除され、 座標は緯度経度を使って WGS 84 で表現することになったため、以前公開した Ruby スクリプトJavaScript 版のように出力先の GeoJSON に座標参照系を埋め込むパターンが使えなくなってしまいました。
QGIS など一部のソフトウェアでは互換性維持のためなのか座標参照系を認識してくれますが、いつまで認識してもらえるかわからないので日本の測量座標系を WGS 84 に変換するタイプのスクリプトを書こうと思っていました。

今回公開したパッケージでは投影系や座標参照系を変換してくれる Proj4 の npm パッケージを使って日本の測量座標系を WGS 84 に変換しています。

なお、今回のパッケージでも以前から課題である「路線データの変換」にはまだ対応していません。
測量データ共通フォーマット SIMA Ver.04.1の仕様が書かれた本が存在するようなので取り寄せてちゃんと理解する必要があるので時間かかると思います。

Tasking Manager 3 を更新する

いくつかの言語で表示するとタスクが2回表示される問題が解決されたので解決済のシステムに更新します。

まずサービスを停止させます。

$ sudo systemctl stop tm3.service
$ sudo systemctl stop nginx.service

TM3 のディレクトリに入って GitHub から最新のシステムを引っ張ってきます。

$ cd ~/tasking-manager/
$ git pull
error: Your local changes to the following files would be overwritten by merge:
        server/config.py
Please commit your changes or stash them before you merge.
Aborting

git の追跡対象である server/config.py に書かれた APP_BASE_URL を書き換えているのでどうにかしろと言われ pull が中断します。
現在の内容をパッチに書き出してローカルの最新コミットの状態に戻します。

$ git diff server/config.py > ~/config.patch
$ git checkout -- server/config.py

今度は大丈夫なはず

$ git pull

無事更新されたら server/config.py の内容にパッチを当てて自分の環境用にします。

$ patch server/config.py ~/config.patch

今回の目玉、フロントエンドの更新です。

$ cd client

//更新された npm パッケージがないか確認する
$ npm outdated

Current と Wanted が違ってなさそうなのでOK。
フロントエンドをビルドします。

$ gulp build

最後にサービスを起動すればOK。

$ cd ~
$ sudo systemctl start tm3.service
$ sudo systemctl start nginx.service

ブラウザからアクセスすると問題が解決しているはずです。

f:id:k-side:20180717095332p:plain

Tasking Manager 3のサイトを HTTPS 化する

前回設定した Tasking Manager 3 を Let's Encrypt で HTTPS 化します。

k-side.hatenablog.jp

作業はこんな感じ。

  • 設定のバックアップ
  • certbot の導入
  • nginxの設定
  • Tasking Managerの設定
  • 自動更新の設定

設定のバックアップ

etckeeper でいいやって楽しました。

$ sudo apt install -y etckeeper

debian 9.4 では勝手に Initial commit までやってくれました。

次に certbot に渡す nginx のドキュメントルートを確認しておきます。
今回はこんな感じになっています。

/home/%user name%/tasking-manager/server/web/static/dist

ファイアウォールhttps 接続で使われるポートを開けておきます。

$ sudo ufw allow https

certbot の導入・証明書取得と作成

Let's Encrypt の処理をよしなにやってくれる certbot を導入します。
wget でホームディレクトリの src 内に certbot ディレクトリを作ってそこに置いておきます。

$ mkdir -p ~/src/certbot
$ cd ~/src/certbot
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto

配置できたら早速証明書の取得をします。
確認しておいた nginx のドキュメントルートとドメインを渡して実行すればOK。

$ certbot-auto certonly --webroot \
-w /home/%user name%/tasking-manager/server/web/static/dist \
-d %ドメイン%

取得した証明書は次のディレクトリに保存されていました。

/etc/letsencrypt/archive/%ドメイン%/fullchain1.pem;
/etc/letsencrypt/archive/%ドメイン%/privkey1.pem;

Key Exchange のスコアを上げるために dhparam を作っておきます。

$ sudo openssl dhparam -out /etc/ssl/dhparam.pem 2048

個々で指定したパス /etc/ssl/dhparam.pem は nginx の設定に使います。

nginx の設定

nginx の設定ファイルを書き換えます。

$ sudo vi /etc/nginx/sites-available/tm3

次の行を追加しました。確認した証明書の保存場所をここで使います。
元からあった listen 80; と同じインデントレベルに置いてあります。

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/archive/%ドメイン%/fullchain1.pem;
    ssl_certificate_key /etc/letsencrypt/archive/%ドメイン%/privkey1.pem;
    ssl_trusted_certificate /etc/letsencrypt/archive/%ドメイン%/fullchain1.pem;

    //openssl で作った dhparam へのパスです
    ssl_dhparam /etc/ssl/dhparam.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!EXPORT:!DES:!3DES:!MD5:!DSS;
    ssl_prefer_server_ciphers  on;

    add_header Strict-Transport-Security max-age=15768000;

書き換えたら nginx をリロードしてエラーが出なければOK。

$ sudo systemctl reload nginx.service

Tasking Manager の設定

Tasking Manager には OSM アカウントで認証した後に戻ってくるコールバック URL などで使われる APP_BASE_URL が設定されているので、ここを https にしておかないとアカウント認証をして Tasking Manager に戻ってくる時に http 接続に戻ってしまいます。

$ cd ~/tasking-manager/server/
$ vi config.py

下記の部分を書き換えればOK。

  class ProdConfig(EnvironmentConfig): 
-     APP_BASE_URL = 'http://%ドメイン%'
+     APP_BASE_URL = 'https://%ドメイン%'

gunicorn を再起動させます。

$ sudo systemctl restart tm3.service

ここで Tasking Manager に HTTPS アクセスできれば大丈夫なはず。

自動更新の設定

自動で証明書が更新されるように cron に設定を追加します。

今回は毎月13日の午前3時00分に更新させる設定にしました。
crontab を使わずに直接 /etc/cron.d/ にファイルを作っちゃいました。

動かなかったらどうしよ(

sudo sh -c "echo '00 03 13 * * root /home/%user name%/src/certbot/certbot-auto renew --post-hook \"systemctl reload nginx.service\"' > /etc/cron.d/letsencrypt"

SSL のスコア

Qualys SSL LABS SSL Server Test でセキュリティレベルを計測したところ A+ でした。

f:id:k-side:20180712155929p:plain

Tasking Manager をv2からv3にマイグレーションする

IDCF クラウドで動いていた Tasking Manager 2 を ConoHa VPS に立てた Tasking Manager 3 に移行する話です。
クッソ長い作業メモなので注意。

新しく Tasking Manager 3 を立てる場合はマイグレーション操作を飛ばして代わりにデータベースを初期化するコマンドを実行すればいいはずです。

移行前も移行後も Debian Stretch(9.4) の環境です。

$ cat /etc/debian_version 
9.4
続きを読む

NEW XPS 13(9370) こんな風に使いました

DELL XPS体験モニターとして届いた NEW XPS 13(9370) について、どの様につ買っていたかを書いていきます。 このポストは DELL アンバサダーへの参加記事です。

用途概略

こんな感じの作業をしていました。

  • 翻訳・記事作成作業
  • 地図のマッピング
  • マインクラフト
  • Web サイト編集

翻訳・記事作成作業

Chrome ブラウザと Visual Studio Code をインストールしてブラウザ上で記事の作成作業をしていました。
メインの英語の概略記事、関連するリンク先のウェブサイト複数、翻訳用タブを開いた上で実際に記事を作成する VS Code を開いての作業です。

タブを開けば開くほどメモリを使う Chrome で40~50タブ開いていましたがメインメモリの大きさと SSD の性能もあってか反応が悪くなった印象はありません。もっとガンガンにタブを開いてブラウズしている方もいると思います。ページによっては通常の表示だけでなく Google のページ翻訳をかけた状態です。さらに他の作業をしている時もそうですが、TweetDeckは常に開きっぱなしです。
ディスプレイサイズは13インチということでそれほど大きな画面ではありませんが、高精細であるため複数のウィンドウを並べて表示しても問題無く作業できます。

英語の記事から文章を選択して翻訳ページにコピペする作業を含めタッチパッドを使いましたが感度のいいタッチパッドのため細かい操作も拾ってくれるので快適に作業ができました。

さて、単語を翻訳してくれた日本語から基本語記事を組み立てたり、このモニターの前半記事の文章を書くなどは VS Code で行っていました。
前半の記事でも紹介しましたが軽量化された本体とは思えないほど安定感があり、キーにほどよい反発感(?)があるためか文字の入力作業は快適でした。そこそこの文章量を打ったつもりですが入力しにくいなと思う場面は出てきませんでしたね。

地図のマッピング

OpenStreetMap 用地図エディタの JOSM とそれを動かすために必要な Java をインストールして地図の編集を行いました。概ね CAD の編集操作のようなものです。
ここではさすがにタッチパッドでの編集は難しく、マウスを使うことにしました。最も、この高感度タッチパッドであれば使い込む中でちょっとした CAD 操作はできるようになるのではないかと思うほど使い勝手のいいものです。ThinkPadトラックポイントで CAD 編集をしていた時期を思い出せそうでした。

ここでは森林のポリゴンにあるエラーを修正するために1万点前後のポイントを持ったポリゴンをダウンロードしてきて操作しますが、反応は快適なままで編集を終えることができます。

マインクラフト

以前は GPU を搭載したパソコンでないと快適なプレイができなかったマインクラフトですが、グラフィック性能の向上もあって拡張機能を追加しないいわゆるバニラ環境(動作を軽くさせる軽量化の拡張も使いませんでした)では CPU に載っているグラフィックでも十分で、特に今回は Core i7-8550U が持つ UHD グラフィックス 620 が強力なこともあって描画領域を少しくらい広げても快適なプレイが可能です。

動きのあるオブジェクトが増えてくると CPU ファンが回り始め、本体下部などの排気口から体感できる排熱が起こります。本体にアルミが使われていることもあり、排熱性能は高そうです。

ここでもさすがにマウスを使いました。

Web サイト編集

jekyll を使った Web サイトの編集を行いました。ここでは Windows Subsystem for Linux を入れて debian に rbenv で Ruby を入れて Windows 側の VS Code で内容を編集します。

まず rbenv で Ruby をインストールするときに Ruby をビルドしますが、さすが Core i7 のマシンだけあって短時間でビルドできました。
サイトの編集でファイルに変更があるとサイトのビルドをやり直すようにオプションを付けていますが、これくらいの作業であれば一瞬でサイトがビルドされるのですぐに内容を確認できて非常に快適です。

記事の作成と同じようにキータイプの多い作業です。記事の作成と同様安定感のある本体と打ちやすいキーボードが活きました。
VS Code の他に WSL のコンソール、PowerShell のコンソール、Chrome のウィンドウ、Chromeデベロッパツールを開いています。さすがに一度に全部を表示させることはできませんが、ここでも感度の良いタッチパッドのおかげで切り替えもスムーズに行え、編集は苦にならずに済みました。

今回の機種はキーボード面がカーボン仕様になっていてとてもカッコイイです。

f:id:k-side:20180625205056j:plain
カーボン仕様のキーボード面

まとめ

高性能な部品を使うことは他のパソコンでも可能ですが、キーボードのタイプ感や本体の安定感を出すための設計、その上で薄型軽量で丈夫というのはなかなかある機種ではありません。
メモリも8GBが上限になっている残念なノートパソコンが多い中、コンパクトタイプにもかかわらず16GBを積めるようになっているのは素晴らしいです。

本体が丈夫ということはそのままカバンに詰め込んで出かけても心配が少ないということですね。

処理性能と携帯性の両方を満足させる機種だと思います。

NEW XPS 13(9370) の紹介

DELL XPS体験モニターとして届いた NEW XPS 13(9370) について、届いた製品を紹介します。
このポストは DELL アンバサダーへの参加記事です。

スペック

まずは届いたパソコンのスペックを置いておきます。
実際購入する場合には用途に応じたスペックになると思いますが届いたものは最高クラスのものでした。

NEW XPS 13(9370)
CPU Core i7-8550U
メモリ 16GB
ストレージ SSD 1TB
モニタ 13.3インチ 4K(3840x2160)(タッチパネル)

インターフェイス

外部機器の接続などをするインターフェイスは USB-C が3機(左側2機、右側1機)、セキュリティケーブルスロット、microSDスロット、ヘッドセットジャックがあり、AC 電源は USB-C を使って接続するタイプです。
USB-C のみになっているため、USB-C から USB-A に変換するケーブルが1本付属しています。

電源のアダプタは非常にコンパクトにできていますが、AC アダプタとコンセントを繋ぐケーブルは割としっかりしたケーブルになっているため、アダプタごと持ち運ぶ場合は少し場所を取るかもしれません。

アダプタに関してデメリットに感じる方もいるかもしれませんが、 XPS 13(9370)の公称バッテリ駆動時間は19時間46分(FHDディスプレイの場合)となっているため、通常の外出ではアダプタが必要になる場面は少なそうなので問題なさそうです。

サイズ・ディスプレイ

以前から XPS 13 という名前のついている機種は13インチノートパソコンの中でも小さい部類でしたが、今回の 9370 モデルではディスプレイの額縁が狭くなりフットプリントが小さくなっています。
ディスプレイの額縁は以前の5.2mmから4.0mmへ、本体の厚さも以前の最薄部9~15mm程度だったものが7.8~11.6mmになり持ち運びがさらに楽になっています。
本体も外側が金属ボディになっているため荷物の多いバッグに入れても安心できそうです。

f:id:k-side:20180625205201j:plain
ディスプレイ額縁は4mm

この機種はタッチパネルを採用しているにも関わらずディスプレイ部も厚くならず薄さを保っています。
ディスプレイも発色が綺麗でしたが、やや輝度が高く感じました。もちろん設定で下げてあげれば問題ないレベルにできます。

4Kディスプレイで高精細な表示が可能です。Windows のスケーリングを100%で使うとアイコンなどが非常に見にくくなりますが、初期状態で Windows 10 の推奨値300%になっていて、必要に応じてスケーリングを変更できます。今回はスケーリング 225% で使用したところ使いやすい表示になりました。

キーボード・タッチパッド

キー配列はほぼ一般的なキー配列と言って良いのではないでしょうか。輝度や音量調整のキーとファンクションキーが一体になっていてそのまま押すと音量調節などの機能を使うことができ、Fn キーとのセットでいわゆるファンクションキー(F1など)を利用できます。左右カーソルの上側にPageUp、PageDown がありますが、ファンクションキーの挙動なども含めて既に「一般化」していそうな部類のものです。

本体も薄いため、キーボードのタイピング感が心配でしたが打ちやすい作りになっています。適度な反発のためか。普段会社で使っているワイヤレスキーボードよりも打ちやすく静かな印象です、。
1.21kgほどの本体ですが、タイピング中も安定感があり打ちやすくなっているのかもしれません。

モニター機は日本語キーボードでしたが販路によって(DELL 公式からとか) US キーボードを選択できます。

タッチパッドは高感度で思ったとおりに動いてくれます。製図や 3D データをグリグリ編集するような用途でなければ非常に使いやすいものになっています。

Windows Hello

Windows 10 のサインイン機能 Windows Hello 対応の指紋認証と顔認証用赤外線カメラが付いています。

指紋認証は電源ボタンと一体化していて電源オンからスムーズにログインできます。

f:id:k-side:20180625205018j:plain
電源ボタンと一体化している指紋認証(DELETEキーの右側)

顔認証はヒンジの付け根部分中央についていて、真ん中に DELL の文字、文字の下にカメラ、カメラの外側に赤外線認証が付いています。
Windows Hello の設定で顔を覚えさせて使います。登録時には PC メガネなしで登録しましたが、認証時に PC メガネをかけていても大丈夫でした。この辺は環境やメガネによって変わるかもしれません。

f:id:k-side:20180625205140j:plain
顔認証デバイス(フラッシュが映り込んでる…)

使った感じはまた別の記事で。

Zabbix API を使ってホストを無効化する

会社から自宅の Zabbix に登録されたホストの監視を無効化しました。

自宅にあるファイルサーバーを停止させるにあたって、Zabbix での監視を無効化しておかないと Slack にアラートが飛んできてしまうのでサーバーの停止の前に監視を無効化させます。
みんな大好き curlAPI を呼んでいます。

API の詳細は公式ドキュメントで → 19. API [Zabbix Documentation 3.4]

なお、この方法で無効化した後に「VPN で繋がるならポートフォワーディングでブラウザからフロントエンドにアクセスできんじゃね?」ということに気づいてしまい、設定してみたら繋がっちゃいました、ぐぬぬ

ログインしてアクセスキーを取得する

ログイン情報を環境変数に入れてアクセスキーを取ります。

$ export ZABBIX_URL=%ZabbixフロントエンドのURL%
$ export ZABBIX_USER=%Zabbixユーザー名%
$ export ZABBIX_PASSWD=%Zabbixユーザーのパスワード%

curl にこんな風な JSON を渡します。

{
  "auth":null,
  "method":"user.login",
  "id":1,
  "params":{
    "user":"${ZABBIX_USER}",
    "password":"${ZABBIX_PASSWD}"
  },
  "jsonrpc":"2.0"
}

帰ってくるアクセスキーも環境変数に入れたいので最終的に curl はこんな感じで実行しました。

$ export API_KEY=`curl -k -d "{\"auth\":null,\"method\":\"user.login\",\"id\":1,\"params\":{\"user\":\"${ZABBIX_USER}\",\"password\":\"${ZABBIX_PASSWD}\"},\"jsonrpc\":\"2.0\"}" -H "Content-Type: application/json-rpc" ${ZABBIX_URL}/api_jsonrpc.php | sed -e "s/^.*\"result\":\"\([^\"]*\)\".*$/\1/g"`

こちらを参考にしています→ zabbix-apiにcurlでログインする | CloudAdvisor

ホスト一覧を取得する

ホストに関する APIを見ると host.get でホストの情報を取得して host.update で状態を変更すれば良さそうです。
host.get した時に返ってくるホストの情報は Host object に出ています。内容は英語ですがページ翻訳すればだいたい大丈夫。host.update を見ると host.update で無効化したいホストの ID を添えて対象ホストの status1 にすれば良さそうです。

host.get でホスト一覧を取得して対象ホストの ID を確認します。JSON で返ってくるので適当な名前のファイルに保存しました。
curl にはこんな風な JSON を渡しています。

{
  "auth":"${API_KEY}",
  "method":"host.get",
  "id":2,
  "params":{
    "output":"extend"
  },
  "jsonrpc":"2.0"
}

API を呼びます。

curl -k -d "{\"auth\":\"${API_KEY}\",\"method\":\"host.get\",\"id\":2,\"params\":{\"output\":\"extend\"},\"jsonrpc\":\"2.0\"}" -H "Content-Type: application/json-rpc" ${ZABBIX_URL}/api_jsonrpc.php -o hostlist.json

これでホストの情報が hostlist.json に保存されます。中身を確認して対象のホストの ID を見てやります。

cat hostlist.json | jq "." | less

今回の対象は 10106 でした。この ID を無効化します。

対象のホストを無効化する

今度渡す JSON はこんな

{
  "auth":"${API_KEY}",
  "method":"host.update",
  "id": 3,
  "params":{
    "hostid":"10106",
    "status":1
  },
  "jsonrpc":"2.0"
}
$ curl -k -d "{\"auth\":\"${API_KEY}\",\"method\":\"host.update\",\"id\": 3,\"params\":{\"hostid\":\"10106\",\"status\":1},\"jsonrpc\":\"2.0\"}" -H "Content-Type: application/json-rpc" ${ZABBIX_URL}/api_jsonrpc.php

こんな JSON が返ってくれば OK っぽいです。

{"jsonrpc":"2.0","result":{"hostids":["10106"]},"id":3}

最後にホストのステータスを確認します。
こんな JSON を渡してステータスを確認。

{
  "auth": "${API_KEY}",
  "method": "host.get",
  "params": {
    "filter": {
      "hostid": ["10106"]
    }
  },
  "id": 5,
  "jsonrpc": "2.0"
}
$ curl -k -d "{\"auth\":\"${API_KEY}\",\"method\":\"host.get\",\"params\":{\"filter\":{\"hostid\":[\"10106\"]}},\"id\":4,\"jsonrpc\":\"2.0\"}"  -H "Content-Type: application/json-rpc" ${ZABBIX_URL}/api_jsonrpc.php | jq "." | less

ページャに渡された整形済 JSON を見て status1 になってれば OK です。

最後にログアウトしておきます。

$ curl -k -d "{\"auth\":\"${API_KEY}\",\"method\":\"user.logout\",\"id\":5,\"params\":[],\"jsonrpc\":\"2.0\"}" -H "Content-Type: application/json-rpc" ${ZABBIX_URL}/api_jsonrpc.php

この後監視を無効化したホストの Zabbix-Agent を停止してアラートが飛んでこないか確認して、ホストをシャットダウンしました。