HDT CoLab · 2026 秋 · Node.js 22 · node:sqlite · canvas 向量繪圖
OSM 城市在線:多人在線 OpenStreetMap 編輯器
一個多人在線的 OpenStreetMap 編輯器,它編輯的是**自己伺服器上的地圖鏡像**。道路、建築、用地、水系與關係都能在瀏覽器裡一起修改 —— 而且永遠不會寫回 OpenStreetMap。
- 207 萬節點
- 32 萬道路
- 1 萬關係
本地鏡像
編輯器不碰官方資料庫,也不需要任何人去申請 OAuth 應用。
伺服器自己持有一套抽取包。導入北京包約需一分鐘,產出單一 SQLite 檔案 —— 沒有瓦片伺服器、沒有外部服務、沒有 npm 依賴。因此改動對真實地圖毫無後果,這正是它能在課堂上使用的原因。
- 節點
- 207 萬
- 道路
- 32 萬
- 關係
- 1 萬
- 資料庫
- 478 MB
- 導入
- 60 秒
- 峰值記憶體
- 214 MB
不用瓦片畫城市
完全不用瓦片伺服器。
地圖直接由向量資料畫在 canvas 上:819 條 OSM Carto 風格的樣式規則,建築做了 2.5D 擠出,所以一條街看起來像一條街、一個街區像一個街區。空間索引用 SQLite 內建的 R*Tree,因此在筆電上平移與查詢都是即時的。
| z16 視口 | 13,411 條道路 · 79,596 個節點 |
|---|---|
| 該視口的 SQL | 523 ms |
| 傳輸量 | 8.5 MB |
| 渲染要素 | 2,817 個 + 141 個標籤 |
| 渲染耗時 | 101 ms |
| 樣式規則 | 819 條 |
一起編輯
同一個區域網內,幾個人可以同時編輯同一座城市。
每一次編輯都先在伺服器校驗再廣播,客戶端只做樂觀預覽。你選中的元素會被軟鎖 120 秒,避免兩人同時改同一條路;寫入前比對版本;一個變更集可以下載成 osmChange,也可以回滾。
- 1選擇檢視並編輯全部 OSM 標籤
- 2節點拖動節點,Shift 拖動整條路
- 3加點新建 POI,159 個預設
- 4畫線Enter 結束
- 5畫面閉合區域自動共用首尾節點
- 6分割在節點處把道路一分為二
- 7合併把端點相連的兩條路併成一條
- 8合點把兩個節點併成一個
- 9刪除可選級聯刪除
- 0矩形化把建築輪廓整理成直角
- Ctrl+F 支援按名稱、key=value 或單獨按 key 搜尋。
- 12 個圖層分類可即時開關。
- 撤銷/重做每人 100 步;整體平移一條路算作一步。
- 協作者游標、正在編輯的元素與聊天頻道都可見。
交通經營
在真實地圖之上,還可以經營一家交通公司。
車站吸附到最近的網路節點,線路沿真實路網尋路,車輛由伺服器統一模擬。人口與崗位由真實建築推算,所以在某棟樓上加一層,周圍的需求就會跟著變。
- 鐵路網
- 4,491 條 · 3.4 萬節點 · 建圖 280 ms
- 公交路網
- 91,245 條 · 52.9 萬段 · 3.6 秒
- 人口
- 1,693 萬,分佈於 3.2 萬個網格
- 崗位
- 483 萬
- 票價
- 3 元 + 0.5 元/公里
- 遊戲時鐘
- 暫停 · ×1 · ×5 · ×20
載荷
讓地圖快,其實主要是傳輸量的問題。
在可編輯縮放以下,伺服器只下發壓成緊湊幾何的線與面 —— 不帶 way id,畫得出來但點不中。重新設計這份幾何所攜帶的內容之後,低縮放的傳輸量少了約一半。
改前 · 改後
架構
零依賴:沒有 npm 套件,執行時也不需要網路。
儲存引擎是 Node 22 內建的 node:sqlite;WebSocket 伺服器依 RFC 6455 自行實作;瀏覽器只用 Leaflet 當幾何與互動引擎,完全不用它載瓦片。
- 瀏覽器Leaflet · OSM 資料模型 · canvas 渲染 · 819 條樣式規則 · 159 個預設 · 11 個工具
- 伺服器路由 · 帳號(scrypt)· 自研 RFC 6455 WebSocket · 幾何/標籤/引用完整性/版本/元素鎖/撤銷/變更集
- SQLitenodes · ways · way_nodes · relations · relation_members · R*Tree 索引 · changesets · changes
測試
六個測試套件合計約 370 項斷言:導入器 82 項、樣式表與預設 133 項、協議級端到端 77 項、瀏覽器 CDP 28 項、啟動健壯性 18 項、交通協議 29 項。
專案自己的筆記寫明下一步:改用二進位向量瓦片,傳輸量預計可再降約十倍。
限制
- 這是本地鏡像編輯器,不是上傳工具:改動只落在一個 SQLite 檔案裡,永遠不會進到 OpenStreetMap。
- OpenStreetMap 在中國境內的資料密度不均,而且本頁顯示的是 WGS-84 原始座標,不是 GCJ-02。
- z15 以下依設計只能看不能改;拾取與編輯從可編輯檔開始。
- 撤銷存在記憶體裡 —— 每人 100 步,伺服器重啟即清空。
- 全國包不是幾 GB:專案實測外推 25~40 GB,導入需一到兩小時。
