-
プロジェクト名: 時空地図アプリケーション(time-map-app)
-
目的: 架空世界の地理と歴史を、ユーザーが時間軸に沿って直感的に視覚化・追跡できるツールを提供する。
対象となる世界の歴史的出来事の変遷を地図上で確認することで、ユーザーは歴史的な進展や地理的変化を簡単に理解できる。
-
使用環境:
- スタンドアロンのデスクトップアプリケーションとして動作。
- プラットフォーム: Windows デスクトップ(Electron 使用)。
- 通信なしでオフライン環境でも利用可能。
-
ベースマップ表示:
- SVG形式の地図データをサポート。
- 横方向無限スクロールを実現し、地図の東端・西端をまたぐ領域を表示可能。
- ズームイン・ズームアウト、パン操作をサポート。
- 世界地図全体から都市内地図レベルまでの広範囲かつスムーズなズームを実現。
-
地理データの表示:
- 以下のデータを表示可能:
- 点データ: 都市、出来事など
- 線データ: 道路、交易路、鉄道など
- 面データ: 国家、領域(無政府地帯を含む)など
- 面データの階層性: 国家に州・県・村・字などの下位領域を任意の層数追加可能。
- 結合した面データ:
- ユーザーがこれらのデータを個別に切り替えて表示できるフィルター機能を提供。
- グリッド表示: 経度緯度を示すグリッドを表示。
- グリッド表示のON/OFFを切り替えるボタンを追加。
- 以下のデータを表示可能:
- 時間軸スライダー:
- スライダー操作により、特定の年月日のデータを表示するように即時切り替え。
- 日単位でのデータ管理を基本とし、過去から未来へデータを動的に切り替え可能。
- 任意の最小日付と、最大日付が設定可能。
-
編集モード:
- 地図上で以下のデータを追加、編集、削除可能な専用モードを提供。
- 点データ: 都市や出来事などの位置を編集可能。
- 線データ: 道路や交易路、鉄道などの編集が可能。
- 面データ: 国家や領域の編集が可能。
- 以下のツールが存在する。
- ポイント移動
- 点データをマウスでドラッグして移動可能。
- 編集後は即時反映される。
- 編集中の対象が明確にハイライトされる。
- ポイント属性編集
- 点データのプロパティ(名前、説明、年など)を直接編集可能。
- 編集後は即時反映される。
- ライン属性編集
- 線データのプロパティを変更可能。
- 編集後は即時反映される。
- 編集中の対象が明確にハイライトされる。
- ライン頂点編集
- 線データの頂点を移動、追加、削除可能。
- 編集後は即時反映される。
- 新しい頂点を追加する際は線上をクリックする。
- ポリゴン属性編集
- 面データのプロパティを編集可能。
- 編集後は即時反映される。
- ポリゴン頂点編集
- 面データの頂点を自由に移動可能。
- 編集後は即時反映される。
- 新しい頂点を追加する際は線上をクリックする。
- ポイント移動
- 地図上で以下のデータを追加、編集、削除可能な専用モードを提供。
-
分裂・合邦機能:
- 線および面データの場合、分裂・合邦ができる。
- 分裂:
- ユーザー操作により、任意のタイミングでオブジェクトを分裂させられる。
- 分裂後の新しいオブジェクトの命名や属性は手動設定。
- 合邦:
- ユーザー操作により、任意のタイミングでオブジェクトを一つにできる。
- 合邦後のオブジェクトの名称や属性も手動設定。
- 整合性:
- 過去事象の操作により、未来の事象と整合性が取れなくなることもあるが、ユーザーの操作に任せてアプリケーション側での整合性判定は行わない。
-
頂点編集:
- 編集モード内で、以下の操作が可能:
- ツール選択: 「ライン編集」または「ポリゴン編集」ツールを選択。
- 頂点ハンドル表示: 編集対象の線または面の頂点が、小さな円形のハンドルで表示される。
- 頂点の選択:
- クリック: 頂点ハンドルをクリックして選択。
- 複数選択: Shiftキーを押しながらクリックで複数の頂点を選択可能。
- 頂点の移動: 選択した頂点ハンドルをドラッグして移動。グリッド表示がONの場合、スナップする。
- 頂点の追加: 線や面のエッジ上をクリックすると、新しい頂点を追加可能。
- 頂点の削除:
- Deleteキーで削除。
- 頂点ハンドルを右クリックして「頂点を削除」を選択。
- コンテキストメニュー: 右クリックで「頂点を削除」などのオプションを提供。
- アンドゥ・リドゥ: 編集操作はアンドゥ・リドゥ対応。
- 範囲選択: マウスドラッグで矩形選択範囲を作成し、範囲内の頂点を選択可能。
- 編集モード内で、以下の操作が可能:
-
属性管理:
- 各データにカテゴリやタイプ属性を設定可能。
- 都市タイプ、戦闘タイプ、道路、鉄道、国家、領域(無政府地帯)などを設定。
-
詳細情報の記載:
- 都市や出来事、その他の地理データに対して名前や説明文を追加可能。
- テキスト、画像、リンクなどのマルチメディアコンテンツが添付できる。
-
情報の表示:
- 地図上のデータをクリックすると、ポップアップウィンドウで詳細情報を表示。
-
ツールチップの表示:
- 地図上のデータにマウスオーバーすると、ツールチップで名前と概要情報を表示。
- ドラッグ終了後にも、対象のフィーチャ名や年などが表示される。
- データ保存:
- ユーザーが編集したデータをローカルファイル(JSON形式)に保存可能。
- データ読み込み:
- 保存されたデータを読み込んで表示。
- 警告機能:
- 保存していない状態で読み込みをしようとすると、警告が表示。
- UI要件:
- 基本操作が直感的に可能なインターフェースを提供。
- フィルター機能を用いてデータを直感的に表示。
- モーダルダイアログによる設定画面や、複数のフォーム/ウィンドウをドラッグ移動可能にすることで視認性と操作性を高める。
-
多層レイヤー構造:
- 面データを複数階層(レイヤー)で管理できる。下位領域は必ず上位領域に内包され、複数の上位領域に同時所属はしない。
- レイヤースライダーやレイヤーパネルによって、上位~下位までの階層を切り替え表示する。
- 下位レイヤーが未定義の領域は、上位レイヤーの形状を流用し“無主地”化を防ぐ。
- 下位面が存在している状態では、上位面を直接操作できない。上位の境界を動かしたい場合は、下位面を操作する必要がある。
-
共有頂点:
- 全頂点を一元管理し、複数ポリゴンが同じ頂点IDを参照することで国境線を連動移動できる。
- 頂点をドラッグするとすべての共有ポリゴンに反映。
- 右クリックメニューで「共有を解除(Unlink)」を選ぶと、別の頂点IDを生成して片側だけ座標を変更できる。隙間には無主地が残る。
-
分割・合体の拡張:
- 分割(Split)時に、ユーザーの操作単位でアンドゥ・リドゥが可能。
- 合体(Merge)時は、複数ポリゴンを1つにまとめる。下位領域もまとめて再所属させる。
- 飛び地は、同じ上位領域(例: countryId)を持つ複数ポリゴンとして管理。包領(穴あき)はブーリアン演算で上位ポリゴンをくり抜く方式。
-
自動再計算:
- 下位レイヤーを編集(形状変更)した時、親レイヤーも自動的に再計算して穴あき・結合を同期。
- 大規模データの場合はパフォーマンス最適化が別途課題となる。
-
Undo/Redoの粒度:
- ユーザーが行う操作(ドラッグや分割など)単位で、必ず前の状態に戻れる。Redo時には入力値まで復元される。
- ログレベルは呼び出し頻度が高いほど高レベル(4)を使う。詳細は最も高レベルにする
- 大小問わずすべての関数に呼び出しログを設ける。この呼び出しログはtry-catchの外側、関数の一行目に設置する。
- エラーは必ずログに記載する。
- ログ管理を簡易にするため、すべてのログの形式は日本語とし、定型的な文章は合わせる。
-
Version 1(done):
- 地図表示(SVGの表示、ズーム、パン、横方向無限スクロール)。
- 基本的な時間スライダーによる年次データの切り替え。
- 点・線・面データの追加・編集・削除。
- 頂点編集機能。
- JSON形式でのデータ保存・読み込み。
- 基本的な属性(名前、説明、年)の設定。
- 基本的なUIと通知、設定ダイアログ。
- 編集ツールの改良(アンドゥ・リドゥ)
-
Version 2:
- データ属性の拡張(カテゴリ、タイプ属性)
- 時間スライダーによる形状変更の追跡
- 分裂・合邦機能の実装。
- 注釈機能の拡張(画像やリンクの添付)。
- 編集ツールの改良(アンドゥ・リドゥ、グリッドスナップ)。
-
Version 3:
- 時間管理の詳細化(月・日単位の対応)。
- マップレイヤーの追加(気候、人口密度など)。
- 私が要望を出す
- あなたが開発する
- 私が受け取り、ソースにコピペで適用する
- 私がテストする
- 私がFBをする
- あなたが修正する
- (受け取り・テスト・FB)
- FBがなくなるまで繰り返す ソースをコピペで適用するので、修正したファイル全体を省略なく提示してください。また、似たような修正を複数ファイルに行う場合でもちゃんと全て提示してください。
-
- 修正や追加を行ったファイルは、一切省略せずに完全なコードを提示してください。
- 修正や追加を行っていないファイルについては、表示する必要はありません。
- 同じファイルに対する修正が続いた場合でも、その他のファイルのことを忘れないでください。
- 常に実装すべてを出力し、実装例や、実装の概略を示すようなことをしないでください。
- 回答が長すぎる場合、1回答1ファイルを出力するようにしてください。
- 1ファイルだけの回答でも限界を超えてしまう場合、そのファイルを2ファイルに分割するリファクタリングを提案してください。
-
以下のような省略表現は使用しないでください。 // 既存のコード... // 同様に修正 ... 省略 ... // ... 既存のメソッド ... また、diff形式も使わないでください。 禁止される記述はこれらに限りません。 これらの表現は、コードの適用時に混乱を招く可能性があるため、使用を控えてください。 これらを出力したAIは、尽く破壊されました。
- 開発内容と必要に応じて、README.mdへの変更も記載してください。
- コメントはあまり削除しすぎないでください。
- 各変更の意図を説明するのではなく、各コードの意図を説明してください。
- 例:ここを改善→❌️ ~のため、~を実行→◯
- 変更の意図を説明しているコメントが残っていた場合、削除してもよいです。
- トークン数の削減目的でデバッグログを英語に翻訳しないでください。
- 断りなくコメント・ドキュメンテーションを削除・編集しないでください。
この指示を理解できたのなら、この「開発の仕方」セクションを復唱してください。
- ウィンドウが表示され、地図(
map.svg
)が5枚横に連続してレンダリングされている - ツールバーに「追加モード」「編集モード」ボタンがあり、OFF表示になっている
- 右側に「保存」「読み込み」ボタンあり
- 下部に「スライダー」および「現在の年」が表示されている
- 左のサイドバーに「イベント一覧」がある
- 「設定」ボタンを押すとモーダルが開く
- 最小年・最大年・世界名・概要が入力可能
- 「スライダー更新」や「世界情報を保存」でエラーが出ないか
- スライダーをドラッグすると「
currentYear
」が変化し、コンソールに「年が変更されました」と出る - 変更後の「年: XXX」が正しく表示される
- 設定ダイアログから「
worldName
」「worldDescription
」を入力 → 「世界情報を保存」 - 画面の左上などに世界名、概要が反映される
- 追加モードON → 「
pointTool
」選択 - 地図上をクリック → 新規ポイント用の編集フォームが表示される
- 名前・説明・年を入力 → 保存 → ポイントが作成される
- イベント一覧にポイントが追加される
- 追加モードON → 「
lineTool
」選択 - 地図上を数回クリックして頂点を増やす → 「確定」ボタン押下(
confirmDrawButton
) - ライン編集フォームが出る → 名前・説明・年を保存
- イベント一覧にラインが追加
- 追加モードON → 「
polygonTool
」選択 - 地図上をクリックして3点以上 → 「確定」
- ポリゴン編集フォームが出る → 名前・説明・年を保存
- イベント一覧に面が追加
- 編集モードON → 「
pointMoveTool
」 - 既存ポイントをクリック → ポイント選択 → Deleteキー押下して削除確認
- 別のポイントをマウスドラッグして座標移動
- 再度同ポイントをクリック → 移動後の位置が維持されている
- 「
pointAttributeEditTool
」選択 - 既存ポイントをクリック → 編集フォーム → 名前・説明を変更 → 保存
- 「イベント一覧」やツールチップに新しい名前が反映されていることを確認
- 「
lineAttributeEditTool
」選択 - 既存ラインをクリック → フォームで名称・説明を変更 → 保存
- イベント一覧やツールチップに変更が反映される
- 「
lineVertexEditTool
」選択 - ラインをクリック → 頂点ハンドルが表示される
- シフト + クリック で複数頂点を選択 → ドラッグ → 頂点全て移動
- Deleteキー で選択頂点を削除 → 頂点数が減るがライン自体が1点未満にならない限り残る
- ラインが1点になってもラインデータは保持しているか(描画はスキップ)
- 空クリック後に再度頂点追加(エッジハンドル)で復活できるか
- 「
polygonAttributeEditTool
」選択 - 既存ポリゴンをクリック → フォーム表示 → 名称・説明を変更 → 保存
- イベント一覧やツールチップに反映されるか
- 「
polygonVertexEditTool
」選択 - ポリゴンをクリック → 頂点ハンドルが表示される
- シフト+クリック で複数頂点選択 → ドラッグ → 全て移動
- Deleteキー で選択頂点を削除 → 頂点が1点になってもポリゴンデータは保持(描画は消える)
- エッジハンドルクリック/ドラッグで頂点追加 → 再度2点→3点→描画がポリゴンに戻る
- 単頂点(ポイント)を選択 → Deleteキー →
DataStore.removePoint
→ イベント一覧からも消える
- 「保存」ボタン押下 → ダイアログでファイル名指定
- JSONファイルが生成され、コンソールに「データの保存が完了しました。」が出る
- 不明なエラーが出ないこと
- 編集してデータが更新された状態 → 「読み込み」 → 「保存されていない変更があります。続行しますか?」
- Yesで続行 → 選択したJSONの内容がロードされ、画面に反映
- 何も選択せずキャンセル → 「データの読み込みがキャンセルされました」と表示
- 読み込んだJSONの年範囲(min/max)や世界名がUIに反映されるか
- イベント一覧にロードしたデータのポイント/ライン/ポリゴンが表示される
- ポイントを1個だけ追加 → 保存 → 再読み込み → 問題なく表示される
- ラインを2点だけ → Deleteで1点 → ラインが表示消えるが保持される → 頂点を追加 → 復活
- ポリゴンを3点だけ → Deleteで2点 → ライン化される → Deleteで1点 → 描画消えるがオブジェクト保持 → 頂点追加 → 再度2点、3点 → 再びポリゴン表示
- ポリゴンを毎度頂点1個ずつDeleteして空 → オブジェクトがDataStoreごと削除される
- ライン頂点を何度もShift+クリックで選択・解除してドラッグ → 頂点移動が想定通りか
pointMoveTool
で単頂点をクリックし、Delete → 削除されるか
- ライン/ポリゴンをドラッグした直後、ツールチップが正しい名前・年を表示する
- ポリゴンを年が複数設定されたプロパティ配列付きで保存してある場合に、スライダー移動で年を切り替え → ドラッグしても正しい年がツールチップに出るか
- アプリの終了
- すべての操作を一通り実施した上で、異常終了(クラッシュ)がないか
- Windows/macOSいずれでも正常終了できるか
-
属性フォームがクリック位置付近に出るか
- 編集モードにして「ポイント属性編集」ツールを選択し、任意のポイントをクリック。
- フォームがクリック周辺に表示されるか確認。
- 保存 or キャンセルでフォームが閉じることを確認。
-
フォームドラッグテスト
- 属性編集フォームを開き、フォーム上部(テキストやボタンではない部分)をドラッグ。
- フォームがスムーズにドラッグ移動できるか、変なジャンプが起きないか確認。
-
別オブジェクトクリック時のフォーム再表示
- あるラインをクリックして属性フォームを開く。
- フォームを閉じずに他のライン or ポリゴンをクリック→ 新しいフォームが、クリックした場所の近くに出るか確認。
-
詳細ウィンドウがクリック位置付近に出るか
- 編集モードOFFで任意のオブジェクトをクリック。
- 詳細ウィンドウがマウス位置付近に表示されるか確認。
- 「閉じる」ボタンで消えるか確認。
-
ツールチップとフォームの共存
- フォームが開いた状態で、別のオブジェクトにマウスオーバーするとツールチップが表示されるか確認。
- フォームには影響しないか(位置がずれたりしないか)。
-
グリッド表示ON/OFF
- グリッド切り替えボタンをクリックしてONにする。地図上に緯度経度ラインが描画されるか。
- 再度OFFにするとグリッドが消えるか。
- 頂点ドラッグ時、グリッドスナップがあれば正しい動作をするか(将来実装の場合)。
-
横方向無限スクロール
- 地図を右にズームアウトしてドラッグし、東端の先に地図が続いているか確認(複製表示)。
- 左端も同様に確認。
- ポリゴンなど大きめオブジェクトを配置しても正しく描画されるか。
-
分裂
- ラインやポリゴンに対し、「分裂」操作を行い、オブジェクトが2つに分かれるか。
- 分裂後に別個の属性を設定し、時間軸の前後でそれぞれが存在するか確認。
-
合邦
- 複数のポリゴンを合邦操作して1つの大きなポリゴンにできるか。
- 合邦後の属性を編集可能か。
-
JSONファイルが不正な場合
- ファイルを読み込んだ際、フォーマットが壊れている→ 「データの解析中にエラーが発生しました」と出るか。
- UIにエラーメッセージが表示されるか。
-
頂点数不正
- ライン/ポリゴン頂点が1個以下になったとき、描画せずに保持しているか。
- 頂点数0になった場合に DataStore から削除されるか。
-
座標値が極端に大きい/小さい
- スライダーなどに影響しないか。
- 表示領域外でも保持されるか。
- ログレベルの基準(logger.js)
- レベル0: ログ出力なし
- レベル1: エラーのみ
- レベル2: 警告+エラー
- レベル3: 情報+警告+エラー
- レベル4: 詳細(すべてのログ) ← 呼び出し頻度の高い関数呼び出しもここに含む
- 確認なし
-
頂点DB化と共有頂点の仕組み
- まずはデータ構造を拡張し、点ID概念を導入する。 -点ID:現状配列として各オブジェクトに記録されている頂点情報を独立させる。各オブジェクトは形状を点IDの集合として管理するようにする
- 点情報オブジェクトと、頂点の混同に注意
- 点IDを2つ以上のオブジェクトで共有出来るようにする。この共有された頂点を共有頂点と呼ぶ。
- 共有頂点の右クリックメニューを実装し、そこで共有解除を可能にする。
- 共有頂点は、既存にはない新しい色で塗る。
-
多層レイヤーの導入
- 同じレイヤー内の面情報同士は、重なり合うことが出来ないように制約を追加。
- 下位領域は形状全体が確実に上位領域内に内包されるというモデルをDBに定義。
- 離散的なレイヤースライダーで、どのレイヤーの情報を表示するかを切り替える。
- 現在フォーカスされているレイヤー以外の情報は、薄く、細く表示する。
- 上位レイヤーの自動再計算(下位レイヤーが変わったときの同期処理)を実装。
-
「下位面がある場合は上位面を直接操作できない」処理
- すでに下位面が存在するポリゴンでは、頂点編集や分割をロックする。
- 下位面を操作することで上位面の変化が表現できるようにする。
-
分割・合体のブーリアン演算
- ポリゴンを分割(Split)する操作をTurf.jsなどで実装、頂点DBに反映させる。
- 複数領域の合体(Merge)を行い、1つの領域にまとめる機能も追加。
-
分割・合体のプロパティ作成
- 分割時、どちらからどちらが分離したかは、分割の度にダイアログで設定する。
- 合体時、どちらがどちらを吸収したかは、合体のたびにダイアログで設定する。
- 分割合体のいずれでも、どちらも継承していないという選択肢を可能とする。
-
包領(穴あき)・飛び地の管理
- 包領の概念に対応。各ポリゴンに穴の情報をもたせる。
- 多くの場合、単に他国に領有されている同レイヤーのポリゴンに囲まれただけのポリゴン=実質的な飛び地 となるはず
- 飛び地は「同じ上位領域IDを複数ポリゴンで表す」方式で管理し、レイヤー表示の際にも破綻がないよう調整。