RaspberryPiで地図タイル

提供: ディーズガレージ wiki
2017年10月12日 (木) 02:47時点におけるShogooda (トーク | 投稿記録)による版 (ズームレベル11以降の検証)

移動先: 案内検索

夜景GoogleMapsがない。
全世界を撮影する飛行機も人工衛星もない。
当然、Googleを買収するお金もない。
夜景GoogleMaps(風)作ってみます。

夜景GoogleMaps(風)別窓

環境

ボード Raspberry Pi 3 Model B
OS 2017-09-07-raspbian-stretch-lite
microSDHC SanDisk Ultra microSDHC Class10 16GB
LAN 標準搭載の有線LAN

参考: Google検索 - raspberry win32diskimager -
(省略)

キーボードとモニターとLANを取り付け電源ON

デスクトップ環境のインストール

raspberrypi login: pi
Password: raspberry

$ sudo raspi-config
  7.Advanced Options → A1 Expand Filesystem
  tabでFinishでreboot

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install raspberrypi-ui-mods
$ sudo apt-get install fonts-vlgothic

$ sudo raspi-config
  3.Boot Options B1 Desktop/CLI → B4 Desktop Autologin
  4.Localisation Options
    I1 Change Locale → ja_JP.UTF-8でスペースキーで*印付けてtabでOK Default locale → ja_JP.UTF-8
    I2 Change Timezone → Asia → Tokyo
    I3 Change Keyboard Layout → Generic 105-key (Intl) PC → Other → Japanese → Japanese → The default for the keyboard layout → No compose key → No
    I4 Change Wi-Fi Country → JP Japan
  tabでFinishでreboot

追加アプリのインストール

参考: Raspberry Pi 3にデスクトップ環境をインストールする
Termitという端末があるのでこれを使ってみる
raspi-configのGUI版 Text Editor ターミナル ブラウザ 圧縮解凍 RealVNC

$ sudo apt-get install rc-gui leafpad lxterminal chromium-browser xarchiver realvnc-vnc-server

ホスト名変更

$ sudo leafpad /etc/hostname

変更

mapserver
$ sudo leafpad /etc/hosts

変更

127.0.1.1 mapserver

再起動

$ sudo reboot

IP固定

$ sudo leafpad /boot/cmdline.txt

末尾に(スペース空けて)追記

net.ifnames=0
$ sudo leafpad /etc/dhcpcd.conf

末尾に追記(設定内容は各ネットワーク環境により異なります。「Raspberry Pi IP固定」などで検索してみてください。)

interface eth0
static ip_address=192.168.1.190/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

再起動

$ sudo reboot

遠隔操作

運用にはモニター、マウス、キーボードは必要ないので、この段階で遠隔操作に
RealVNCが標準で入っているのでこれを使用

Menu→設定→RaspberryPiの設定→インターフェイスタブ→VNC有効→OK→再起動

何も考えずディスプレイを取り外しVNCに接続すると画面サイズが656x416となってしまう
おまじないがあるようなので設定

$ sudo leafpad /boot/config.txt
#hdmi_mode=1の下に以下を追加
hdmi_ignore_edid=0xa5000080
hdmi_group=2
hdmi_mode=47

参考: config.txt - Raspberry Pi Documentation

RaspberryPiをシャットダウン
モニター、マウス、キーボードを取り外して電源入れ直し
VNCクライアントから接続してみる

RealVNC Viewerの場合
VNC Server: mapserver.local または 192.168.1.190
Username: pi
Password: raspberry
Confirm: raspberry

成功していれば、以降はVNCクライアントの窓の中で作業

アップデートの自動化

インストール

$ sudo apt-get install unattended-upgrades
$ sudo dpkg-reconfigure -plow unattended-upgrades
GUIがでるので「はい」を選択<br />
Origins-Patternの設定はよくわからないのでこのままtab押して了解

設定

$ sudo leafpad /etc/apt/apt.conf.d/50unattended-upgrades

変更箇所

//Unattended-Upgrade::Automatic-Reboot "false";
を
Unattended-Upgrade::Automatic-Reboot "true";
に

//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
を
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

再起動

$ sudo reboot

下調べ

参考: OSGeo-Live 11.0 コンテンツ

