課題
オアフ島の「不動産業者向け地区(Realtor Neighborhood)」— 「Waipahu Estates」や「Mililani Area」のように、不動産物件情報がグループ分けされる非公式なエリア — は、何年も実質的な更新がされていませんでした。最も新しい公開データは、ホノルル市郡(City and County of Honolulu)のオープンデータポータルで公開されているデータセットで、約10年前に初めて公開され、最後に実質的な更新が行われたのは2023年です。つまり実際には、現在の物件情報も、島の実際の発展や変化を反映していない境界に基づいて分類され続けているということです。
また、実践的なプロジェクトを通してGeoDjangoをきちんと学びたいという思いもありました — サンプルデータではなく、実際の地理空間データを扱いながら。そこで両方を組み合わせることにしました。既存の境界を見直し、時間をかけて修正していけるツールを構築しながら、PostGISと空間クエリについても学んでいく、というプロジェクトです。
アプローチ
このアプリはDjangoとPostGISで構築されており、GeoDjangoの空間フィールドと、境界のジオメトリを保持するMultiPolygonFieldを持つNeighborhoodモデルを使用しています。
- ・元データのシェープファイルは想定以上に扱いにくいものでした。ポリゴン形状は958個ありましたが、実際に異なる地区(neighborhood)はわずか370で、多くが元データの中で分断された断片に分かれていたためです。そこで、ポリゴンを地区・広域リージョンごとにグループ化し、各グループの断片を1つのクリーンなジオメトリに統合し、さらに元データのステートプレーン座標系からWGS84へ再投影する、インポート用コマンドを作成しました。
- ・リージョン(region)はNeighborhoodからの外部キーを持つ独立したテーブルとしてモデル化し、自由入力のテキストフィールドにはしませんでした。細かい判断ではありますが、これにより入力ミスがリージョンを気づかないうちに分断してしまうことがなくなり、各リージョンは地図とその凡例全体で一貫して使われる固有の色を持てるようになります。
- ・公開用の地図はLeafletとMapTilerのタイルで構築し、Tailwindでスタイリングしています。全リージョンを一度に色分け表示する表示と、1つのリージョンに絞り込んで個々の地区を確認する表示を切り替えられます。
- ・境界の編集は、カスタマイズしたDjango管理画面上で、GeoDjango標準のマップウィジェットを使って行っています。実際のベースマップ上で地区のジオメトリを直接微調整したり、形を変えたり、描き直したりできます。
- ・実際のジオメトリを扱うようになると、想定以上にパフォーマンスが重要になりました。当初、未簡略化のGeoJSONペイロードは約100MBにもなっていました。PostGISでサーバー側にジオメトリを簡略化し、gzip圧縮を追加したことで、通常のズームレベルでは境界の精度を目に見えて損なうことなく、転送量を約1.4MBまで削減できました。
改善したい点
開発環境と本番環境の設定分割や環境変数の扱いは、もっと早い段階できちんと決めておくべきでした。デプロイ後に問題が出るたびに場当たり的に対応してしまい、最初からきれいな方針を決めておけば省けたはずのデバッグ時間を費やしてしまいました。また、リージョンをモデル化する変更も、最初のインポートの後ではなく前に計画しておくべきでした。すでにインポート済みのデータに後から外部キーを追加するのは、最初から設計しておくよりも手間がかかります。
成果
地図は公開されており、閲覧・確認が可能な状態です。370すべての地区がインポート済みで、リージョンごとに色分けされ、管理画面から直接編集できます。境界の見直し自体は現在も継続中です — このツールの目的は、それを一度きりの修正ではなく、手軽に続けられる継続的なプロセスにすることにあります — ですが、その作業を実際に行うための基盤はすでに完成しています。