1

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

怎么才能长。和纬度。来自 webgl 地球?

通过这个函数,我得到了双击点,通过这个点,我找到了 long。和纬度。但结果并不正确。似乎点击的点没有正确确定。

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://github.com/dataarts/webgl-globe/archive/master.zip 您可以直接在 Mozilla 上打开它,如果您在 Chrome 中打开它,它适用于由于 Cross-Origin 而缺少地球表面图像资源共享政策。它需要放在虚拟主机中。

4

2 回答 2

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;

        }
    }
于 2012-11-09T13:54:50.610 回答
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 是单击的坐标(指画布的左上角),而画布是 webgl 地球所在的画布区域。

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

现在想象将您的画布区域划分为 4 个正方形,单击 NW 象限将返回例如 -0.8、-05 x 和 y 值,单击 SE 即返回几个 0.6、0.4 值。

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

于 2013-12-11T11:13:51.107 回答