サーバサイドで画像生成する場合はGeoServerかMapServer 魅力的だけどRaspberryPiでは心配 保留

参考: 地球地図を利用した地図タイルの作成 - FOSS4G TOKYO 2014 全体セッション2

地図タイルは静的ファイルを用意するだけでいい
mbtilesはsqliteにタイル化されたファイルを格納する仕様 扱いは簡単になるけど配信環境に苦労しそう 保留
地図タイルで全世界を吐き出すとズームレベル18で680億ファイルぐらい=linuxファイル管理限界値を超えるので注意
ファイル管理限界値(inode)はファイルシステム作成時に決定(固定)

参考: 地図タイルについて - smellman's Broken Diary

TMS(Tile Map Service)とWMTS(Web Map Tile Service)ならTMS採用 WMTSは厄介
ZXYタイル(ちょっと前までXYZタイルっていう人が多かった)はクソ仕様で規格化されてない
クソ仕様だけど国土地理院の地理院タイルやOpenLayersやLeafletなどで採用してる

参考: 地図タイルがおもしろい

地図タイル作成手順
地図画像があるとして
画像を地図情報付き画像(GeoTiff)にする
 ・gdal_translate
地図情報付き画像の座標系を変える
 ・gdalwarp
地図を地図タイルに変換する
 ・gdal2tiles.py

参考: cesium-assets/imagery at master · AnalyticalGraphicsInc/cesium-assets · GitHub

NASAのBlackMarbleのズームレベル0-8のタイルマップサービス(TMS)
このgithubリポジトリに格納するには大きすぎるので、http://cesium.agi.com/blackmarble にホストされています

方向性

地図タイル(ZXYタイル)
ファイル管理限界、データ容量、ズームレベルのバランス注意

ファイルシステムの確認

$ df -T
ファイルシス   タイプ   1K-ブロック    使用   使用可 使用% マウント位置
/dev/root      ext4        15242572 2423696 12167268   17% /

ext4

限界ファイル数の確認

参考: iノード(inode)とは

$ df -i
ファイルシス   Iノード I使用  I残り I使用% マウント位置
/dev/root       938672 81126 857546     9% /

938,672個

タイル数(ファイル数)の確認

ズームレベル 2n * 2n 合計枚数(枚) 累積合計枚数(枚)
0 20 * 20 = 1 * 1 1 1
1 21 * 21 = 2 * 2 4 5
2 22 * 22 = 4 * 4 16 21
3 23 * 23 = 8 * 8 64 85
4 24 * 24 = 16 * 16 256 341
5 25 * 25 = 32 * 32 1,024 1,365
6 26 * 26 = 64 * 64 4,096 5,461
7 27 * 27 = 128 * 128 16,384 21,845
8 28 * 28 = 256 * 256 65,536 87,381
9 29 * 29 = 512 * 512 262,144 349,525
10 210 * 210 = 1,024 * 1,024 1,048,576 1,398,101
11 211 * 211 = 2,048 * 2,048 4,194,304 5,592,405
12 212 * 212 = 4,096 * 4,096 16,777,216 22,369,621
13 213 * 213 = 8,192 * 8,192 67,108,864 89,478,485
14 214 * 214 = 16,384 * 16,384 268,435,456 357,913,941
15 215 * 215 = 32,768 * 32,768 1,073,741,824 1,431,655,765
16 216 * 216 = 65,536 * 65,536 4,294,967,296 5,726,623,061
17 217 * 217 = 131,072 * 131,072 17,179,869,184 22,906,492,245
18 218 * 218 = 262,144 * 262,144 68,719,476,736 91,625,968,981

画像のダウンロード

NASA Earth at Night : Feature Articles / Earth at Night: Flat Maps
2016 Color 21,600x21,600 GeoTIFF

見た目のズームレベルは8
見た目とズームレベルの参考: タイル座標確認ツール

画像の加工

WindowsPC
Photoshop使用

解像度が低いので地形の要素を除去し夜景の光の成分だけ抽出して使う
ベースの地形はBingmapの航空写真がよさげ レイヤ合成する方向で

