コード例 #1
0
ファイル: PointPerspective.cpp プロジェクト: jlaura/isis3
  /**
   * This method is used to set the latitude/longitude (assumed to be of the
   * correct LatitudeType, LongitudeDirection, and LongitudeDomain. The Set
   * forces an attempted calculation of the projection X/Y values. This may or
   * may not be successful and a status is returned as such.
   *
   * @param lat Latitude value to project
   *
   * @param lon Longitude value to project
   *
   * @return bool
   */
  bool PointPerspective::SetGround(const double lat, const double lon) {
    // Convert longitude to radians & clean up
    m_longitude = lon;
    double lonRadians = lon * PI / 180.0;
    if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;

    // Now convert latitude to radians & clean up ... it must be planetographic
    m_latitude = lat;
    double latRadians = lat;
    if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
    latRadians *= PI / 180.0;

    // Compute helper variables
    double deltaLon = (lonRadians - m_centerLongitude);
    double sinphi = sin(latRadians);
    double cosphi = cos(latRadians);
    double coslon = cos(deltaLon);

    // Lat/Lon cannot be projected
    double g =  m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
    if (g < (1.0 / m_P)) {
      m_good = false;
      return m_good;
    }

    // Compute the coordinates
    double ksp = (m_P - 1.0) / (m_P - g);
    double x = m_equatorialRadius * ksp * cosphi * sin(deltaLon);
    double y = m_equatorialRadius * ksp *
               (m_cosph0 * sinphi - m_sinph0 * cosphi * coslon);
    SetComputedXY(x, y);
    m_good = true;
    return m_good;
  }
コード例 #2
0
ファイル: PointPerspective.cpp プロジェクト: jlaura/isis3
  /**
   * Constructs an PointPerspective object
   *
   * @param label This argument must be a Label containing the proper mapping
   *              information as indicated in the Projection class. Additionally,
   *              the point perspective projection requires the center longitude
   *              to be defined in the keyword CenterLongitude.
   *
   * @param allowDefaults If set to false the constructor expects that a keyword
   *                      of CenterLongitude will be in the label. Otherwise it
   *                      will attempt to compute the center longitude using the
   *                      middle of the longitude range specified in the labels.
   *                      Defaults to false.
   *
   * @throws IException::Io
   */
  PointPerspective::PointPerspective(Pvl &label, bool allowDefaults) :
    TProjection::TProjection(label) {
    try {
      // Try to read the mapping group
      PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);

      // Compute and write the default center longitude if allowed and
      // necessary
      if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
        double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
        mapGroup += PvlKeyword("CenterLongitude", toString(lon));
      }

      // Compute and write the default center latitude if allowed and
      // necessary
      if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
        double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
        mapGroup += PvlKeyword("CenterLatitude", toString(lat));
      }

      // Get the center longitude  & latitude
      m_centerLongitude = mapGroup["CenterLongitude"];
      m_centerLatitude = mapGroup["CenterLatitude"];
      if (IsPlanetocentric()) {
        m_centerLatitude = ToPlanetographic(m_centerLatitude);
      }

      // convert to radians, adjust for longitude direction
      m_centerLongitude *= PI / 180.0;
      m_centerLatitude *= PI / 180.0;
      if (m_longitudeDirection == PositiveWest) m_centerLongitude *= -1.0;

      // Calculate sine & cosine of center latitude
      m_sinph0 = sin(m_centerLatitude);
      m_cosph0 = cos(m_centerLatitude);

      // Get the distance above planet center (the point of perspective from
      // the center of planet), and calculate P
      m_distance = mapGroup["Distance"];
      m_distance *= 1000.;
      m_P = 1.0 + (m_distance / m_equatorialRadius);

    }
    catch(IException &e) {
      QString message = "Invalid label group [Mapping]";
      throw IException(e, IException::Io, message, _FILEINFO_);
    }
  }
