# 台北市房價地圖

整合進 [土地開發利潤評估計算器](../index.html) 的市場視覺化模組，四種模式呈現。

## 資料來源

| 資料 | 來源 | 規模 |
|---|---|---|
| 北市捷運站 | [repeat/northern-taiwan-metro-stations](https://github.com/repeat/northern-taiwan-metro-stations)（北市行政區內篩出）| 87 站 |
| 行政區邊界 | [xashiex/taiwan-district-boundary-to-geojson](https://github.com/xashiex/taiwan-district-boundary-to-geojson)（國土資訊圖資中心原檔轉 GeoJSON）| 12 區 |
| 預售屋實價 | 內政部不動產交易實價查詢服務 — 2025 全年 4 季 ZIP | ~3,500 筆 → 聚合 ~215 建案 |
| 代表案手 curate | 591、住展、PLEX、5168 比價王 | 26 個 |

## 四模式說明

| 模式 | 用途 | 限制 |
|---|---|---|
| **點位** | 看 26 個 curated 代表案位置與單價 | — |
| **熱度** | 高斯模糊熱度圖（Leaflet.heat）| 26 點偏少 |
| **行政區** | 12 區面填色（choropleth）| 樣本少的區用區平均 |
| **捷運環帶** | 每站 200/400/800m 同心圓，依該環內預售屋中位單價著色 | Geocoding 限制：部分案使用行政區中心 fallback |

## ETL 流程（Python script）

```
etl_build_cases.py     主流程：解析 LVR ZIP → 聚合建案 → Nominatim geocode → spatial join 到捷運站
etl_fast_fallback.py   失敗地址用「街道級 + 行政區中心」補強
```

執行：
```bash
cd web/market-map
python3 etl_build_cases.py
python3 etl_fast_fallback.py
python3 etl_build_cases.py    # 重跑用新 cache
```

`.geocode_cache.json` 為 OSM Nominatim 查詢 cache，避免重複呼叫 API。

## 資料密度（2026-05-18 跑）

214 個 2025 預售屋建案 × 87 北市捷運站，800m 內 spatial join 結果：

| 案數 | 站數 |
|---:|---:|
| 10 案（上限）| 9（雙連/民權西路/中山國小/南京三民/中山/台北車站/大橋頭等核心區）|
| 7-9 案 | 21 |
| 4-6 案 | 18 |
| 1-3 案 | 27 |
| 0 案 | 12（文湖線東段內湖/木柵山區、北投山區、象山）|

熱點：中山/大同/中正核心區，新建案集中明顯。
冷點：文湖線東段、北投山區 — 不是 ETL 漏抓，是該區 2025 推案本身就少。

## 後續可擴充

- [ ] 加入「買賣」資料（a_lvr_land_a），過濾「建築完成年月 ≤ 5 年」= 新成屋，可大幅補強零案站
- [ ] 把代表案 26 個（cases.json）與 ETL 自動產出（cases-full.json）做雙層 view 切換
- [ ] 加捷運線 polyline layer
- [ ] sensitivity heatmap：把計算器試算結果疊上去看「實際售價 vs 試算利潤率」

## 用法

- IDE 預覽：直接開 `index.html`（Cursor / VSCode Open Preview）
- 本機 server：`cd web/market-map && python3 -m http.server 8000` → http://localhost:8000

點地圖點上的「→ 丟進計算器試算」會帶單價回計算器頁面。

## 資料結構（`cases.json`）

```json
{
  "_meta": {
    "updated": "YYYY-MM-DD",
    "tiers": [ /* 色階定義 */ ]
  },
  "cases": [
    {
      "id": "區-案名-slug",
      "name": "建案名",
      "district": "行政區（中文）",
      "type": "危老 / 都更 / 預售 / 新成屋 / 中古對照 / 區平均",
      "lat": 25.xxxx,
      "lng": 121.xxxx,
      "priceLow": 100,
      "priceHigh": 120,
      "nearestMrt": "捷運站",
      "year": 2024,
      "note": "簡短說明",
      "sources": ["URL1", "URL2"]
    }
  ]
}
```

## 加新案的 SOP

1. **查實價登錄** — 591實價登錄、住展、PLEX、5168比價王
2. **記下單價區間**（開價 vs 實價成交均，標 priceLow/priceHigh）
3. **找座標** — 用 Google Maps 搜建案地址，從 URL 取 `!3d!4d` 後的數字當座標
4. **附 source URL** — 至少 1 個來源連結
5. **加進 `cases.json`** 的 `cases` 陣列

## 已知限制

1. **座標為近似值** — 大多取「最近捷運站」+ 街廓微調；正式 portfolio 用建議逐案核對 Google Maps
2. **單價以「萬/坪（建坪）」**為單位，含公設；不同案公設比落差大（30-35%）會影響每坪實際使用面積
3. **2024-2025 推案** — 房市資訊半衰期短，每 6 個月應更新一次
4. **未涵蓋商辦** — 純住宅/混合住宅；商辦案另列
5. **「區平均」案標籤** 為大安/信義/士林 — 因該區案件分散難用單案代表

## 資料來源（依使用次數排序）

| 來源 | 用途 | 連結 |
|---|---|---|
| 591實價登錄 | 個案資訊 + 實價成交 | https://newhouse.591.com.tw/ |
| 住展（myhousing）| 個案規劃、戶數、樓層 | https://build.myhousing.com.tw/ |
| PLEX | 建案基本資料、戶型 | https://www.plex.com.tw/ |
| 5168 比價王 | 實價登錄門牌級 | https://price.houseprice.tw/ |
| 內政部實價登錄 | 官方原始資料 | https://lvr.land.moi.gov.tw/ |
| 地產天下（自由電子報）| 區域脈絡、推案新聞 | https://estate.ltn.com.tw/ |
| Nownews 地產焦點 | 推案動態 | https://www.nownews.com/ |
| 經濟日報房市 | 開價對比、區平均 | https://money.udn.com/ |
| 商業周刊 / 都更全都通 | 重大案例分析 | https://urbanrenewal.wealth.com.tw/ |

## 設計決策（給未來自己/閱讀者）

- **不接 API**：實價登錄有開放 API，但接 API + ETL 增加維護成本，且實價登錄資料 6 週後才公開。手 curate 反而更靈活也更能對焦「代表案」。
- **不用 GeoJSON**：26 點規模用 JSON + 程式生 marker 就夠，GeoJSON overkill。後續若加 polygon（行政區邊界、捷運線）再轉。
- **無框架**：Leaflet + 原生 JS。與計算器同思路，盡量壓低 portfolio 公開的依賴與部署成本。

## 後續可擴充

- [ ] 加捷運線 layer（淡水信義、文湖、松山新店、板南、中和新蘆、環狀）
- [ ] 加行政區邊界 polygon（從 [moi 政府資料開放平台](https://data.gov.tw/) 拿）
- [ ] 改 marker 大小反映「總銷」（圓圈面積 ∝ 總銷億）
- [ ] 加「時間軸」slider（依完工/推案年份篩選）
- [ ] 接 1990–2025 歷史價格資料做動態演進
- [ ] 加「我的計算器試算」結果為一個 layer 與市場價對照
