经纬度坐标系转threejs空间直角坐标系

发布于 2024-11-12 10:55:56

首先需要和建模工程师确定好他们建模的坐标0点具体是哪个位置,以及此点对应的实际世界中的经纬度坐标。且建模工程师建模一定要和真实城市街区比例一致(当然按一定比例缩小也可以)
具体实现代码

// 这个就是和建模工程师确定的建模时的0点对应的真实世界的经纬度坐标(本文经纬度为wgs84坐标系,如果是其他坐标系,需要先转换成wgs84)
const threeMapZeroCenter  =  {
  lng: 114.2858126490011,
  lat: 30.581177854141437
}

// wgs84经纬度坐标转threejs三维坐标
function wgs84ToThreePosition(lng, lat, height) {
  // 模型世界坐标0点对应的wgs84坐标
  // TODO: 需要和模型组的确定准确坐标
  const cityModelCenterPos = {
    lng: threeMapZeroCenter.lng,
    lat: threeMapZeroCenter.lat,
    height: 0,
  }

  // 找到地图的中心对应的经纬度坐标
  const center = lngLatToMercator(cityModelCenterPos)
  const mercatorMax = 20037508.3427892

  const y = height ? height : 0
  const z = (+lng / 180.0) * mercatorMax
  let x = (Math.PI / 180.0) * +lat
  const tmp = Math.PI / 4.0 + x / 2.0
  x = (mercatorMax * Math.log(Math.tan(tmp))) / Math.PI

  // 这一步是重点:墨卡托平面坐标系很大,需要结合模型调试一个合适的比例,例如下面的0.85,是结合模型上两个实际点位调试出的大概比例,通常通过0点和另外一个点确定这比例系数需要设置多少。
  return {
    x: (center.x - x) * 0.85,
    y: y - center.y,
    z: (center.z - z) * 0.85,
  }
}

// 经纬度坐标转墨卡托
function lngLatToMercator({ lng, lat, height }) {
  var y = height ? height : 0
  var z = (lng / 180.0) * 20037508.3427892
  var x = (Math.PI / 180.0) * lat
  var tmp = Math.PI / 4.0 + x / 2.0
  x = (20037508.3427892 * Math.log(Math.tan(tmp))) / Math.PI
  return { x: x, y: y, z: z }
}
0 条评论

发布
问题