📚

備忘録:『位置情報エンジニア養成講座』(#位置エン本)読了記録

2024/12/03に公開

はじめに

こんにちは、生成AIを活用しながら留学中の空いた時間を使って開発の勉強をしているニートです。
細かい自己紹介は初回の記事に書いてあります。

今回は『位置情報エンジニア養成講座』(#位置エン本)(井口奏大著)を一通り読み終えたので、
備忘録的に残しておきたい内容を記述できればと思っています。
https://amzn.asia/d/i0kvXCw

コンサル時代から不動産業界にかかわることが多かったこともあり、位置情報空間地理情報といったものに興味があり
『位置情報エンジニア養成講座』(#位置エン本)という本は結構前に買っていたのですが、長らく本棚に積んだままでした。

現在オーストラリアに留学しているのですが、何となく読みたいなぁと思っていたので、
荷物の制限がある中持ってきた5冊の本のうちの1冊です。

本の内容そのものは非常にためになったのですが、
この記事では本の紹介というよりも紙面上記載されていない以下の3点を書いておこうと思います。

  • WindowsユーザがgeoJSONをvector fileに変換する方法(tippecanoeの利用方法)
  • vector fileで利用するpbfフォントファイルの作成方法(mapboxのnode-fontnikの利用方法)
  • 指定避難所データ(csv)をgeoJSONファイルに変換する方法(QGISではなくpythonで処理)

前提

私自身ソフトウェア開発に関しては実務は全くの未経験です。
コンサルでIT寄りだったので知識がゼロというわけではないですが、本職ではないです。

書籍の書評は以下のブログを見てみるとよいと思います。私は大変満足しています。
https://qiita.com/sorami/items/bfeebba21216609ad576
https://note.com/taki__taki__/n/naa50cb09f5e7

書評にもありますが、この書籍では位置情報の入門的なお話から後半では位置情報を利用したアプリケーションの開発体験もすることができます。
前述していますが、特に後半の開発体験においては、著者がgithubでソースコードを公開しています。
https://github.com/Kanahiro/location-tech-sample-v1

それでは、中身に入っていきます。

WindowsユーザがgeoJSONをvector fileに変換する方法

geoJSONファイルをvector tileに変換する方法として tippecanoe(ティピカノー) というオープンソースツールを利用します。
macユーザは簡単に利用を進められるのですが、windowsは直接サポートされていないので、Linux環境を用意して実施する必要があります。

1.Ubuntsuの導入

windows環境上にLinux環境を入れるためにはWSLが必要です。
全く利用したことがない方は以下の記事を参考に入れてみてください。
https://qiita.com/_masa_u/items/d3c1fa7898b0783bc3ed

入れた後は、基本的にvscodeで開発する際は、windowsとWSLどっちで実行しているのか気にするようにしましょう。
WSL側からvscodeを開けばそれで問題ないですが、
windowsからvscodeを開いている人は、左下の青色の >< マークを押して、connect to WSL をクリックして環境設定するのがよいと思います。

2.tippecanoeのインストール

ここは書籍内でもコードの記載があるので不要かと思いますが、私は以下のような流れで処理しました。
このコードには、sudo等強制的な処理が多く含まれています。必ずご自身の責任で実施してください。

code
sudo apt update #Ubuntuのパッケージリストを更新→id,passwordが求められる
sudo apt install -y build-essential libsqlite3-dev zlib1g-dev #Tippecanoeをビルドするために必要な依存パッケージをインストール
git clone https://github.com/felt/tippecanoe #リポジトリのクローン

cd tippecanoe #クローンしたリポジトリのディレクトリに移動
make #build
sudo make install #install

#以下、正しくインストールされたかチェック用
teppecanoe -v 
teppecanoe -h

# geoJSONファイルのVectorTile化
cd .. #元の階層に戻ってから実行する
# 例1
tippecanoe -e tiles ./N03-20240101_GML/N03-20240101.geojson -l admin -ab -z8 -pC -P
# 例2
tippecanoe -e skhb -l skhb -Z5 -z8 -pf -pk -pC -P skhb.geojson

注意点

vector tileファイルが出来上がったら開発のプロジェクトに当該ファイルを移植して利用できます。

vector fileで利用するpbfフォントファイルの作成方法(mapboxのnode-fontnikの利用方法)

開発ライブラリであるMapLibre GL JSではglyphという特殊なフォント仕様があります。
これを利用するためには一般的なフォントファイルをpbfファイルに変換する必要があります。
書籍内ではgithubのソースコードにあるアセットを利用してね、という形になっていますが、
実際に自分で用意する方法として以下のfont-makerアプリケーションが紹介されています。

しかし、私はこのアプリケーションではうまくフォントを作ることができませんでした。
処理が動き始めるんですが、完了せずに勝手に終わってしまうんですよね。。。
→仕方ないので、別の方法ということで、node-fontnikというライブラリを利用したのでその紹介になります。

1.利用する元のフォントのダウンロード(ttfファイル)

私はNotoSnasJPをgoogle fontからダウンロードしました。
ご利用の際にはご自身でもライセンスは確認してください。

2.フォントファイルをttfからpbfに変換する

以下の記事を参考に実施しました。
https://qiita.com/T-ubu/items/f2a2084778e456bc8057

上記の記事の内容は今回の要件にはオーバーエンジニアリングなので
ubuntsu上でmapbox/node-fontnikを利用する
という基本方針をベースにもっと簡単な処理にします。

code
cd /mnt/c/Projects/Font #ディレクトリ移動
git clone https://github.com/mapbox/node-fontnik #githubクローン
cd node-fontnik #できたディレクトリに移動
make #build/install

cd .. #Fontディレクトリに戻る
mkdir Noto_Sans_JP_Bold_pbf #pbfファイルを管理するディレクトリを作成
./node-fontnik/bin/build-glyphs ./Noto-Sans-JP/static/NotoSansJP-Bold.ttf Noto_Sans_JP_Bold_pbf #上記で作ったNoto_Sans_JP_Bold_pbfフォルダにpbfファイルを作成する

できたフォントファイルをプロジェクトフォルダ内に移管したうえで、
プロジェクト内では以下のような記述で利用できます。

code
app
style: {
    // MapLibre-Style
    version: 8,
    glyphs: "./{fontstack}/{range}.pbf", //fontstackに下部のtext-fontが代入される
    sources: { 
#----省略
    {
        id: 'school-label-layer',
        source: 'school',
        type: 'symbol',
        minzoom: 12,
        layout: {
            'text-field': ['get', 'P29_004'],
            'text-font': ["Noto_Sans_JP_Bold_pbf"],

指定避難所データ(csv)をgeoJSONファイルに変換する方法(python処理)

アプリケーション開発体験の中で指定避難所場所データを利用するのですが、公開データはcsv形式となっており、地図アプリケーションにそのまま反映できません。
書籍内ではQGISを利用してファイル変換をしているのですが、
私自身QGISはあまりはまらなかった(GUI操作があまり得意ではなかった)のでpythonでやりました。
(これは完全に好みの問題です。)

1.利用する元の避難所データを取得(csvファイル)

国土地理院から出されているオープンデータです。避難所場所データ

2.csvファイルをgeoJSONファイルに変換する

親友(cahtGPT)と相談しながらpythonで処理することにしました。
pythonにはgeopandasという位置情報を取り扱うライブラリが存在していて処理は非常に簡潔です。

まずはvenvで実行環境を用意

code
python -m venv venv
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\venv\Scripts\activate
# start installing
pip install pandas geopandas shapely

以下の処理で書籍内ではQGISでやっているcsv→geoJSON変換と同様の処理が可能です。

code
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point

# CSVファイルの読み込み
df = pd.read_csv('./utils/全国指定緊急避難場所データ.csv')

# 不要なカラムを削除
df = df.drop(columns=["市町村コード", "都道府県名及び市町村名", "NO", "指定避難所との住所同一"])

# カラム名を変更
df = df.rename(columns={
    "施設・場所名": "name",
    "住所": "address",
    "洪水": "disaster1",
    "崖崩れ、土石流及び地滑り": "disaster2",
    "高潮": "disaster3",
    "地震": "disaster4",
    "津波": "disaster5",
    "大規模な火事": "disaster6",
    "内水氾濫": "disaster7",
    "火山現象": "disaster8",
    "緯度": "latitude",
    "経度": "longitude",
    "備考": "remark"
})

# disasterカラムをBooleanに変換 (nullはFalse、それ以外はTrue)
for disaster_col in ["disaster1", "disaster2", "disaster3", "disaster4", "disaster5", "disaster6", "disaster7", "disaster8"]:
    df[disaster_col] = df[disaster_col].notnull()

# 緯度・経度のカラムを指定して、Pointオブジェクトを作成
geometry = [Point(xy) for xy in zip(df['longitude'], df['latitude'])]
gdf = gpd.GeoDataFrame(df, geometry=geometry)

gdf = gdf.drop(columns=["latitude", "longitude"])
# print(gdf.info())

# GeoJSONファイルに出力
gdf.to_file('skhb.geojson', driver='GeoJSON')

上記でgeoJSONファイルができれば、あとはtippecanoeを利用して、vector tileにすることができます。

おわりに

位置情報どころかソフトウェア開発自体未経験ですが、
本を読み切って作りたいアプリケーションが1つ浮かんでいるので、まずはそれを作ってみようと思います。(年内目標)

また、本書籍は後続本も出ています。
https://amzn.asia/d/8k72nkZ

自分でアプリを作ってみる際には必要なサーバー側の知識が載っていそうなのでこちらもチェックしないといけないですね。
(物理本のが好きなのですがオーストラリアで手に入れるにはコストがかかりすぎるのでkindleで買いました。)
こちらも読み終わって自分なりのプラスアルファがあればまた記事にしたいと思います。

以上です。ありがとうございました。

Discussion