Skip to content

坐标转换

三维开发的核心就是坐标转换和矩阵变换,熟悉坐标系非常重要。

three-tile 中包含地理坐标系、世界坐标系、模型坐标系、屏幕坐标系等。上节调整摄像机位置就是用到了经纬度到世界坐标系的转换。

TIP

与 cesium 等使用球心坐标系不同,three-tile 内部采用 EPSG:3857 地图坐标系,坐标轴为东北上。

1. 坐标系介绍

  • 地理坐标系

    地理坐标一般指经纬度海拔高度,或投影坐标等。经纬度海拔作为坐标更加直观,但三维场景中并不能直接使用它,需要将它转换为三维世界坐标或模型坐标才能使用。

  • 世界坐标系

    世界坐标是 WebGL(OpenGL)中的概念,一般采用右手坐标系,原点为世界中心,这个坐标是全局唯一的,也叫全局坐标系。threejs 的世界坐标 X 指向右,y 轴指向上,z 轴指向屏幕外。

  • 模型坐标系

    模型坐标系也叫局地坐标系,一般是指相对于模型中心的坐标。

  • 屏幕坐标系

    屏幕坐标系是二维坐标,这个容易理解,但在三维场景中,坐标原点在屏幕左下角,y 轴向上。

  • three-tile 地图模型坐标

    threejs 使用的右手坐标系,默认 y 轴是指向上的,可以看做指向天顶,x 轴指向右,也就是东,z 轴指向北。

    为符合人类习惯,three-tile 中地图坐标系定义 x 轴指向东,y 轴指向北,z 轴指向天顶。

    所以将地图模型加入场景时,可以看到一行代码:

    ts
    map.rotateX(-Math.PI / 2);

这句代码就是将地图旋转到世界坐标系的 xz 平面。

2. 坐标转换

上面的概念大概明白即可,threejs 提供了世界坐标、模型坐标、地理坐标之间的转换方法:

名称参数返回功能
geo2map(geo: Vector3)geo: 地理坐标(经纬度高度)Vector3:地图模型局地坐标地理坐标转地图模型坐标
map2geo(pos: Vector3)pos: 地图模型局地坐标Vector3:地理坐标(经度、纬度、高度)地图模型坐标转地理坐标
geo2world(geo:Vector3)geo: 地理坐标(经纬度高度)Vector3:世界坐标系坐标地理坐标转世界坐标
world2geo(world:Vector)world:世界坐标系坐标Vector3:地理坐标(经度、纬度、高度)世界坐标转地理坐标

前面移动摄像机到指定经纬度,就是使用了 geo2world 方法:

ts
// 地图中心经纬度高度(m)转为世界坐标
const centerPostion = map.geo2world(new THREE.Vector3(110, 35, 0));
// 摄像机经纬度高度(m)转为世界坐标
const cameraPosition = map.geo2world(new THREE.Vector3(116.39199596764485, 39.91047669278009, 1000 * 1000));

还有模型坐标到与世界坐标的转换、屏幕坐标与世界坐标的转换等,是 threejs 的自带方法,这里就不啰嗦了。

注意

three-tile V0.10.3 版本开始,应广大网友要求,地图坐标单位由公里改为米,以与主流 GIS 类软件保持一致。

3. 坐标转换示例

如:要向地图上指定经纬度添加物体,先用 map.geo2world 将经纬度转换为世界坐标,再将物体的 position 设置为该世界坐标即可。

下面的示例地图上添加标注:

loading

上面的代码使用 threejs 的 CSS2DRenderer 类添加标签到地图上: https://threejs.org/docs/index.html?q=css#examples/zh/renderers/CSS2DRenderer

Released under the MIT License.