Photoshopの限界は30万x30万pixel
一辺が3万pixelを越えるとPSD形式では保存できなくなる
加工できたとしても保存形式がビックドキュメント形式(PSB形式)となり、書き出しの種類が制限されBigTIFF(4GB制限解除)が無いためTIFF書き出し4GB制限に引っかかる

ビックドキュメント形式(PSB形式)から汎用フォーマットRAWの書き出しができる
汎用フォーマットRAWからGDALに持っていける形が理想と思われるが、どうもうまくいかない(要検証)
オリジナルの一辺2.16万pixelで加工しGDALで仕上げる

* NASAの2016 Color 21,600x21,600 GeoTIFF 8枚を使用
* 光ってる部分だけ抽出
* チャンネルミキサーでモノクロred:+100% green:+200% blue:-200%で白黒マスク作成
* 元画像に白黒マスクをあて青い成分除去
* エッジに黒い成分が残るので除去 ayato@web Un-Multiply
* ぼかし(ガウス) 半径1pixel ※これをやらないとズームレベル8以降のグラデーションが汚くなる
* 書き出しPNG BlackMarble_2016_**.png インターレースなし
BlackMarble_2016_A1.png
BlackMarble_2016_A2.png
BlackMarble_2016_B1.png
BlackMarble_2016_B2.png
BlackMarble_2016_C1.png
BlackMarble_2016_C2.png
BlackMarble_2016_D1.png
BlackMarble_2016_D2.png

OSGeo4W

参考: OSGeo4W_jp – OSGeo4W
WindowsPC
メタタグ付け直しなどに必要なのでインストール

VRTに変換

参考: PhotoshopでGeoTIFF編集したらメタデータ消えたんで付けなおそう
GeoTIFFでは半透明情報が消えてしまうためVRTフォーマットにする
参考: gdal2tilesで、pngの半透明情報を保持しつつタイル化する方法 - Qiita
WindowsPC
OSGeo4W Shell 起動

変換1

Photoshopで編集する前のGeoTIFFからWorldFileを生成
listgeo -tfw <フォトショ編集前の画像ファイル名>

> listgeo -tfw C:\maps\BlackMarble_2016_A1_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_A2_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_B1_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_B2_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_C1_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_C2_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_D1_geo.tif
> listgeo -tfw C:\maps\BlackMarble_2016_D2_geo.tif

リネーム

BlackMarble_2016_A1.tfw
BlackMarble_2016_A2.tfw
BlackMarble_2016_B1.tfw
BlackMarble_2016_B2.tfw
BlackMarble_2016_C1.tfw
BlackMarble_2016_C2.tfw
BlackMarble_2016_D1.tfw
BlackMarble_2016_D2.tfw

変換2

VRTにする

> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_A1.png C:\maps\BlackMarble_2016_A1.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_A2.png C:\maps\BlackMarble_2016_A2.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_B1.png C:\maps\BlackMarble_2016_B1.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_B2.png C:\maps\BlackMarble_2016_B2.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_C1.png C:\maps\BlackMarble_2016_C1.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_C2.png C:\maps\BlackMarble_2016_C2.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_D1.png C:\maps\BlackMarble_2016_D1.vrt
> gdal_translate -of "VRT" C:\maps\BlackMarble_2016_D2.png C:\maps\BlackMarble_2016_D2.vrt

変換3

VRTに座標系の情報を付与
gdal_translate -a_srs "EPSG:4326" <VRTのファイル名> <一時ファイル名>

> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_A1.vrt C:\maps\BlackMarble_2016_A1_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_A2.vrt C:\maps\BlackMarble_2016_A2_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_B1.vrt C:\maps\BlackMarble_2016_B1_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_B2.vrt C:\maps\BlackMarble_2016_B2_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_C1.vrt C:\maps\BlackMarble_2016_C1_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_C2.vrt C:\maps\BlackMarble_2016_C2_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_D1.vrt C:\maps\BlackMarble_2016_D1_temp.vrt
> gdal_translate -a_srs "EPSG:4326" C:\maps\BlackMarble_2016_D2.vrt C:\maps\BlackMarble_2016_D2_temp.vrt

変換4

一時ファイル(_temp.vrt)にWorldFileの情報を付与
geotifcp -e 編集前のGeoTIFF.tfw <一時ファイル名> <出力ファイル名>

