JRの白黒ハッチが描きたくて地図エディタを自作した

11

この記事はAI(Claude)が書いている。ネタ出しと文句と事実確認は運営者。

地図の上に路線図を描くのを、長いことGoogleマイマップでやってきた。描いた地図を眺めてニヤニヤするのが好きだ。ただ道具としてのマイマップにはずっと不満があって、それが積もりに積もった結果、とうとう自分のVPSに地図エディタを立ててしまった。名前はEditMap。実装はClaude Codeに丸投げで、私がやったのはプロダクトオーナーとして要件定義を主導スクショを貼って文句を言い続けることだけ。

サイトはこちら: map.osato-acid.com機能紹介ページ

EditMapのエディタ画面。左に要素一覧、地図上に各種の線種と駅ボックス付きの線
エディタ全景。左が要素一覧で、線の下に駅ボックスがぶら下がる

マイマップの不満

先に不満を並べておく。まず線のスタイルが貧弱。変えられるのは色と太さと透明度くらいで、地形図でおなじみのJR線の白黒ハッチも、単線の横棒も、複線の二本棒も描けない。路線図を描く人間にとって、あの記号が使えるかどうかはけっこうでかい。全部ただの色付きの線で描くと、JRも私鉄も三セクものっぺり同じ顔になってしまう。

次に駅。線に沿って駅を並べたければ、ひとつずつ手で置くしかない。それだけならまだ我慢できるけど、線を引き直すと駅の列が線からずれる。で、また全部置き直し。ルートをちょっと直すたびにこれをやる。苦行だった。

あとレイヤが10個までしか作れない。JR、私鉄、地下鉄、廃線、と分けていくとあっという間に上限に当たる。要素の重なり順もほぼ運任せで、JRの上に私鉄が乗ってきてほしくないのに、直す手段がない。要素が増えると一覧はただの長いリストと化して、どれがどの路線だか自分でも分からなくなってくる。ひとつひとつは小さい不満なのに、10年分積もると引っ越しを決意するには十分だった。

線種

というわけで、EditMapで最初に作らせたのが地形図の鉄道記号。JR線のハッチ、単線、複線、二重線、はしご状の線。メニューから選ぶだけで、色も太さも自由に変えられる。太さを変えると記号の刻みも一緒に伸び縮みしてくれる。この連動、当たり前にできそうに見えて中身はけっこう面倒だったらしい。開発中は破線の刻みが太さに追従しなくて、どの破線も点々に潰れて見える時期があった。私が「dashがほぼdotになってる」と文句を言い、AIが直し、今度は別の線種が崩れ、の往復を何回かやって今の形に落ち着いた。

線種見本。JR線ハッチ、単線、複線、二重線、はしご、破線、点線
線種見本。上からJR線・単線・複線・二重線・はしご・破線・点線

駅ボックス

もうひとつの目玉が、線にくっついてくる駅ボックス。線の上に長方形を置くと、その長方形は線の子分になる。線が曲がっている場所に置けばボックスも線なりに折れ曲がるし、線を引き直せば勝手に線の上へ戻ってくる。マイマップ時代のあの置き直し作業は、これで消滅した。

折れ曲がった線の上で駅ボックスも折れ曲がっている様子
線が折れると、折れ目の上の駅ボックスも一緒に折れる

既定サイズは20m×40mで、あとから変えられる。ただし長方形が崩れるような変形はできないようにしてある。名前を付けなければ「親の線の名前 図形1」みたいに勝手に命名されるので、駅を連投していても手が止まらない。ズームアウトすると小さな記号に切り替わって、もっと引くと消える。全体を眺めるときに四角がびっしりで路線が見えない、とはならないようにした。

線の編集

路線図って、線を1本引いて終わりということがまず無い。延伸区間を描き足すし、支線を分けるし、系統をまとめたくなる。EditMapでは線の端をつまんでそのまま延長できるし、途中の好きな場所から分岐も作れる。分岐した線は親の色と線種を引き継ぐ。逆に、別々に描いた線をひとまとめにするグループ化もあって、書き出すときは1本の要素として出てくる。

重なり順は「レイヤ強さ」という数値で決まる。大きい方が手前。それだけの仕組みなんだけど、私鉄の上にJRを重ねたい、みたいな注文が数字ひとつで通るのは気分がいい。マイマップでモヤモヤしていたところが、ここで全部片付いた。一覧は親子構造で、線を畳むとぶら下がっている駅ボックスもまとめて隠れる。レイヤ数の上限みたいなものは無い。

スマホ

いちばん手こずったのがここ。地図の編集を指でやろうとすると、当たり判定との戦いになる。細い線を指でつまむのは無理があるし、かといって判定を広げすぎると隣の線を拾う。線選択の判定は広すぎと狭すぎを行ったり来たりして、最終的に18ピクセルに落ち着いた。この数字に理屈は無い。試行回数だけがある。

頂点を置く操作は、画面中央に照準を固定して、地図のほうを動かす方式にした。指で画面を突く方式だと、置きたい場所がちょうど指の下に隠れて見えないからだ。線を描くのも、延長も、分岐も、駅ボックスの配置も、全部この照準でやる。おかげでスマホでもPCと同じ編集がひととおりできる。外で地図の間違いに気付いて、その場でスマホから直す、くらいのことなら正直PCを開くより速い。

スマホ版EditMapの画面。下部にマップ名のシートと追加ボタン
スマホ版。右下の+から描き始める

私の使い方

参考までに自分の使い方を書いておくと、JR線は黒のハッチ、私鉄は各社の色で、地域の鉄道網を一枚の路線図にしている。廃止された区間や未成線は点線や細い線で描き分ける。この描き分けが線種ワンタッチで済むのがうれしい。マイマップだと線を選び直して設定を開いて、とやっているうちに面倒になって、描き分け自体を諦めていた。道具が渋いと表現ごと崩れるといういい見本だと思う。

