読者です 読者をやめる 読者になる 読者になる

OpenStreetMap のノートデータを GeoJSON モドキに変換する

Windows PowerShell OSM

OpenStreetMap のノート機能によって残されたノートを取り出して解析しやすくできたらいいなと思ってデータを変換してみました。

まずノートのデータは Planet OSMnotes から最新のデータをダウンロードして解凍。
データは次のような XML になっていました

<?xml version="1.0" encoding="UTF-8"?>
<osm-notes>
<note id="4" lat="36.7232991" lon="68.8641500" created_at="2013-04-24T08:07:02Z" closed_at="2013-04-24T08:08:51Z">
  <comment action="opened" timestamp="2013-04-24T08:07:02Z" uid="1626" user="FredB">test</comment>
  <comment action="closed" timestamp="2013-04-24T08:08:51Z" uid="1626" user="FredB"></comment>
</note>
<note id="6" lat="35.5170066" lon="139.6322554" created_at="2013-04-24T08:12:38Z">

こんなんが約 205MB 分くらい書かれています。

最初は PowerShell でまじめに

PS> [xml](Get-Content planet-notes-latest.osn)

とかやろうとしたのですが、速攻でメモリが無くなったのであきらめました。

とりあえず今回ほしかったのは note 要素が持つ属性だけだったので、<note がある行だけを抜き出して文字列として処理する PowerShell スクリプトを書きました。
取り出した要素を GeoJSON っぽいフォーマットで表示させます。この方法だと一気に全部読まずに逐次処理するのでそんなにメモリを食いませんでした。
一応、ソースを乗っけておきますが、ほかの人が見ると頭を抱えそうなひどいコードです。

PS> ConvertFrom-Osn-to-GeoJSONmodoki.ps1 | Out-File notes.geojson -Encoding Default

みたいな感じで使います。

出力された GeoJSON モドキは最後の3行が

},
  ]
}

となっているので、テキストエディタ

}
  ]
}

となるようにカンマを消さないとエラーが出ます、油断大敵です。

出来上がった GeoJSON も世界中のデータが乗っているので、日本だけ切り出すために QGIS でクリップの処理か、日本のあたりだけ選択して選択されたオブジェクトだけを保存すると日本のデータだけが取り出せます。

XML を一気に読まないで逐次処理する方法探した方がいいだろうな…。

PowerShell から Twitter に投稿するだけのモジュールを作ってみた

Windows PowerShell

今度は PowerShell との格闘中にツイートしたくなったので、 PowerShell のプロンプトからツイートする PowerShell モジュールを作ってみました。
インストール方法は Github に書いておきました。

PowerShellPost@github

スクリプトの実行を許可していないと使えないはずです。Set-ExecutionPolicy の結果が RemoteSigned などになっていない場合には管理者権限で PowerShell を実行して Set-ExecutionPolicyRemoteSigned なりにしておいてください。
例によって CoreTweet を使って投稿するようになっています。

インストールスクリプトを実行して赤い文字が出てなければインストール成功なのでまずは Get-PspostOAuth コマンドを使ってアクセストークンとかをセットする必要があります。
AccessToken と AccessTokenSecret は $($env:USERPROFILE)\Documents\WindowsPowerShell\Modules\PsPost に setting.json という名前で保存されます。

Send-Text -Message "hoge" でツイートすることができます。

PowerShell のプロンプトを再起動してコマンドが使えない場合は Import-Module -Name PsPost して読み込んであげてください。

作成は Windows 7 Enterprise 64ビットで PowerShell は 4.0 を使用している環境です。

PowerShell で iTextSharp を使って PDF にテキストを追加する

Windows PowerShell

番号管理している土地の図面に所有者の名前入れて名前でフォルダ分けしやがれという無茶振りを受け、PDF 化済の図面に所有者名を入れることになったので書いたスクリプトです。
名前でフォルダ分けするのは何回か PowerShell で行ったことはありますが、PDF に文字列を追加するのは初めてでした。

