ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

map3d 道路渲染拆解:用 react-three-drei 的 Line 组件绘制城市路网的 3 个关键步骤

map3d 道路渲染拆解:用 react-three-drei 的 Line 组件绘制城市路网的 3 个关键步骤 map3d 道路渲染拆解用 react-three-drei 的 Line 组件绘制城市路网的 3 个关键步骤【免费下载链接】map3d️ Generate City 3D map with R3F. Include building and road information.项目地址: https://gitcode.com/gh_mirrors/map/map3d如果你想在浏览器里生成一张真实城市的 3D 地图map3d 是一个很值得拆解的开源项目它基于React-Three-FiberR3F构建通过 OpenStreetMap 数据自动生成带建筑物和道路信息的城市三维场景并支持一键导出 GLB 模型。本文聚焦其中最有趣的部分——城市道路渲染拆解 map3d 如何用react-three-drei的Line组件把经纬度数据一步步变成屏幕上那条条绿色的三维路网。️ 先认识 Road 组件路网的总指挥map3d 的道路渲染全部集中在 src/three/Space.tsx 的Roads组件里。它接收一个矩形区域由用户在二维地图上拖选产生然后完成三件事步骤做什么对应源码位置① 取数据请求 Overpass API获取区域内所有道路Space.tsx#L327-L343② 投影坐标经纬度 → 3D 场景本地坐标Space.tsx#L321-L325③ 绘制线条用 drei 的Line逐条渲染道路Space.tsx#L347-L365下面逐个拆解。第一步用 Overpass API 查询城市道路数据Roads组件里用useEffect监听选中的区域一旦用户框选完成就向 Overpass APIOpenStreetMap 的查询接口发出一条查询取出该矩形范围内所有带highway标签的 way道路并以out body geom拿到完整几何点序列。const query [out:json][timeout:25];(wayhighway;);out body geom;;返回的数据直接存入roads状态后续的渲染全部由 React 响应式驱动——这正是 R3F 项目的惯用思路数据进状态渲染交给声明式 JSX。 选区范围由 SelectMap.tsx 的 Leaflet 地图提供区域范围存放在 areaStore.ts 的 Zustand store 中实现了二维选区与三维场景的解耦。第二步把经纬度投影到 3D 本地平面三维场景无法直接理解经纬度map3d 用了一个很经典的技巧——局部平面投影取区域中心点作为参考基准refLat / refLng经度差乘以scale51000再乘cos(refLat)做纬度方向压缩修正最后映射为THREE.Vector3(x, 0.1, -y)。function project(lat, lng) { const x (lng - refLng) * scale * Math.cos((refLat * Math.PI) / 180); const y (lat - refLat) * scale; return new THREE.Vector2(x, y); }两个值得注意的细节y轴固定为0.1让道路整体略微抬升避免与地面建筑模型发生深度冲突z-fighting-v.y取反OpenStreetMap 的 y 轴向上而 three.js 场景的 z 轴方向与之相反取反后才能让地图方向正确地铺在场景里。这套投影公式在 Space.tsx 的Space组件中同样出现一次——建筑和道路共用同一套坐标系统保证两者严丝合缝地叠在一起。第三步用 drei 的 Line 组件逐条绘制道路数据准备就绪后渲染本身只有几行{roads.map((road, index) { const points road.geometry.map((pt) { const v project(pt.lat, pt.lon); return new THREE.Vector3(v.x, 0.1, -v.y); }); return ( Line points{points} color#33f516 lineWidth{1} userData{{ exportToGLB: true }} / ); })}Line来自 react-three-drei它是对 three.js 线条的 React 化封装points直接把投影后的Vector3数组丢进去drei 内部自动处理BufferGeometry和Line2材质你完全不用碰底层几何体lineWidth屏幕空间线宽保证道路在远景下依然清晰可见普通LineBasicMaterial的线宽在高分屏上会细到看不见color那抹标志性的荧光绿#34f516让路网在灰色建筑群中一目了然。这正是Line组件最大的价值用声明式 JSX 拿到可编程线宽的抗锯齿线条一行配置换掉几十行 three.js 样板代码。 隐藏细节userData标记让道路可被导出为 GLB注意每条Line都带了userData{{ exportToGLB: true }}。这是一个非常巧妙的设计Space.tsx 的Export函数在导出时遍历整个场景只克隆打了这个标记的对象再交给GLTFExporter打包——于是建筑物和道路会被完整导出而天空、灯光、小车等装饰元素则被自动排除。一句话总结这个模式用 userData 做导出白名单让三维场景与资产导出解耦。 快速上手本地运行如果你想亲手跑一遍这个项目依赖清单见 package.jsongit clone https://gitcode.com/gh_mirrors/map/map3d cd map3d npm install npm run dev打开后在地图上框选一个小区域 → Next Step 拉取建筑数据 → 进入 3D 场景即可看到绿色路网右下角的Export GLB按钮能把道路与建筑打包成三维模型文件。写在最后map3d 的道路渲染看似简单实际浓缩了三维地图开发的三个核心环节地理数据获取Overpass API→ 局部平面投影经纬度转场景坐标→ 声明式线条渲染drei Line。三步走下来一条完整的路网生产线就搭起来了。想继续深挖推荐顺着这份阅读路径探索道路渲染主体src/three/Space.tsx区域状态管理src/state/areaStore.ts二维选区交互src/components/map/SelectMap.tsx掌握这套取数 → 投影 → 渲染的方法论你再去做数字孪生、无人机测绘可视化、GPS 轨迹标记这类项目时会发现自己已经站在了正确的起点上。【免费下载链接】map3d️ Generate City 3D map with R3F. Include building and road information.项目地址: https://gitcode.com/gh_mirrors/map/map3d创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表