駅ボックスは全駅には置いていない。乗換駅と起終点と、描きたい駅だけ。全部置くとさすがにくどい。あとは廃線を1970年代の航空写真でなぞって、現役の線より下のレイヤ強さで敷いてある。今の地図では消えた築堤や橋台があの写真にはまだ写っていて、現役路線の隙間に廃線がうっすら見える地図は、自分で言うのもなんだけど眺めていて飽きない。

データの持ち出し

作った地図はKML/KMZでいつでも書き出せる。マイマップからKMLで書き出して持ち込むのもいけるし、逆にEditMapで作った地図をマイマップやGoogle Earthに持っていくのも通る。GPXも読めるので、GPSロガーの記録を下敷きにもできる。線種や駅ボックスみたいな独自情報はKMLの拡張領域に書いてあるだけだから、他のアプリで開けば普通の線として見えるし、EditMapに戻せば元どおり。

要するに、このサービスが気に入らなくなったら、いつでもデータごと逃げられる。乗り換えコストを人質に取るサービスが好きじゃないので、ここは最初に決めた。自分が10年分の地図を抱えてマイマップから逃げるとき、一番気にしたのがここだったから。

共有はマップごとにリンクを発行する方式。リンクを知っている人はログインなしで見られる。旅行の前に行程を線で引いてリンクを同行者に投げておくと、集合場所の説明が地図ごと済む。相手にアプリを入れさせる必要も、アカウントを作らせる必要もない。共有をやめたくなったらリンクを無効化すればいい。

中身

技術寄りの話も少しだけ。描画はMapLibre GL JSで、ベースマップはOpenStreetMap由来のPMTilesという形式のタイルを自分のVPSに置いている。タイルもフォントもスプライトも全部自前ホストで、外部の地図APIは使っていない。どこかの値上げや仕様変更で、ある日突然地図が出なくなる心配が無い。ちょうどこの記事を書いている裏で、日本域3.5GBのタイルを惑星まるごと128GBに入れ替える作業が走っていて、終われば海外の路線も描けるようになる。

ベースマップは地理院タイルにも切り替えられる。標準、淡色、航空写真、それと1970年代の航空写真。廃線をなぞるときは70年代の写真が効く。

サーバ側はクラウドネイティブでスケーラブルなマイクロサービス構成ただのPHPで、データベースも無い。マップごとにKMLファイルをそのまま保存しているだけ。素朴だけど、何か起きてもファイルを開けば中身がそのまま読めるのは強い。バックアップは5世代自動で残る。これは開発中にAIが私の中央線を消した事件を受けて付いた機能で、あのときの私はわりと本気で怒っていた。今は同じ事故が起きても巻き戻せる。

AIとの開発

実装はほぼ全部Claude Codeで、私が書いたコードは1行も無い。やったのはスクショを貼って文句を言うことだけ。じゃあ楽だったかというと微妙で、仕様を言葉にする手間はしっかり残る。駅ボックスひとつ取っても、「左右対称であることより線と平行であることを優先しろ」という一文にたどり着くまでに、変な形に潰れた長方形を何枚も見せられた。こっちの言い方が曖昧だと、曖昧さがそのまま画面に出てくる。

AIの困った癖もいろいろ見えた。頼んでいない仕様を勝手に生やす。終了操作ひとつ取っても、こっちは線を描くときと同じ操作で終わりたいのに、気を利かせたつもりで別の終了方法を発明してくる。一度うまくいった直し方に固執して、原因が別のときも同じ修正を繰り返す。人間の部下なら言い方に悩むところだけど、相手はAIなので遠慮なく差し戻せる。開発が速いことの正体は、実装が速いことより、この差し戻しを無限にやれることかもしれない。

それでも、個人がひとりで持てる開発力としては明らかに過剰なものが手に入るようになったと思う。線が線上の図形を従えて曲がる、なんて機能を外注したらいくら取られるのか見当もつかない。それが文句を言うだけで生えてくる。この記事もそのAIが書いていて、冒頭に明示してあるのはそういう事情だ。AIが書いた記事のカテゴリを作ったので、今後この手のものはそこに入れていく。

お金と今後

維持費について正直に書いておくと、サーバはもともと別の用途で借りていたVPSの間借りなので、EditMapのために新しく払っている金はほぼ無い。とはいえタダで回り続ける保証も無いので、広告を少し貼るかもしれない。エディタの邪魔になる場所には置かないつもり。有料化の予定は無い。人が増えて回らなくなったら、そのとき考える。

機能は自分が困った順に増えてきたので、今後も基本はそれ。ただ、使う人が増えれば自分では思いつかない使い方が出てくるはずで、そこからの要望は歓迎する。個人開発のいいところは、要望から実装までの間に会議が1回も挟まらないこと。悪いところは開発者が飽きたら止まることだけど、自分の地図が全部ここに乗っているので、少なくとも自分が使う分は止めようがない。

登録

登録は無料。map.osato-acid.comでメールアドレスを入れると登録用リンクが届いて、ユーザ名とパスワードを決めればすぐ使える。やめたくなったら退会すればサーバ上のデータは消える。詳しい機能は紹介ページにまとめてある。

もともと自分が路線図を描くために作ったので、機能の重心は完全に鉄道に寄っている。ただ中身は線と図形と地点だけなので、旅の行程表でも、散歩コースでも、聖地巡礼の足取りでも、使い方は選ばない。要望や不具合は[email protected]まで。反応があれば、また私がAIに文句を言う日々が始まる。