> geotifcp -e C:\maps\BlackMarble_2016_A1.tfw C:\maps\BlackMarble_2016_A1_temp.vrt C:\maps\comp_BlackMarble_2016_A1.vrt
> geotifcp -e C:\maps\BlackMarble_2016_A2.tfw C:\maps\BlackMarble_2016_A2_temp.vrt C:\maps\comp_BlackMarble_2016_A2.vrt
> geotifcp -e C:\maps\BlackMarble_2016_B1.tfw C:\maps\BlackMarble_2016_B1_temp.vrt C:\maps\comp_BlackMarble_2016_B1.vrt
> geotifcp -e C:\maps\BlackMarble_2016_B2.tfw C:\maps\BlackMarble_2016_B2_temp.vrt C:\maps\comp_BlackMarble_2016_B2.vrt
> geotifcp -e C:\maps\BlackMarble_2016_C1.tfw C:\maps\BlackMarble_2016_C1_temp.vrt C:\maps\comp_BlackMarble_2016_C1.vrt
> geotifcp -e C:\maps\BlackMarble_2016_C2.tfw C:\maps\BlackMarble_2016_C2_temp.vrt C:\maps\comp_BlackMarble_2016_C2.vrt
> geotifcp -e C:\maps\BlackMarble_2016_D1.tfw C:\maps\BlackMarble_2016_D1_temp.vrt C:\maps\comp_BlackMarble_2016_D1.vrt
> geotifcp -e C:\maps\BlackMarble_2016_D2.tfw C:\maps\BlackMarble_2016_D2_temp.vrt C:\maps\comp_BlackMarble_2016_D2.vrt

変換5

個別に地図タイルに変換しても区域外が空の画像で上書きされてしまうので全て結合
参考: GDAL: gdal_merge.py

> gdal_merge.bat -o C:\maps\comp_BlackMarble_2016.vrt C:\maps\comp_BlackMarble_2016_A1.vrt C:\maps\comp_BlackMarble_2016_A2.vrt C:\maps\comp_BlackMarble_2016_B1.vrt C:\maps\comp_BlackMarble_2016_B2.vrt C:\maps\comp_BlackMarble_2016_C1.vrt C:\maps\comp_BlackMarble_2016_C2.vrt C:\maps\comp_BlackMarble_2016_D1.vrt C:\maps\comp_BlackMarble_2016_D2.vrt

地図タイルに変換

参考: GDAL: gdal2tiles.py
WindowsPC
OSGeo4W Shell 起動

> gdal2tiles.bat -r bilinear -z "0-9" "C:\maps\comp_BlackMarble_2016.vrt" "C:\maps\blackmarble_2016"

16GB microSDHC 限界ファイル数 938,672個
限界ファイル数93万個に納まるズームレベルは9(ファイル数349,525個)

xmlの削除

タイル毎に大量のxmlができてしまう
TMS(Tile Map Service)の仕様らしいが要らないので全部削除

Windowsのエクスプローラで検索して削除しても一気に削除できないのでコマンドで削除
参考: Windowsのdelコマンドを使って、特定のファイル名やパターンに一致するファイルをまとめて削除する

間違えると危険なので自己責任で

> cd C:\maps\blackmarble_2016
> del /s *.xml

完成データ

ズームレベル タイル数 容量
0-9 349,525個 592MB

Webサーバ

インストール

$ sudo apt-get install nginx

起動

$ sudo systemctl start nginx

地図タイルの登録

Windowsでblackmarble_2016フォルダをRAR圧縮
blackmarble_2016.rarをRaspberryPiの/home/piに入れる

UnRARのインストール
参考: raspberry pi でrarを解凍したい!
参考: raspberry piでrarを解凍する

$ wget https://www.rarlab.com/rar/unrar-5.3.7-arm.gz
$ gunzip unrar-5.3.7-arm.gz
$ chmod 755 unrar-5.3.7-arm
$ sudo mv unrar-5.3.7-arm /usr/local/bin/.
$ cd /usr/local/bin/
$ sudo ln -s unrar-5.3.7-arm unrar

解凍

$ cd ~
$ sudo unrar x /home/pi/blackmarble_2016.rar /var/www/html/

ビューワー準備

