笛卡尔坐标转经纬度坐标(cesium源码抠出来的)

function fromCartesian(cartesian) {
  const oneOverRadii = {
    x: 1.0 / 6378137.0,
    y: 1.0 / 6378137.0,
    z: 1.0 / 6356752.3142451793
  };
  const oneOverRadiiSquared = {
    x: 1.0 / (6378137.0 * 6378137.0),
    y: 1.0 / (6378137.0 * 6378137.0),
    z: 1.0 / (6356752.3142451793 * 6356752.3142451793)
  };

  const p = scaleToGeodeticSurface(
    cartesian,
    oneOverRadii,
    oneOverRadiiSquared,
    0.1
  );

  if (!(p !== undefined && p !== null)) {
    return undefined;
  }

  let n = {
    x: p.x * oneOverRadiiSquared.x,
    y: p.y * oneOverRadiiSquared.y,
    z: p.z * oneOverRadiiSquared.z
  };
  const m1 = magnitude(n);
  n = {
    x: n.x / m1,
    y: n.y / m1,
    z: n.z / m1
  };

  const h = {
    x: cartesian.x - p.x,
    y: cartesian.y - p.y,
    z: cartesian.z - p.z
  };

  const longitude = Math.atan2(n.y, n.x);
  const latitude = Math.asin(n.z);
  const height =
    Math.sign(h.x * cartesian.x + h.y * cartesian.y + h.z * cartesian.z) *
    magnitude(h);

  let result = {};
  result.longitude = (longitude * 180.0) / Math.PI;
  result.latitude = (latitude * 180.0) / Math.PI;
  result.height = height;
  return result;
}

function scaleToGeodeticSurface(
  cartesian,
  oneOverRadii,
  oneOverRadiiSquared,
  centerToleranceSquared
) {
  const positionX = cartesian.x;
  const positionY = cartesian.y;
  const positionZ = cartesian.z;

  const oneOverRadiiX = oneOverRadii.x;
  const oneOverRadiiY = oneOverRadii.y;
  const oneOverRadiiZ = oneOverRadii.z;

  const x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX;
  const y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY;
  const z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ;

  // Compute the squared ellipsoid norm.
  const squaredNorm = x2 + y2 + z2;
  const ratio = Math.sqrt(1.0 / squaredNorm);

  // As an initial approximation, assume that the radial intersection is the projection point.
  const intersection = {
    x: cartesian.x * ratio,
    y: cartesian.y * ratio,
    z: cartesian.z * ratio
  };

  // If the position is near the center, the iteration will not converge.
  if (squaredNorm < centerToleranceSquared) {
    return !isFinite(ratio) ? undefined : intersection;
  }

  const oneOverRadiiSquaredX = oneOverRadiiSquared.x;
  const oneOverRadiiSquaredY = oneOverRadiiSquared.y;
  const oneOverRadiiSquaredZ = oneOverRadiiSquared.z;

  // Use the gradient at the intersection point in place of the true unit normal.
  // The difference in magnitude will be absorbed in the multiplier.
  const gradient = {
    x: intersection.x * oneOverRadiiSquaredX * 2.0,
    y: intersection.y * oneOverRadiiSquaredY * 2.0,
    z: intersection.z * oneOverRadiiSquaredZ * 2.0
  };

  // Compute the initial guess at the normal vector multiplier, lambda.
  let lambda =
    ((1.0 - ratio) * magnitude(cartesian)) / (0.5 * magnitude(gradient));
  let correction = 0.0;

  let func;
  let denominator;
  let xMultiplier;
  let yMultiplier;
  let zMultiplier;
  let xMultiplier2;
  let yMultiplier2;
  let zMultiplier2;
  let xMultiplier3;
  let yMultiplier3;
  let zMultiplier3;

  do {
    lambda -= correction;

    xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX);
    yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY);
    zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ);

    xMultiplier2 = xMultiplier * xMultiplier;
    yMultiplier2 = yMultiplier * yMultiplier;
    zMultiplier2 = zMultiplier * zMultiplier;

    xMultiplier3 = xMultiplier2 * xMultiplier;
    yMultiplier3 = yMultiplier2 * yMultiplier;
    zMultiplier3 = zMultiplier2 * zMultiplier;

    func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0;

    // "denominator" here refers to the use of this expression in the velocity and acceleration
    // computations in the sections to follow.
    denominator =
      x2 * xMultiplier3 * oneOverRadiiSquaredX +
      y2 * yMultiplier3 * oneOverRadiiSquaredY +
      z2 * zMultiplier3 * oneOverRadiiSquaredZ;

    const derivative = -2.0 * denominator;

    correction = func / derivative;
  } while (Math.abs(func) > 0.000000000001);

  // if (!(result !== undefined && result !== null)) {
  //   return new Cartesian3(
  //     positionX * xMultiplier,
  //     positionY * yMultiplier,
  //     positionZ * zMultiplier
  //   );
  // }
  let result = {
    x: positionX * xMultiplier,
    y: positionY * yMultiplier,
    z: positionZ * zMultiplier
  };
  return result;
}

function magnitude(cartesian) {
  return Math.sqrt(
    cartesian.x * cartesian.x +
      cartesian.y * cartesian.y +
      cartesian.z * cartesian.z
  );
}

fromCartesian({x:-2307065.8,y:5418833.5,z:2440308.2})

  

posted @ 2024-07-25 17:51  小韓烟柳  阅读(192)  评论(0)    收藏  举报