サマリー
自分が欲しい機能を詰め込んだ世界地図を覚えるWebアプリを趣味で作りました。
私と同じ趣味・趣向のある方、よかったら遊んでみてください。
https://geo-quiz-taupe.vercel.app/
** 本アプリは所属企業としての業務ではなく、筆者の趣味として作成したもので、営利を目的としたものではありません。
開発背景
5月某日、大阪万博に家族で行ってきました。
そこでCommons館に行った際、
ふと、娘が物心ついた時に
「パパ、世界の国全部わかるよ?」
とドヤ顔したいな、と思い、世界の国の位置を全部覚えたくなりました。
既存のアプリで探してみたものの、
- 「選択式ではなく国名で回答したい」
- 「一部抜粋ではなくすべての国を網羅したい」
- 「回答していくと地図が埋まっていく感覚が欲しい」
といった、自分が欲しい機能の満たされたものが見つからず。
そこで、エンジニアのDIY魂に火がついて、自力で作ることに。
要件定義(=自分が欲しい機能の列挙)
自分が欲しい機能を好きに詰め込みました。
欲しいモード
- 地域別モード
- 国旗クイズモード
- 辞典的に搭載している国を順に並べられるモード
クイズの形式
- 選択式ではなく、国名で回答できること
- 回答に幅を持たせる(一般的な略称やひらがなも正解とする)
- 一部抜粋ではなく、(基本的に)すべての国が網羅されていること
UIUX
- 回答していくと、地図が埋まっていく感覚が得られること
- 途中保存機能
- PCでもスマホでもできる
- 回答のたびに止まらず、サクサク進められる
開発
慣れた技術を使いつつ、最新バージョンを試す良い機会と捉えて開発を進めました。
主な使用技術
DB不要の、簡単なフロントエンドアプリとして実装。(コストゼロ!)
-
フレームワーク:
Next.js15(AppRouter) -
地図ライブラリ:
React Simple Maps
https://www.react-simple-maps.io/
世界地図を手軽に描画できるライブラリです。
ズームや画面中央の位置調整なども可能です。 -
デプロイ:
Vercel -
その他:
Tailwind CSS, TypeScript など
地図データの作成
React Simple Mapsで描画する地図データは、geojson or topojson形式で定義することができます。
https://www.react-simple-maps.io/docs/map-files/
今回は、下記のtopojson形式のサンプルデータ(features.json)をベースに使用しました。
https://www.react-simple-maps.io/examples/basic-world-map/
地図の描画は、topojson形式で指定することで、各国の領域が指定され、地図が描画されます。
ただし、このままだと、
- 日本語名がない
- 首都の座標がない
- 地域がない
など、情報が不足していたため、それらを生成AI(Gemini)の協力のもと、補いました。
こういう一般的な情報をもとにファイルを作ってもらうのに生成AIは便利ですね。
デザイン
地図の配色を、いろいろと試したものの、いまいちしっくりこず。
いろいろ悩んでいたところ、自分が好きな下記のYoutubeチャンネルのことを思い出し、地図の配色はこちらを参考にさせていただきました。
(余談ですが、下記のYoutubeチャンネルは、世界史を地球目線で見られて、すごく面白く、勉強になるのでおすすめです。)
国旗画像データ
下記のCDNを利用して、画像を表示しています。
https://flagpedia.net/
ただし、上述のtopojsonデータで利用している国のコードと、このCDNで必要なコードの形式が違うため、その対照表をコード内で持って置換をした上で、国のデータと国旗データを紐づけています。
国の紹介文
辞典モードと、クイズでのヒントとして、各国の紹介文を表示しています。
その紹介文も、生成AIに作成してもらいました。
ざっと見ている感じ、誤った情報はなさそうな気がしていますが、誤情報があったら、コメントにてご指摘ください。
心がけたこと
地図関連、クイズ関連で、色々なモードで共有する部分が多いため、コンポーネントの共通化には気を配りました。
その恩恵として、地域別モードの実装などがかなり楽にできました。
その他詰まった点
React Simple Mapsのインストール時に、詳細なエラーを覚えていないですが(Next.js15とのバージョンの整合性だったか?)、そのままnpm installするとエラーが出るため、下記のようにoverridesをして対応しました。
"overrides": {
"react-simple-maps": {
"d3-geo": "^3.1.0",
"d3-color": "^3.1.0",
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"react": "^16.8.0 || 17.x || 18.x || 19.x",
"react-dom": "^16.8.0 || 17.x || 18.x || 19.x"
},
"d3-interpolate": {
"d3-color": "^3.1.0"
},
"d3-transition": {
"d3-color": "^3.1.0"
}
}
開発時の課題
1. 世界の国の総数問題
「世界の国の総数」には実は明確な正解がなく、定義が様々です。
どの国目線で見るかによっても、定義は異なります。
日本目線で見る場合、下記2つが主な定義です。
定義 | 数 | 補足 |
---|---|---|
日本が承認している国の数 | 196 | 台湾、北朝鮮、ニューカレドニア、西サハラ、パレスチナ、プエルトリコなどは含まれない。 |
国連加盟国 | 193 | バチカン、コソボ、クック、ニウエなどは、日本は承認しているが国連未加盟。 |
作者としては、
- 地図を埋めていくゲームである以上、空白を残すのは本意でない
- 日本未承認でも、地域として大きい国(地域)は搭載する(台湾、北朝鮮など)
- できるだけ多くの国と地域を搭載したい
- バチカンやコソボなど、国連未加盟でも日本が承認している国は追加したい
- とはいえ、自治領など含め、すべてを搭載するのは大変
という考えだったため、
基本は上述のサンプルデータをベースに、一部の国を追加し、204の国と地域を搭載する形になりました。
(なので、「世界の国」というよりは、「世界の国と地域」という方が正確ではあります。)
2. オセアニアの島国問題
問題1:小さすぎて表示が難しい
オセアニアの小さな島国は、地図を拡大しても限界があり、クイズとして難問すぎる・・・。
問題2:島国の集合体の場合の旗を置く位置
キリバスなど、島国の集合体の国の場合、国の場所を指定するのが難しい。
首都に旗を指すが、実際は太平洋に散らばる国だったりするため、正確とは言い難い・・・。
成果と今後の展望
成果
今後のやりたいこと
-
タイムトライアルモード
- 制限時間内に、何カ国答えられるかを競うモード
- 小さい国ほど点数が高いようにする
-
国の形から、場所を当てるモード
- 隣接した国同士がぱちっとくっつく感じのUIUX
-
島国で小さすぎる時ときに、緯度経度の線を出してみる
-
アプリ化してみたい
- 久々にReactNative(Expo)を使って、アプリ化してみたい
-
メルカトル図法ではない、陸地のサイズが変わらない図法での地図表示も可能にしたい
気が向いた時に、ちまちま機能追加していけたら、と思っています。
まとめ
「自分が欲しいものを作る」というのは、やはりエンジニア冥利に尽きると改めて感じました。
アプリを遊んでの感想等あれば、コメントにて、教えてください!