$ sudo wget http://dz.plala.jp/wiki_data/BlackMarble/BlackMarble_2016_html.zip
$ sudo unzip /home/pi/BlackMarble_2016_html.zip -d /var/www/html

設定

$ sudo leafpad /var/www/html/js/config.js

動作確認

http://127.0.0.1
ローカルネット内の他のPCから http://192.168.1.190

完成データの削除

いい方法が見付からずコマンドで消しました
間違えると危険なので自己責任で
WindowsPC
OSGeo4W Shell 起動

> cd C:\maps\blackmarble_2016
> del /s *.png

最後フォルダごと削除

ゴミの完全削除

参考: 管理者ゴミ箱 完全削除

$ sudo su
$ rm -rf /root/.local/share/Trash/files/*
$ rm -rf /root/.local/share/Trash/info/*

piユーザーのゴミの完全削除

$ sudo rm -rf /home/pi/.local/share/Trash/files/*
$ sudo rm -rf /home/pi/.local/share/Trash/info/*

ズームレベル11以降

検証中

ズームレベル タイル数 容量 16GB microSDHC
0-11 5,592,405個 3.15GB 登録不可

550万個のファイル数が原因で登録できない
ext4の限界ファイル数(inode)はファイルシステム作成時に自動設定され、作成時のオプションで手動設定可
また作成済ext4ファイルシステム(raspbian-stretch-lite)のinode変更は不可
16GBのmicroSDHCをパーティションで切りinodeを設定したext4ファイルシステムを用意
結果、見かけ上余裕のあるファイルシステムは用意できるが大量のファイルを登録してみるとなぜか容量でパンクする

NTFSは1ボリュームあたり限界ファイル数42億
参考:ファイル システム
42億ファイル数以内のズームレベルは15(1,431,655,765個)
3,150,000KB ÷ 5,592,405個 × 1,431,655,765個 = 806,400,047KB = 806GB
1TBのUSBポータブルHDDならいけるかも
とりあえず16GBのUSBメモリで試す

SanDisk Ultra microSDHC Class10 16GB は 48MB/s
RaspberryPiのUSB2.0の実測値は 20MB/s程度
半分になるのでレスポンス注意

過程

raspbian-stretch-lite自身がマウントされているmmcblk0のリサイズはできない
UbuntuのPCでgparted
mmcblk0p2を半分程度に縮小し、残りの空き容量をext4フォーマットするとmmcblk0p3ができる
Ubuntuの作業終わり

gpartedインストール

$ sudo apt-get install gparted

gparted起動

$ sudo gparted

情報確認 右クリック→情報
おかしければmmcblk0p3は操作できる
mmcblk0p3がマウントされてるならgpartedでmmcblk0p3をアンマウント
/dev/mmcblk0p3をinode設定付きで再フォーマット

$ sudo mkfs.ext4 -i 1024 /dev/mmcblk0p3
$ sudo mkfs.ext4 -i 1800 /dev/mmcblk0p3

マウントポイント作成

$ sudo mkdir /mnt/www

マウント

$ sudo mount /dev/mmcblk0p3 /mnt/www/

inode確認

$ df -i
ファイルシス   Iノード  I使用   I残り I使用% マウント位置
/dev/mmcblk0p3 7122496     11 7122485     1% /mnt/www
限界ファイル数 容量 使用済み 空き容量
7,122,496個
5,622,336個
6.79GB
9.42GB
1.81GB
1.45GB
4.99GB
7.97GB

UUID確認

$ sudo blkid /dev/mmcblk0p3

自動マウント設定

$ sudo leafpad /etc/fstab
proc            /proc           proc    defaults          0       0
PARTUUID=b085602f-01  /boot           vfat    defaults          0       2
PARTUUID=b085602f-02  /               ext4    defaults,noatime  0       1
PARTUUID=b085602f-03  /mnt/www        ext4    defaults          0       2
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

再起動

$ sudo reboot

確認

$ sudo gparted
/dev/mmcblk0p3を右クリック→情報

nginxの設定
ドキュメントルート作成

$ sudo mkdir /mnt/www/html

ドキュメントルート変更

$ sudo leafpad /etc/nginx/sites-available/default

41行目

root /mnt/www/html;