After a thorough search for the most effective "three.js approach" to tackle this issue, I have decided to share it here for future reference. The following solution assumes that Y is oriented upwards:
const latLngToVector3 = (latLng, radius) => {
const phi = Math.PI * (0.5 - (latLng.lat / 180));
const theta = Math.PI * (latLng.lng / 180);
const spherical = THREE.Spherical(radius || latLng.radius || 1, phi, theta);
return new THREE.Vector3().setFromSpherical(spherical);
};
const vector3ToLatLng = (v3) => {
const spherical = new THREE.Spherical().setFromVector3(v3);
return {
lat: 180 * (0.5 - (spherical.phi / Math.PI)),
lng: 180 * (spherical.theta / Math.PI),
};
};
// convert to x,y,z with radius = 1
const v3 = latLngToVector3({ lat: -16.8985, lng: 145.7134 });
// convert back to lat/lng
const latLng = vector3ToLatLng(v3);
To understand the underlying mechanisms, take a look at the Spherical.setFromvector3 and Vector3.setFromSpherical methods.