Three.js 自建 3D 校园地图 (Self-Built 3D Campus Map with Three.js)
一句话:不依赖任何 GIS 框架,用「OSM/高德数据 + Three.js 挤出」纯手搓校园 3D 地图。数据与渲染分离,任何"数据可视化 3D"都是同一套路。
核心认知:地图 API 从不给你 3D,只给坐标
地图类 API(高德/OSM/百度)返回的本质是带坐标的表格:
- 楼 = 一圈经纬度点(墙脚轮廓)+ 属性(名字、层数)
- 路 = 一串中心线点 + 等级(primary/service/footway...)
- POI = 单个经纬度点 + 名字
3D 是自己算出来的:2D 轮廓 × 高度 = 3D 体块。楼高 = 层数标签 × 3.2m(缺失则按类型猜)。Three.js 的 ExtrudeGeometry 就是"压饼干":平面形状往上拉。
数据源对比(2026 实测,宁波高校场景)
| 来源 | 轮廓 | 名字 | 楼层 | 要 key | 备注 |
|---|---|---|---|---|---|
| OSM | ✓ 全 | 25/88 栋 | 44/88 栋 | ✗ 免费 | 国内校园覆盖稀,欧洲城市极好 |
| 高德 REST | ✗ 无 | POI 点全 | ✗ | ✓ 免费 | 只有"点",无楼块轮廓 |
| 高德 JS API | ✓(自渲染) | ✓ | ✓ | ✓ | 数据取不出来,只给画布 |
| 天地图 | 精度差 | ✓ | ✗ | ✓ | 不推荐校园场景 |
关键结论:
- OSM + 高德 REST 互补合并 = 钱湖校区 88 栋楼全形 + 29 栋真名
- 高德 JS API 楼块数据无法导出,想要数据只能:手工描卫星图 / CustomLayer 混合渲染(丑,不推荐)
- 校内步行导航数据:所有家都没有,只能自建路径网
管线(Pipeline)
Overpass API (OSM) 高德 REST API
│ way[building] │ place/text (POI)
▼ ▼
convert_overpass.py enrich_campus.py
经纬度→米(等距圆柱投影) GCJ02→WGS84 反偏移
按类型赋默认高度 点落在哪栋楼轮廓内→名字归谁
▼ ▼
campus.json (米制 GeoJSON)
▼
CampusCleanMap.vue (Three.js)
Shape→Extrude / 路→ribbon面 / CSS2D标签关键代码要点
经纬度转米(局部等距圆柱投影,校园尺度误差可忽略):
x = (lon - CENTER_LON) * 111320 * cos(radians(CENTER_LAT)) y = (lat - CENTER_LAT) * 110574- GCJ02→WGS84 反偏移:标准近似逆算法,精度 1-2m。实测高德与 OSM 在该校区整体偏差仅 4m(用同名楼校准:POI 点换算后与 OSM 同名楼质心做中位数差)。
- POI 落楼:点在多边形内(point-in-polygon)直接配;45m 内配最近无名楼标"位置近似";校外丢弃。
- 路变面:中心线 + 等级宽度(primary 9m / footway 2.2m)→ 左右偏移 → ribbon 面。比画线真实得多。
- Three.js 侧:ShapeGeometry(底)+ ExtrudeGeometry(楼)+ CSS2DRenderer(标签)+ OrbitControls(拖拽)。One immediate render after setup 防黑屏。
踩坑记录
- Overpass API 不稳:504/500 频发,kumi.systems 镜像也 502。重试 + sleep 15s 是唯一解。查询越简单越容易过。
- OSM 校门节点缺失:两个校区 barrier/entrance 节点数为 0,没人标。需从「边界多边形 ∩ 道路延伸线」推断。
- 地图 API 都不吐楼块数据:高德 JS API 的 3D 楼块是内部渲染,CustomLayer 只是让你往它的画布里挂自己的 Three.js 场景,不给数据。混合渲染视觉割裂,不如卫星图手描。
- 三层楼高全是标签:hM 属性=米,building:levels×3.2,无标签按 btype 默认值(dormitory 6 层等),高度一半是估算。
复用套路
任何 3D 数据可视化(园区/城市/展馆/地铁)都是三段式:
REST API 拉 JSON → 经纬度转米/投影 → Three.js 挤出渲染
会校园,就会城市。
项目
- 代码:
Desktop/zwu-3dmap/zwu-map(Vue3 + Vite + Three.js,数据管线在scripts/) - 相关:Plugins(Three.js 官方文档)、Overpass API 文档、高德开放平台
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Web