今回は PowerShell を使って iText で配布されている iTextSharp を読み込んで文字列を追加させています。
各種ファイルパスが B ドライブにあるのはただの RAM DISK なので気にしないでください。ついでに用紙サイズが B4 なのですが、伝統なので気にしたら負けです。

引っかかったところ

まず用紙サイズ。
iTextSharp.text.Rectangle で作っている用紙サイズの数値はミリメートルではなく 28.35 px/cm を基準として必要な数字が取り出せました。PDF を Tiff で保存するときの一番低い解像度と同じ単位ですね。 最初はミリメートルを指定してエラい小さい図面になってしまいました。

次いで用紙の向き。 元の PDF は B4 横の図面なのですが、iTextSharp.text.pdf.PdfReader で読み込むと B4 縦で配置されてしまいました。
そこで AddTemplate を使って回転させたのですが、こいつの指定にも難儀しました。
回転行列と dx, dy っぽい値を入れたら回転してくれました。合ってるのかなこれ…。

$$ \begin{bmatrix} Cos \theta & - Sin \theta \\ Sin \theta & Cos \theta \end{bmatrix} $$

オレ達の戦いはこれからだ

これで1枚分は名前を入れられるので、番号と名前のデータベースを PowerShell で読み込んで振り分けるスクリプトを書かないとですね。
何枚もやって変な風に出てきたら泣くしかない。

PowerShell で緯度経度と平面直角座標を相互変換する API を利用する

PowerShell

前回のエントリに似た内容を PowerShell で作成しました。
国土地理院の測量計算サイトで公開されている APIPowerShell で使います。

PowerShell から API の一部である「緯度、経度から平面直角座標への換算」と「平面直角座標から緯度、経度への換算」を利用するスクリプトです。

コードは Github に置いてあります

API を利用するためには測量計算 API 利用規約に同意する必要がありますのでご注意ください。

こちらは受け取った情報を URL にしてサーバに送信し、受信した JSON を返す形です。
XML より扱いが簡単そうだったので JSON にしました。
Excel で書いていた分早く書けました。
というか大分短く書いても使えそうな感じだったので短いです。

設定ファイルを複数マシンで共有する

Linux PowerShell Windows

前半はLinuxドットファイルgithubで同期させてる話で後半はPowerShellのプロファイルをDropboxで同期させてる話です。

Linuxドットファイルを同期させる

Linuxドットファイルgithubで同期する方法があちこちに書かれていたので同じ様にやってみました。
登録してあるリポジトリは下記のURLです。
dotfiles

作り方もあちこちに書いてありますが、自分用にメモしておきます。

適当なディレクトリを作成して、そこに現在のドットファイルを移動する

# cd ~
# mkdir dotfiles
# mv ./.profile ./dotfiles/
# mv ./.screenrc ./dotfiles/
# mv ./.vimrc ./dotfiles/

移動したファイルからホームディレクトリにシンボリックリンクを作成するスクリプトを作成する。

# cd ~/dotfiles
# touch dotfileslink.sh
# chmod +x dotfileslink.sh
# nano dotfileslink.sh
#!/bin/sh
# ln -sf ~/dotfiles/.profile ~/.profile
# ln -sf ~/dotfiles/.vimrc ~/.vimrc
# ln -sf ~/dotfiles/.screenrc ~/.screenrc

スクリプトを実行してgithubに登録する

# ./dotfileslink.sh
# git init
# git add -A
# git commit -a -m "Initial commit"
# git remote add origin %githubのURL%
# git push origin master
新しいマシンでの取り込み

新しく設定したLinuxドットファイルを利用するためには、gitをインストールした後にホームディレクトリでいくつかのコマンドを実行すればOk。

# git clone %githubのURL%
# cd dotfiles
# ./dotfileslink.sh

PowerShellのプロファイルも同期してみた

こちらはgithubではなくてDropboxリポジトリを作成しています。
~\Dropbox\git\psprofileを作成して設定します。

