TOKYO SOUBA MAP 中古マンション 相場マップ
- JavaScript (vanilla)
- Leaflet
- PHP
- MariaDB / MySQL
- GIS / 地理空間データ
- シェープファイル解析
- GeoJSON
OVERVIEW
プロジェクト概要
課題
不動産の「相場」は、物件を1件ずつ見ても掴めません。 国土交通省は実際に成約した取引価格を公開していますが、 APIは市区町村と四半期を指定して取引を1件ずつ返す形で、 地域ごとの水準を並べて比べるには自分で集計するしかありませんでした。
目的
取引事例を町丁目ごとに集計し、㎡単価の中央値を面の色で比較できるツールにすること。 フレームワークを使わず vanilla JS + Leaflet で、 127,640件の取引を、地図では地域ごとの相場、一覧では条件に合う取引として 同時に扱えるところまで作り込んでいます。 データの取得・正規化・投入はPHPのバッチ、検索はDB側で完結させました。
PROCESS
制作プロセス
-
DESIGN
Figma で3ペイン(検索条件/地図/結果一覧)を設計し、そのまま実装に落とし込み。
-
DATA
国土数値情報の鉄道データから東京都内784駅、位置参照情報から町丁目6,518件(23区に限らず都内全域)の検索用マスタを生成。
-
PIPELINE
取引価格APIの取得・正規化・投入バッチをPHPで実装。テスト16件で検証。
-
OPTIMIZE
127,640件をどう描くかを実測して設計。件数ではなく地域の数で描画量が決まる形にし、ズームで粒度を切り替える。
-
DEPLOY
PHPとMySQLが必要なため、ロリポップへFTPSで配置。実取引 127,640 件を投入して公開。
GALLERY
成果物ギャラリー
RETROSPECTIVE
振り返り・工夫した点
MEASURE, DON'T GUESS
「12.7万件は重いだろう」と考えずに、まず全部測りました。 計測はブラウザに全件を載せていた初期版で、実データ投入前のデモ生成データ 137,700件(実データ127,640件より多い件数)に対して行いました。 結果は検索2〜3ms、全件ソート34msで、重かったのは描画だけでした。 推測で設計していたら、間違ったところを最適化していたはずです。 この結果があったので、検索はDBへ、地図は点ではなく面へと 役割を分ける判断ができました。
ZOOM CAPS THE COST
該当が12.7万件でも、画面に描く面の数は地域の数で頭打ちになります。 ズーム13以上は町単位(丁目をまとめた区画。23区で935面)に切り替え、 1回に返す地域は500件を上限にして、 超えたら市区町村(23面)へ粒度を落とします。 検索結果の件数と描画コストを切り離しました。 実測で464面の描画が20msです。
FIXED COLOR SCALE
面の色は都全体で固定した区切りで塗っています。 画面内の値で自動スケールすると、地図を動かすたびに同じ町の色が変わり、 相場マップとして比較できなくなります。「動かしても意味が変わらない」ことを優先しました。 区切りは実測分布から決めた7段です。等間隔だと上位3段に31町しか入らず、 地図がほぼ2色に潰れることが分かったためです。
MATCH THE MAP TO THE DATA
取引データの位置は町丁目までで番地がありません。 個人が特定されないための匿名化で、どのデータを使っても解消しません。 当初は物件ごとにピンを立てていましたが、同じ町の取引は全件が1点に重なり、 重なりを避けて散らすと「実際の所在地」に見えてしまいます。 そこで町丁目の境界そのものを塗る形に作り替えました。 境界は国勢調査の町丁目データ(23区で3,151区画)を、丁目をまたいで 935の町の形にまとめ直し、地図用に軽くして作っています(頂点80.8%削減)。 既製のライブラリを使わず、ファイル形式の解析から自分で書きました。 取引データに写真はありません。掲載しているのはライセンスを確認したイメージ写真で、 画面上のすべての画像に「イメージ」のバッジを重ねています (一覧・地図・詳細のスライド、それぞれに明示)。 間取り図も、取引データの間取りと面積から描いた模式図である旨を添えています。 扱っているのは売り出し中の物件ではなく過去の成約記録なので、 看板も「物件検索」ではなく相場マップにしました。 データが言えること以上を名乗らない、という同じ判断です。
LIVE
公開版
ログイン不要で実際に触れます。左の「まずは例から」を押すと即座に検索が走ります。 国土交通省「不動産情報ライブラリ」の実取引データ 127,640 件で動作しています (2023年4月〜2026年3月・東京23区)。 取得・正規化・投入はPHPのバッチ、検索はDB側で完結。