Get longitude and latitude from the Globe in WebGL

泪湿孤枕 提交于 2019-12-05 06:49:03

问题


I'm using WebGL globe from http://workshop.chromeexperiments.com/globe/. If any point of the globe is clicked, I need to get the longitude and latitude of that point. These parameters are to be passed to the Google Maps for 2D map.

How can I get the long. and lat. from the webgl globe?

Through this function I'm getting the double clicked point, and through this point I'm finding the long. and lat. But the results are not correct. It seems that the clicked point is not determined properly.

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);

        }
    }

Get the WebGL Globe here https://dl.dropbox.com/u/48682822/globe.zip You can open it directly on Mozilla, if you open it in Chrome it works with earth surface image lack because of Cross-Origin Resource Sharing policy. It needs to be put in a virtual host.


回答1:


Try to use the function in this way

    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;

        }
    }



回答2:


I used the code you share with a little correction and it works great.

The way to let it work correctly is to understand exactly what you pass to the new THREE.Vector3.

This function need three parameters (x, y, z)

z in our/your case is sculpted as 0.5 and it's ok

x and y must be a number among -1 and 1, so, to obtain this values you need to catch the click coordinates on your canvas and then, with this formula, reduce them to a value in this range (-1...0...1);

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

where p_coord_X and p_coord_Y are the coordinates of the click (referred to the left top corner of your canvas) and canvas is the canvas area where lives your webgl globe.

The problem is how to get the click X and Y coordinates in pixel, because it depends by how your canvas is placed in your HTML enviroment. For my cases the solution over proposed where not suitable cause i returned always false results; so i build a solution to get extacly the x and y coordinates of my canvas area as i clicked on it (i had for my case too to insert a scrollY page correction).

Now imagine to devide in 4 square your canvas area, a click in the NW quadrant will return for example a -0.8, -05 x and y values, a click in SE i.e. a couple of 0.6, 0.4 values.

The ray.intersectObject() function that follows uses then our click-vector-converted data to understand if our click intersects the globe, if it matches, return correctly the coordinates lat and lon.



来源:https://stackoverflow.com/questions/13294851/get-longitude-and-latitude-from-the-globe-in-webgl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!