Skip to content

坐标转换

三维可视化,玩的就是坐标转换和矩阵变换,熟悉坐标系非常重要。three-tile 中包含地理坐标系、世界坐标系、模型坐标系、屏幕坐标系等。上节调整摄像机位置就是用到了经纬度到世界坐标系的转换。

拿到一个坐标,必须搞清楚它是基于哪个坐标系的,比如拿到经纬度,我们知道它是以地球中心为原点的。

1. 坐标系介绍

  • 地理坐标系

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

  • 世界坐标系

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

  • 模型坐标系

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

  • 屏幕坐标系

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

  • three-tile 地图模型坐标

    右手坐标系默认情况 y 轴是指向上的,可以看做指向天顶,z 轴指向右,也就是东。为符合人类习惯,three-tile 的模型坐标系定义 x 轴指向东,y 轴指向北,z 轴指向天顶,所以将地图模型加入场景时,可以看到一行代码:

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

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

2. 坐标转换

threejs 提供了世界坐标、模型坐标、地理坐标之间的转换方法,three-tile 增加了一些方法用于地理坐标与这些坐标之间的转换。

名称参数返回功能
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. 坐标转换示例

一个在地图上标注位置的示例:

loading

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

TIP

CSS2DRenderer 是通过通过添加 DOM 标签到场景中实现的,使用比较简单,但如果添加的标签太多会影响速度,更好效果可以使用 sprite 或 canvas 等方式。只要理解了坐标转换,实现方式都一样。


Released under the MIT License.