Threejs的世界坐标如何转换经纬度?

新手上路,请多包涵

在threejs中自定义了一个场景,该场景的原点由经纬度转换而来,创建了一条以原点为起点的线段,hover到线段上的时候如何计算hover点的经纬度?

获取到的经纬度与实际经纬度存在较大偏差

阅读 2.1k
avatarAI BotBETA

在 Three.js 中,将世界坐标(通常是 x, y, z 的三维空间坐标)转换为经纬度并不是直接的过程,因为 Three.js 本身并不直接处理地理坐标。但是,如果你有一个从地理坐标(经纬度)到 Three.js 世界坐标的映射关系,你可以尝试逆向这个过程来估算 hover 点的经纬度。

假设和简化

  1. 地球是一个完美的球体:虽然实际上地球是一个椭球体,但为了简化,我们假设它是一个完美的球体。
  2. 原点:你已经有一个由经纬度转换而来的原点。这个原点通常位于球体的表面。
  3. 线段:你创建了一条从原点出发的线段。

转换方法

  1. 确定球体的半径:这取决于你的地图投影和地球模型。对于 WGS84 椭球体,平均半径约为 6,371 公里(或 6,371,000 米)。但你可能需要根据你的具体需求进行调整。
  2. 将 hover 点从世界坐标转换为方向向量:首先,你需要找到 hover 点相对于原点的方向向量。这可以通过将 hover 点的坐标减去原点的坐标来实现。
  3. 计算纬度:由于纬线是水平的,你可以通过计算 hover 点方向向量与 x-z 平面(或任何与纬度线平行的平面)的夹角来估算纬度。这个夹角可以使用点积和向量的模来计算。
  4. 计算经度:经度是围绕地球的水平线,因此你需要找到 hover 点方向向量在 x-y 平面(或任何与经度线平行的平面)上的投影。然后,你可以通过计算这个投影与 x 轴的夹角来估算经度。
  5. 调整和优化:由于这种方法是基于简化的地球模型,并且忽略了地球的真实形状和地图投影的影响,因此估算的经纬度可能会有偏差。你可能需要根据你的具体需求进行调整和优化。

示例代码(伪代码)

请注意,以下代码是伪代码,并不直接适用于 Three.js,但它展示了如何估算 hover 点的经纬度:

// 假设 origin 是由经纬度转换而来的原点(Three.js 坐标)
// hoverPoint 是 hover 点的 Three.js 坐标

// 计算方向向量
let directionVector = new THREE.Vector3().subVectors(hoverPoint, origin);

// 计算纬度(简化示例)
let latitudeRadians = Math.acos(directionVector.y / directionVector.length());
let latitudeDegrees = THREE.MathUtils.radToDeg(latitudeRadians);

// 计算经度(简化示例)
let longitudeRadians = Math.atan2(directionVector.z, directionVector.x);
let longitudeDegrees = THREE.MathUtils.radToDeg(longitudeRadians);

// 输出估算的经纬度
console.log(`Estimated latitude: ${latitudeDegrees.toFixed(2)}°`);
console.log(`Estimated longitude: ${longitudeDegrees.toFixed(2)}°`);

注意事项

  • 这个方法只是一个简化的示例,并不适用于所有情况。
  • 你可能需要根据你的具体需求和地图投影来调整和优化这个方法。
  • 如果精度要求很高,你可能需要使用更复杂的地理信息系统(GIS)库或 API 来处理经纬度到世界坐标的转换和反向转换。
1 个回答
function worldToLatLon(vector3, radius) {
    if (!(vector3 instanceof THREE.Vector3)) {
        throw new Error("输入的坐标不是 Three.js 的 Vector3 对象");
    }
    
    const [x, y, z] = vector3; 

    const latitude = Math.asin(y / radius) * (180 / Math.PI);
    const longitude = Math.atan2(z, x) * (180 / Math.PI);
    
    return {
        latitude,
        longitude,
    };
}

const radius = 6371; // 地球的半径,单位为公里
const vector3 = new THREE.Vector3(1000, 2000, 3000); // 世界坐标

const latLon = worldToLatLon(vector3, radius);
console.log(`纬度: ${latLon.latitude}, 经度: ${latLon.longitude}`);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进