> New-Item -Type Directory ~/Dropbox/git/psprofile
> Set-Location ~/Dropbox/git/psprofile
> git init --bare --share=true

プロファイルがあるディレクトリに移動して適当なディレクトリを作成します。

> Set-Location ~/Documents/WindowsPowerShell
> New-Item -Type Directory dotfiles

既に存在しているプロファイルを作成したディレクトリに移動します。
名称も変更しているのは別のマシンで取り込む時に必要そうだったからです。
移動した後は新しいディレクトリ内のスクリプトをプロファイルに取り込むためのプロファイルスクリプトを作成します。

> Move-Item Microsoft.PowerShell_profile.ps1 ./dotfiles/psprofile.ps1
> Write-Output ". ~\dotfiles\psprofile.ps1" > $PROFILE
> Copy-Item $PROFILE ./dotfiles

ここまでできたらDropboxリポジトリに突っ込んでおきます。

> Set-Location ./dotfiles
> git init
> git add -A
> git commit -a -m "Initial commit"
> git remote add origin ~/Dropbox/git/psprofile
> git push origin master

こんな感じで。

新しいマシンでの取り込み

もちろんgitを入れてパスの設定までしておかないといけませんし、Dropboxを入れて同期が完了していないといけません。

> New-Item -Type File -Force $PROFILE
> Set-Location ~/Documents/WindowsPowerShell
> git clone ~/Dropbox/git/psprofile
> Set-Location ./dotfiles
> Copy-Item ./Microsoft.PowerShell_profile.ps1 ../

これでPowerShellを立ち上げ直せば他のマシンと同じプロファイルが使えるはずです。

PowerShellの場合git入れるのが面倒だったり、設定ファイル一つならコピーしちゃってもいいんですけどね。

Get-Contentで文字コードを指定してファイルを読み込む

Windows PowerShell

JOSMで作成した地物データファイルをPowerShellで読み込もうとしたところエラーになってしまいました。

PS > $a = [xml](Get-Content .\基準点.xml)
値 "System.Object[]" を型 "System.Xml.XmlDocument" に変換できません。エラー: "'<' (16 進数値 0x3C)
は無効な属性文字です。 行 12、位置 5 です。"
発生場所 行:1 文字:11
+ $a = [xml] <<<< (Get-Content .\基準点.xml)
    + CategoryInfo          : NotSpecified: (:) []、RuntimeException
    + FullyQualifiedErrorId : RuntimeException

構造に問題があるのかと思ったけどInternetExplorerなどではエラーなく表示できるので問題ないはず。

xyzzyで「基準点.xml」を開いてみたところ文字コードが「utf8n」となっていました、BOMなしのUTF-8のようです。
BOMがないことによって文字コードの判別に失敗したPowerShellがエラーを起こした模様。

Get-Contentで読み込む際に文字コードを指定できれば解決しそうということで「-Encoding UTF8」を付けて実行してみたところうまく解釈してくれました。

PS > $a = [xml](Get-Content -Encoding UTF8 .\基準点.xml)

Get-HelpしてもGet-Contentに「-Encoding」のオプションなんて出てこなかったような気がするけどこれでイケました。

2014/04/24追記

////ココカラ
日本語ヘルプの入っていないPowerShellだと「-Encoding」のオプションが表示されるようです。
環境によってちょっと異なるようですね。
////ココマデ

2014/04/24さらに追記

////ココカラ
Windows8だと日本語でも「-Encoding」の説明が出てきました。
本文で実行した環境はWindows7だったのでその辺の違いもあるんですかね。
////ココマデ

PowerShellでリモートマシンに接続する

Windows PowerShell

PowerShellでリモート管理できないか探していたらリモートマシンに接続する方法があったので試してみました。
今回勢いで実機でテストしてしまったのは内緒です。

構成は下記のような感じ。

  • サーバー(接続される側):ThinkPadX200 Windows 8.1 Pro Update 1
  • クライアント(接続する側):ThinkPadT420 Windows 7 Enterprise SP1

以下設定メモ

続きを読む