コード例 #3
0
  /**
  * This method is used to set the latitude/longitude (assumed to be of the
  * correct LatitudeType, LongitudeDirection, and LongitudeDomain. The Set
  * forces an attempted calculation of the projection X/Y values. This may or
  * may not be successful and a status is returned as such.
  *
  * @param lat Latitude value to project
  *
  * @param lon Longitude value to project
  *
  * @return bool
  */
  bool LunarAzimuthalEqualArea::SetGround(const double lat,
                                          const double lon) {
    // Convert longitude to radians
    m_longitude = lon;
    double lonRadians = lon * Isis::PI / 180.0;
    if (m_longitudeDirection == PositiveWest)
      lonRadians *= -1.0;

    // Now convert latitude to radians... it must be planetographic
    m_latitude = lat;
    double latRadians = lat;
    if (IsPlanetocentric())
      latRadians = ToPlanetographic(latRadians);
    latRadians *= Isis::PI / 180.0;

    double x, y;
    if (lonRadians == 0.0 && latRadians == 0.0) {
      x = 0.0;
      y = 0.0;
      SetComputedXY(x, y);
      m_good = true;
      return true;
    }

    double E = acos(cos(latRadians) * cos(lonRadians));
    double test = (sin(lonRadians) * cos(latRadians)) / sin(E);

    if (test > 1.0) test = 1.0;
    else if (test < -1.0) test = -1.0;

    double D = HALFPI - asin(test);
    if (latRadians < 0.0)
      D = -D;

    double radius = m_equatorialRadius;
    double PFAC = (HALFPI + m_maxLibration) / HALFPI;
    double RP = radius * sin(E / PFAC);

    x = RP * cos(D);
    y = RP * sin(D);

    SetComputedXY(x, y);
    m_good = true;
    return true;

  } // of SetGround
コード例 #4
0
ファイル: TransverseMercator.cpp プロジェクト: assutech/isis3
 /**
  * This method is used to set the latitude/longitude (assumed to be of the
  * correct LatitudeType, LongitudeDirection, and LongitudeDomain. The Set
  * forces an attempted calculation of the projection X/Y values. This may or
  * may not be successful and a status is returned as such.
  *
  * @param lat Latitude value to project
  *
  * @param lon Longitude value to project
  *
  * @return bool
  */
  bool TransverseMercator::SetGround(const double lat,const double lon) {
    // Get longitude & fix direction
    p_longitude = lon;
    if (p_longitudeDirection == PositiveWest) p_longitude *= -1.0;

    double cLonDeg = p_centerLongitude * 180.0 / Isis::PI;
    double deltaLon = p_longitude - cLonDeg;
    while (deltaLon < -360.0) deltaLon += 360.0;
    while (deltaLon > 360.0) deltaLon -= 360.0;
    double deltaLonRads = deltaLon * Isis::PI / 180.0;

    // Now convert latitude to radians & clean up ... it must be planetographic
    p_latitude = lat;
    double latRadians = p_latitude * Isis::PI / 180.0;
    if (IsPlanetocentric()) {
      latRadians = ToPlanetographic(p_latitude) * Isis::PI / 180.0;
    }

    double ml = p_equatorialRadius * (p_e0 * latRadians - p_e1 * sin(2.0 * latRadians)
                 + p_e2 * sin(4.0 * latRadians) - p_e3 * sin(6.0 * latRadians));

    // Declare variables
    const double epsilon = 1.0e-10;

    // Sphere Conversion
    double x,y;
    if (p_sph) {
       double cosphi = cos(latRadians);
       double b = cosphi * sin(deltaLonRads);

       // Point projects to infinity
       if (fabs(fabs(b) - 1.0) <= epsilon) {
         p_good = false;
         return p_good;
       }
       x = 0.5 * p_equatorialRadius * p_scalefactor * log((1.0 + b) / (1.0 - b));

       // If arcosine argument is too close to 1, con=0.0 because arcosine(1)=0
       double con = cosphi * cos(deltaLonRads) / sqrt(1.0 - b * b);
       if (fabs(con) > 1.0) {
         con = 0.0;
       }
       else {
         con = acos(con);
       }
       if(p_latitude < 0.0) con = -con;
       y = p_equatorialRadius * p_scalefactor * (con - p_centerLatitude);
    }

    // Ellipsoid Conversion
    else {
      if(fabs(Isis::HALFPI - fabs(latRadians)) < epsilon) {
        x = 0.0;
        y = p_scalefactor * (ml - p_ml0);
      }
      else {
        double sinphi = sin(latRadians);
        double cosphi = cos(latRadians);
        double al = cosphi * deltaLonRads;
        double als = al * al;
        double c = p_esp * cosphi * cosphi;
        double tq = tan(latRadians);
        double t = tq * tq;
        double n = p_equatorialRadius / sqrt (1.0 - p_eccsq * sinphi * sinphi);
        x = p_scalefactor * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als
                  / 20.0 * (5.0 - 18.0 * t + t * t + 72.0 * c - 58.0 * p_esp)));
        y = p_scalefactor *(ml - p_ml0 + n * tq * (als * (0.5 + als / 24.0 *
                  (5.0 - t + 9.0 * c + 4.0 * c * c + als / 30.0 *
                  (61.0 - 58.0 * t + t * t + 600.0 * c - 330.0 * p_esp)))));
      }
    }

    SetComputedXY(x,y);
    p_good = true;
    return p_good;
  }
