TileLayer 瓦片底图
类型
组件
默认用法
TileLayer 将标准 XYZ / 滑窗地图栅格瓦片(256 像素、Web Mercator 投影,
即 OpenStreetMap、高德、天地图所使用的方案)投影到 Scene 的 GeoReference
地面平面上。
url传入瓦片地址模板,支持{z}、{x}、{y}以及可选的{s}子域占位符。- 默认情况下图层跟随相机:将可见地面矩形(相机视锥投影到地面平面)按给定
zoom铺满瓦片,底图始终覆盖整个视口;平移、缩放或旋转相机时自动加载/卸载瓦片。padding外扩瓦片圈保证移动过程中地图不露底。 - 如需固定底图,可通过
points传入需要覆盖的地理角点(并设置followCamera={false});组件会一次性请求与其包围矩形相交的所有瓦片。 - 瓦片图片懒加载,到达后淡入;瓦片使用普通
MeshBasicMaterial,因此 WebGPU 与 WebGL 渲染器均可用。 - 默认开启空气透视:锚定到瓦片覆盖边缘的距离雾,加上一块与背景同色的衬底平面,使瓦片区域在倾斜视角下自然融入背景,不露出生硬的矩形边界;缩放或环绕相机时雾的锚点会自动重新拟合。不需要时可设
fog={false};背景为图片时可用groundColor指定雾与衬底的颜色。 - 用锚定到 WGS84(GPS 标准)坐标的
GeoObject在地图上放置图钉;其onReady回调向内部 Group 添加一个圆锥 mesh,卸载时自动销毁。
瓦片影像的 datum(基准面)必须与 datum 属性一致(静态模式下覆盖点亦同)。
OSM 影像以 WGS84 索引,因此使用 Scene 默认 datum 即可。
下面的每个示例都可以用 WebGPU(默认)或 WebGL 渲染器查看 —— 切换标签页进行对比。
- WebGPU
- WebGL
import * as THREE from 'three'
import { Scene, TileLayer, GeoObject } from 'react-three-lite'
import type { GeoPoint, SceneComponents } from 'react-three-lite'
// WGS84 (GPS standard) point near Suzhou; used as both the local origin and the pin anchor.
const PIN: GeoPoint = { lng: 120.60682, lat: 31.330898 }
const ORIGIN = PIN
// OpenStreetMap standard raster tiles are indexed in WGS84 coordinates.
const TILE_URL = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
const TILE_ZOOM = 15
// GeoObject creates an internal Group and disposes its meshes on unmount.
const decoratePin = (anchor: THREE.Object3D) => {
const cone = new THREE.Mesh(
new THREE.ConeGeometry(40, 120, 24),
new THREE.MeshBasicMaterial({ color: 0xff3b30 })
)
// Lift the cone so its base sits on the ground.
cone.position.y = 60
anchor.add(cone)
}
function App() {
const handleCreated = (scene: THREE.Scene, components: SceneComponents) => {
const { camera } = components
// A fixed south-side viewpoint keeps the raster map readable like a
// conventional map; looking north from due south keeps it north-up.
scene.setPosition(camera, { x: 0, y: 600, z: 850 })
camera.lookAt(0, 0, 0)
}
return (
<Scene
origin={ORIGIN}
onCreated={handleCreated}
bgColor="rgb(40, 42, 54)"
style={{ marginTop: '10px', width: '100%', height: '300px' }}
>
<TileLayer url={TILE_URL} zoom={TILE_ZOOM} datum="WGS84" />
<GeoObject coordinate={PIN} datum="WGS84" onReady={decoratePin} />
</Scene>
)
}
import * as THREE from 'three'
import { Scene, TileLayer, GeoObject } from 'react-three-lite'
import type { GeoPoint, SceneComponents } from 'react-three-lite'
// WGS84 (GPS standard) point near Suzhou; used as both the local origin and the pin anchor.
const PIN: GeoPoint = { lng: 120.60682, lat: 31.330898 }
const ORIGIN = PIN
// OpenStreetMap standard raster tiles are indexed in WGS84 coordinates.
const TILE_URL = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
const TILE_ZOOM = 15
// GeoObject creates an internal Group and disposes its meshes on unmount.
const decoratePin = (anchor: THREE.Object3D) => {
const cone = new THREE.Mesh(
new THREE.ConeGeometry(40, 120, 24),
new THREE.MeshBasicMaterial({ color: 0xff3b30 })
)
// Lift the cone so its base sits on the ground.
cone.position.y = 60
anchor.add(cone)
}
function App() {
const handleCreated = (scene: THREE.Scene, components: SceneComponents) => {
const { camera } = components
// A fixed south-side viewpoint keeps the raster map readable like a
// conventional map; looking north from due south keeps it north-up.
scene.setPosition(camera, { x: 0, y: 600, z: 850 })
camera.lookAt(0, 0, 0)
}
return (
<Scene
rendererType="webgl"
origin={ORIGIN}
gridHelper={false}
onCreated={handleCreated}
bgColor="rgb(40, 42, 54)"
style={{ marginTop: '10px', width: '100%', height: '300px' }}
>
<TileLayer url={TILE_URL} zoom={TILE_ZOOM} datum="WGS84" />
<GeoObject coordinate={PIN} datum="WGS84" onReady={decoratePin} />
</Scene>
)
}