如何在 WebGL Globe 中获取屏幕中心点的经纬度值?

How to get lat long values of point at center of screen in WebGL Globe?

Google's WebGL Globe 允许在特定经纬度处放置标记。但是我们如何才能获得当前位于屏幕前面或屏幕中心的点的经纬度值。可能正在使用相机位置或旋转值。

我们可以使用以下代码从经纬度值查找地球上的位置:

var phi = (90 - lat) * Math.PI / 180;
var theta = (180 - lng) * Math.PI / 180;
point.position.x = 200 * Math.sin(phi) * Math.cos(theta);
point.position.y = 200 * Math.cos(phi);
point.position.z = 200 * Math.sin(phi) * Math.sin(theta);

据我所知,没有直接的方法可以得到它。我看到两个选项:

  • 您可以修改 globe.js 以“导出”rotation 对象:在 globe.js 的末尾添加以下内容,就在 [=12= 之后]:

    this.rotation = rotation;
    
  • 或者,如果你不想修改globe.js,你可以使用scene属性,在里面找到相机,并使用它的位置找到纬度和经度。直接使用场景可能有更简单的方法,不是很确定。

请注意,globe 使用 three.js,因此您可以在任何搜索中使用它。

另一种方法是使用THREE.Spherical():

phi.innerHTML = "0";
theta.innerHTML = "0";

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var sphere = new THREE.Mesh(new THREE.SphereGeometry(2.5, 16, 12), new THREE.MeshBasicMaterial({color: "maroon", wireframe: true}));
scene.add(sphere);

renderer.domElement.addEventListener("mousedown", onMouseDown, false);

var center = new THREE.Vector2(); // default is [0.0], the center of the screen
var raycaster = new THREE.Raycaster();
var point = new THREE.Vector3();
var spherical = new THREE.Spherical();
var intersect;

function onMouseDown(event) {
  raycaster.setFromCamera(center, camera);
  intersect = raycaster.intersectObject(sphere);
  if (intersect.length === 0) return;
  
  sphere.worldToLocal(point.copy(intersect[0].point));
  spherical.setFromVector3(point);
  phi.innerHTML = THREE. Math.radToDeg(Math.PI * .5 - spherical.phi);
  theta.innerHTML = THREE.Math.radToDeg(spherical.theta);
  
  let marker = new THREE.Mesh(new THREE.BoxGeometry(.125, .125, .125), new THREE.MeshBasicMaterial({
    color: Math.random() * 0xffffff,
    wireframe: true
  }));
  marker.position.copy(intersect[0].point);
  scene.add(marker);

}


render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
#data{
  font-family: Monotype;
  color: white;
  position: absolute;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="data">
phi: <span id="phi"></span>&deg;<br>
theta: <span id="theta"></span>&deg;
</div>