コード例 #5
0
ファイル: TransverseMercator.cpp プロジェクト: jlaura/isis3
  /**
   * Constructs a TransverseMercator object
   *
   * @param label This argument must be a Label containing the proper mapping
   *              information as indicated in the Projection class. Additionally,
   *              the transversemercator projection requires the center longitude
   *              to be defined in the keyword CenterLongitude, and the scale
   *              factor to be defined in the keyword ScaleFactor.
   *
   * @param allowDefaults If set to false the constructor expects that a keyword
   *                      of CenterLongitude and ScaleFactor will be in the label.
   *                      Otherwise it will attempt to compute the center
   *                      longitude using the middle of the longitude range
   *                      specified in the label, and the scale factor will
   *                      default to 1.0. Defaults to false.
   *
   * @throws IException
   */
  TransverseMercator::TransverseMercator(Pvl &label, bool allowDefaults) :
      TProjection::TProjection(label) {
    try {
      // Try to read the mapping group
      PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);

      // Compute and write the default center longitude if allowed and
      // necessary
      if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
        double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
        mapGroup += PvlKeyword("CenterLongitude", toString(lon));
      }

      // Compute and write the default center latitude if allowed and
      // necessary
      if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
        double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
        mapGroup += PvlKeyword("CenterLatitude", toString(lat));
      }

      // Get the center longitude  & latitude
      m_centerLongitude = mapGroup["CenterLongitude"];
      m_centerLatitude = mapGroup["CenterLatitude"];

      // make sure the center latitude value is valid
      if (fabs(m_centerLatitude) >= 90.0) {
        string msg = "Invalid Center Latitude Value. Must be between -90 and 90";
        throw IException(IException::Io, msg, _FILEINFO_);
      }

      // make sure the center longitude value is valid
      if (fabs(m_centerLongitude) > 360.0) {
        string msg = "Invalid Center Longitude Value. Must be between -360 and 360";
        throw IException(IException::Io, msg, _FILEINFO_);
      }

      // convert latitude to planetographic if it is planetocentric
      if (IsPlanetocentric()) {
        m_centerLatitude = ToPlanetographic(m_centerLatitude);
      }

      // convert to radians and adjust for longitude direction
      if (m_longitudeDirection == PositiveWest) m_centerLongitude *= -1.0;
      m_centerLatitude *= PI / 180.0;
      m_centerLongitude *= PI / 180.0;

      // Compute other necessary variables. See Snyder, page 61
      m_eccsq = Eccentricity() * Eccentricity();
      m_esp = m_eccsq;
      m_e0 = 1.0 - 0.25 * m_eccsq * (1.0 + m_eccsq / 16.0 * (3.0 + 1.25 * m_eccsq));
      m_e1 = 0.375 * m_eccsq * (1.0 + 0.25 * m_eccsq * (1.0 + 0.468750 * m_eccsq));
      m_e2 = 0.058593750 * m_eccsq * m_eccsq * (1.0 + 0.750 * m_eccsq);
      m_e3 = m_eccsq * m_eccsq * m_eccsq * (35.0 / 3072.0);
      m_ml0 = m_equatorialRadius * (m_e0 * m_centerLatitude - m_e1 * sin(2.0 * m_centerLatitude) +
                                    m_e2 * sin(4.0 * m_centerLatitude) - m_e3 * sin(6.0 * m_centerLatitude));

      // Set flag for sphere or ellipsiod
      m_sph = true; // Sphere
      if (Eccentricity() >= .00001) {
        m_sph = false; // Ellipsoid
        m_esp = m_eccsq / (1.0 - m_eccsq);
      }

      // Get the scale factor
      if ((allowDefaults) && (!mapGroup.hasKeyword("ScaleFactor"))) {
        mapGroup += PvlKeyword("ScaleFactor", toString(1.0));
      }
      m_scalefactor = mapGroup["ScaleFactor"];
    }
    catch(IException &e) {
      string message = "Invalid label group [Mapping]";
      throw IException(e, IException::Io, message, _FILEINFO_);
    }
  }
