在WebGL中获取Globe的经度和纬度

时间:2012-11-08 17:54:04

标签: google-maps math astronomy webgl-globe

我正在使用来自http://workshop.chromeexperiments.com/globe/的WebGL globe。如果点击地球的任何一点,我需要获得该点的经度和纬度。这些参数将传递到Google Maps for 2D地图。

我怎样才能得到很长时间。和拉特。来自webgl globe?

通过这个功能,我得到双击点,通过这一点,我找到了很长的。和拉特。但结果不正确。似乎没有正确确定点击的点。

function onDoubleClick(event) {
        event.preventDefault();

        var vector = new THREE.Vector3(
            ( event.clientX / window.innerWidth ) * 2 - 1,
            -( event.clientY / window.innerHeight ) * 2 + 1,
            0.5
        );

        projector.unprojectVector(vector, camera);

        var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());

        var intersects = ray.intersectObject(globe3d);

        if (intersects.length > 0) {

            object = intersects[ 0 ];

            console.log(object);
            r = object.object.boundRadius;
            x = object.point.x;
            y = object.point.y;
            z = object.point.z;
            console.log(Math.sqrt(x * x + y * y + z * z));

            lat = 90 - (Math.acos(y / r)) * 180 / Math.PI;
            lon = ((270 + (Math.atan2(x, z)) * 180 / Math.PI) % 360) - 180;

            console.log(lat);
            console.log(lon);

        }
    }

在此处获取WebGL Globe https://dl.dropbox.com/u/48682822/globe.zip 您可以直接在Mozilla上打开它,如果您在Chrome中打开它,它会因为跨地域资源共享策略而缺乏地球表面图像。它需要放在虚拟主机中。

2 个答案:

答案 0 :(得分:3)

尝试以这种方式使用该功能

    function onDoubleClick(event) {
        event.preventDefault();

        var canvas = renderer.domElement;
        var vector = new THREE.Vector3( ( (event.offsetX) / canvas.width ) * 2 - 1, - ( (event.offsetY) / canvas.height) * 2 + 1,
0.5 );

        projector.unprojectVector( vector, camera );

        var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());

        var intersects = ray.intersectObject(globe3d);

        if (intersects.length > 0) {

            object = intersects[0];

            r = object.object.boundRadius;
            x = object.point.x;
            y = object.point.y;
            z = object.point.z;

            lat = 90 - (Math.acos(y / r)) * 180 / Math.PI;
            lon = ((270 + (Math.atan2(x, z)) * 180 / Math.PI) % 360) - 180;

            lat = Math.round(lat * 100000) / 100000;
            lon = Math.round(lon * 100000) / 100000;
            window.location.href = 'gmaps?lat='+lat+'&lon='+lon;

        }
    }

答案 1 :(得分:0)

我使用你所分享的代码进行了一些修正,效果很好。

让它正常工作的方法是准确理解你传递给新的THREE.Vector3的内容。

此功能需要三个参数(x,y,z)

z在我们/您的情况下被雕刻为0.5并且没有问题

x和y必须是-1和1之间的数字,因此,要获得此值,您需要捕获画布上的单击坐标,然后使用此公式将它们减少到此范围内的值(-1 ... 0 ... 1);

var vectorX = ((p_coord_X / canvas.width ) * 2 - 1);
var vectorY = -((p_coord_Y / canvas.height ) * 2 - 1);

其中p_coord_X和p_coord_Y是点击的坐标(指向画布的左上角),而canvas是生成webgl globe的画布区域。

问题是如何获取像素中的单击X和Y坐标,因为它取决于画布在HTML环境中的放置方式。 对于我的情况,解决方案提出了不合适的原因我返回总是错误的结果;所以我建立了一个解决方案,以便在我点击它时获得画布区域的x和y坐标(我的情况也是为了插入一个滚动页面校正)。

现在想象一下你的画布区域的4个方格,在NW象限中点击将返回例如-0.8,-05 x和y值,SE中的点击,即几个0.6,0.4值。

接下来的ray.intersectObject()函数使用我们的点击矢量转换数据来理解我们的点击是否与地球相交,如果匹配,则正确返回坐标lat和lon。