美文网首页程序员
经纬度坐标系转threejs空间直角坐标系

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

作者: Erric_Zhang | 来源:发表于2023-01-29 18:14 被阅读0次

    在利用threejs做一些例如城市模型等3D开发时,会发现threejs无法直接支持经纬度坐标,例如城市模型的某个建筑,它在空间直角坐标系中的位置,可以用一个x,y,z表示,但是没法和实际世界中地球坐标系的经度、维度相关联,二者之间有一套相互映射的算法,这样当有需求需要在某个经纬度位置添加某个东西时,也可以正确的显示在三维模型中。

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

    相关文章

      网友评论

        本文标题:经纬度坐标系转threejs空间直角坐标系

        本文链接:https://www.haomeiwen.com/subject/ceephdtx.html