コード例 #6
0
ファイル: TransverseMercator.cpp プロジェクト: jlaura/isis3
  /**
   * This method is used to set the latitude/longitude (assumed to be of the
   * correct LatitudeType, LongitudeDirection, and LongitudeDomain. The Set
   * forces an attempted calculation of the projection X/Y values. This may or
   * may not be successful and a status is returned as such.
   *
   * @param lat Latitude value to project
   *
   * @param lon Longitude value to project
   *
   * @return bool
   */
  bool TransverseMercator::SetGround(const double lat, const double lon) {
    // Get longitude & fix direction
    m_longitude = lon;
    if (m_longitudeDirection == PositiveWest) m_longitude *= -1.0;

    double cLonDeg = m_centerLongitude * 180.0 / PI;
    double deltaLon = m_longitude - cLonDeg;
    while(deltaLon < -360.0) deltaLon += 360.0;
    while(deltaLon > 360.0) deltaLon -= 360.0;
    double deltaLonRads = deltaLon * PI / 180.0;

    // Now convert latitude to radians & clean up ... it must be planetographic
    m_latitude = lat;
    double latRadians = m_latitude * PI / 180.0;
    if (IsPlanetocentric()) {
      latRadians = ToPlanetographic(m_latitude) * PI / 180.0;
    }

    // distance along the meridian fromthe Equator to the latitude phi
    // see equation (3-21) on pages 61, 17.
    double M = m_equatorialRadius * (m_e0 * latRadians 
                                      - m_e1 * sin(2.0 * latRadians)
                                      + m_e2 * sin(4.0 * latRadians) 
                                      - m_e3 * sin(6.0 * latRadians));

    // Declare variables
    const double epsilon = 1.0e-10;

    // Sphere Conversion
    double x, y;
    if (m_sph) {
      double cosphi = cos(latRadians);
      double b = cosphi * sin(deltaLonRads);

      // Point projects to infinity
      if (fabs(fabs(b) - 1.0) <= epsilon) {
        m_good = false;
        return m_good;
      }
      x = 0.5 * m_equatorialRadius * m_scalefactor * log((1.0 + b) / (1.0 - b));

      // If arcosine argument is too close to 1, con=0.0 because arcosine(1)=0
      double con = cosphi * cos(deltaLonRads) / sqrt(1.0 - b * b);
      if (fabs(con) > 1.0) {
        con = 0.0;
      }
      else {
        con = acos(con);
      }
      if (m_latitude < 0.0) con = -con;
      y = m_equatorialRadius * m_scalefactor * (con - m_centerLatitude);
    }

    // Ellipsoid Conversion
    else {
      if (fabs(HALFPI - fabs(latRadians)) < epsilon) {
        x = 0.0;
        y = m_scalefactor * (M - m_ml0);
      }
      else {
        // Define Snyder's variables for ellipsoidal projections, page61
        double sinphi = sin(latRadians);
        double cosphi = cos(latRadians);
        double A = cosphi * deltaLonRads;        // see equation (8-15), page 61
        double Asquared = A * A;
        double C = m_esp * cosphi * cosphi;      // see equation (8-14), page 61
        double tanphi = tan(latRadians);
        double T = tanphi * tanphi;              // see equation (8-13), page 61
        double N = m_equatorialRadius / sqrt(1.0 - m_eccsq * sinphi * sinphi);
                                                 // see equation (4-20), page 61

        x = m_scalefactor * N * A 
               * (1.0 + Asquared / 6.0 * (1.0 - T + C + Asquared / 20.0 
                                 *(5.0 - 18.0*T + T*T + 72.0*C - 58.0*m_esp)));
        y = m_scalefactor 
               * (M - m_ml0 + N*tanphi*(Asquared * (0.5 + Asquared / 24.0 *
                             (5.0 - T + 9.0*C + 4.0*C*C + Asquared / 30.0
                             *(61.0 - 58.0*T + T*T + 600.0*C - 330.0*m_esp)))));
      }
    }

    SetComputedXY(x, y);
    m_good = true;
    return m_good;
  }