Skip to content

3. 调整地图位置和缩放

地图创建部分已讲过,地图的中心位置和缩放需要通过调整摄像机位置和姿态来实现。

loading

三维场景下,地图的位置和缩放,是通过调整摄像机的位置和姿态来实现的。设置 camera 的 position 设置观察者的坐标、设置 controls.target.position 设置地图中心坐标。

这两个坐标可以根据经纬度和海拔高度计算得到。可以在地图和场景创建完成后立即设置地图初始位置,也可以在运行时调整,还可以利用 tween 进行动画调整。

1. 设置地图初始位置

直接设置地图中心和摄像机位置

ts
// 地图中心经纬度高度(m)
const lonlat = new THREE.Vector3(116.39, 39.91, 0);
// 地图中心经纬度高度(m)转为世界坐标
const centerPosition = map.geo2world(lonlat);
// 摄像机经纬度高度(m)转为世界坐标
const cameraPosition = map.geo2world(new THREE.Vector3(lonlat.x, lonlat.y - 0.1, lonlat.z + 10000));

// 设置地图中心
viewer.controls.target.copy(centerPosition);
// 设置摄像机位置
viewer.camera.position.copy(cameraPosition);

2. 跳转到地图指定位置:

GLViewer 提供 flyTo 方法,可以跳转到指定位置。

ts
/**
 * 跳转到指定经纬度
 * @param x 经度
 * @param y 纬度
 * @param z 高度(m)
 */
window.goto = function (x, y, z) {
    const lonlat = new THREE.Vector3(x, y, z);
    console.log("goto", lonlat);
    // 地图中心经纬度高度(m)转为世界坐标
    const centerPosition = map.geo2world(lonlat);
    // 摄像机经纬度高度(m)转为世界坐标
    const cameraPosition = map.geo2world(new THREE.Vector3(lonlat.x, lonlat.y - 0.1, lonlat.z + 10000));
    // 飞行漫游到指定位置
    viewer.flyTo(centerPosition, cameraPosition);
};

viewer.flyTo 是 GLViewer 的一个方法,animate 参数为 true 时使用 Tween 动画平滑漫游,函数很简单,如果动画效果不符合你的需求,可以参照下面代码自己写一个。

ts
	/**
	 * Fly to a position
	 * @param centerPosition Map center target position
	 * @param cameraPosition Camera target position
	 * @param animate animate or not
	 */
	public flyTo(centerPosition: Vector3, cameraPosition: Vector3, animate = true) {
		this.controls.target.copy(centerPosition);
		if (animate) {
			const start = this.camera.position;
			new Tween(start)
				// fly to 10000
				.to({ y: 10000*1000, z: 0 }, 500)
				// to target
				.chain(new Tween(start).to(cameraPosition, 2000).easing(TWEEN.Easing.Quintic.Out))
				.start();
		} else {
			this.camera.position.copy(cameraPosition);
		}
	}

3. 取得和恢复地图位置状态

threejs 的控制器 OrbitControls 和 MapControls 提供了 saveState 和 reset 方法( https://threejs.org/docs/index.html?q=orb#examples/zh/controls/OrbitControls.reset ),可以用来保存地图当前状态和恢复之前的状态,即保存和恢复地图姿态视角。

技巧

地图的位置手工很难估算准确。上面示例显示了地图和摄像机当前的位置,可以先用鼠标调整好你想要的地图,然后复制地图中心坐标和摄像机坐标,再用 viewer.flyTo 方法跳转。

Released under the MIT License.