Пример #1
0
  /**
   * Called when the mouse moves over this widget
   *
   * @param event
   */
  void VisualDisplay::mouseMoveEvent(QMouseEvent *event) {
    double startX = width() / 2 - (p_boxWidth * (int)floor(p_boxSamps / 2) + (p_boxWidth / 2));
    double startY = height() / 2 - (p_boxHeight * (int)floor(p_boxLines / 2) + (p_boxHeight / 2));

    int x = (int)ceil((event->x() - startX) / p_boxWidth);
    int y = (int)ceil((event->y() - startY) / p_boxHeight);

    if(!p_set || x < 1 || y < 1 || x > p_boxSamps || y > p_boxLines) {
      emit setSample("Sample: n/a");
      emit setLine("Line: n/a");
      emit setDn("DN: n/a");
    }
    else {
      emit setSample(QString("Sample: %1").arg(p_ulSamp + x - 1));
      emit setLine(QString("Line: %1").arg(p_ulLine + y - 1));
      double dn = p_pixelData[y-1][x-1];
      if(IsSpecial(dn))
        emit setDn(QString("DN: %1").arg(PixelToString(dn)));
      else
        emit setDn(QString("DN: %1").arg(dn));
    }
  }
Пример #2
0
  /**
   * GetPointInfo builds the PvlGroup containing all the important 
   * information derived from the Camera.  
   * 
   * @return PvlGroup* Data taken directly from the Camera and 
   *         drived from Camera information. Ownership passed.
   */
  PvlGroup * CameraPointInfo::GetPointInfo() {
    CheckConditions();

    Brick b(3,3,1,currentCube->PixelType());
    
    int intSamp = (int)(camera->Sample() + 0.5);
    int intLine = (int)(camera->Line() + 0.5);
    b.SetBasePosition(intSamp, intLine, 1);
    currentCube->Read(b);

    double pB[3], spB[3], sB[3];
    string utc;
    double ssplat, ssplon, sslat, sslon, pwlon, oglat;

    // Create group with ground position
    PvlGroup * gp = new PvlGroup("GroundPoint");
    {
      gp->AddKeyword(PvlKeyword("Filename",currentCube->Filename()));
      gp->AddKeyword(PvlKeyword("Sample",camera->Sample()));
      gp->AddKeyword(PvlKeyword("Line",camera->Line()));
      gp->AddKeyword(PvlKeyword("PixelValue",PixelToString(b[0])));
      gp->AddKeyword(PvlKeyword("RightAscension",camera->RightAscension()));
      gp->AddKeyword(PvlKeyword("Declination",camera->Declination()));
      gp->AddKeyword(PvlKeyword("PlanetocentricLatitude",
                                camera->UniversalLatitude()));
  
      // Convert lat to planetographic
      double radii[3];
      camera->Radii(radii);
      oglat = Isis::Projection::ToPlanetographic(camera->UniversalLatitude(),
                                                 radii[0],radii[2]);
      gp->AddKeyword(PvlKeyword("PlanetographicLatitude",oglat));
      
      gp->AddKeyword(PvlKeyword("PositiveEast360Longitude",
                                camera->UniversalLongitude()));
  
      //Convert lon to -180 - 180 range
      gp->AddKeyword(PvlKeyword("PositiveEast180Longitude",
                                Isis::Projection::To180Domain(
                                  camera->UniversalLongitude())));

      //Convert lon to positive west
      pwlon = Isis::Projection::ToPositiveWest(camera->UniversalLongitude(),
                                               360);
      gp->AddKeyword(PvlKeyword("PositiveWest360Longitude",pwlon));

      //Convert pwlon to -180 - 180 range
      gp->AddKeyword(PvlKeyword("PositiveWest180Longitude",
                                Isis::Projection::To180Domain(pwlon)));
  
      camera->Coordinate(pB);
      PvlKeyword coord("BodyFixedCoordinate");
      coord.AddValue(pB[0],"km");
      coord.AddValue(pB[1],"km");
      coord.AddValue(pB[2],"km");
      gp->AddKeyword(coord);
  
      gp->AddKeyword(PvlKeyword("LocalRadius",camera->LocalRadius(),"m"));
      gp->AddKeyword(PvlKeyword("SampleResolution",camera->SampleResolution(),"m"));
      gp->AddKeyword(PvlKeyword("LineResolution",camera->LineResolution(),"m"));
  
      camera->InstrumentPosition(spB);
      PvlKeyword spcoord("SpacecraftPosition");
      spcoord.AddValue(spB[0],"km");
      spcoord.AddValue(spB[1],"km");
      spcoord.AddValue(spB[2],"km");
      spcoord.AddComment("Spacecraft Information");
      gp->AddKeyword(spcoord);
  
  
      gp->AddKeyword(PvlKeyword("SpacecraftAzimuth",camera->SpacecraftAzimuth()));
      gp->AddKeyword(PvlKeyword("SlantDistance",camera->SlantDistance(),"km"));
      gp->AddKeyword(PvlKeyword("TargetCenterDistance",camera->TargetCenterDistance(),"km"));
      camera->SubSpacecraftPoint(ssplat,ssplon);
      gp->AddKeyword(PvlKeyword("SubSpacecraftLatitude",ssplat));
      gp->AddKeyword(PvlKeyword("SubSpacecraftLongitude",ssplon));
      gp->AddKeyword(PvlKeyword("SpacecraftAltitude",camera->SpacecraftAltitude(),"km"));
      gp->AddKeyword(PvlKeyword("OffNadirAngle",camera->OffNadirAngle()));
      double subspcgrdaz;
      subspcgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(),
        ssplat,ssplon);
      gp->AddKeyword(PvlKeyword("SubSpacecraftGroundAzimuth",subspcgrdaz));
  
      camera->SunPosition(sB);
      PvlKeyword scoord("SunPosition");
      scoord.AddValue(sB[0],"km");
      scoord.AddValue(sB[1],"km");
      scoord.AddValue(sB[2],"km");
      scoord.AddComment("Sun Information");
      gp->AddKeyword(scoord);
  
      gp->AddKeyword(PvlKeyword("SubSolarAzimuth",camera->SunAzimuth()));
      gp->AddKeyword(PvlKeyword("SolarDistance",camera->SolarDistance(),"AU"));
      camera->SubSolarPoint(sslat,sslon);
      gp->AddKeyword(PvlKeyword("SubSolarLatitude",sslat));
      gp->AddKeyword(PvlKeyword("SubSolarLongitude",sslon));
      double subsolgrdaz;
      subsolgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(),
        sslat,sslon);
      gp->AddKeyword(PvlKeyword("SubSolarGroundAzimuth",subsolgrdaz));
  
      PvlKeyword phase("Phase",camera->PhaseAngle());
      phase.AddComment("Illumination and Other");
      gp->AddKeyword(phase);
      gp->AddKeyword(PvlKeyword("Incidence",camera->IncidenceAngle()));
      gp->AddKeyword(PvlKeyword("Emission",camera->EmissionAngle()));
      gp->AddKeyword(PvlKeyword("NorthAzimuth",camera->NorthAzimuth()));
  
      PvlKeyword et("EphemerisTime",camera->EphemerisTime(),"seconds");
      et.AddComment("Time");
      gp->AddKeyword(et);
      iTime t(camera->EphemerisTime());
      utc = t.UTC();
      gp->AddKeyword(PvlKeyword("UTC",utc));
      gp->AddKeyword(PvlKeyword("LocalSolarTime",camera->LocalSolarTime(),"hour"));
      gp->AddKeyword(PvlKeyword("SolarLongitude",camera->SolarLongitude()));
    }
    return gp;
  }
Пример #3
0
  /**
   * Updates the tracking labels.
   *
   *
   * @param p
   */
  void TrackTool::updateLabels(QPoint p) {
    MdiCubeViewport *cvp = cubeViewport();

    clearLabels();

    if(cvp == NULL) {
      return;
    }

    double sample, line;
    cvp->viewportToCube(p.x(), p.y(), sample, line);
    if((sample < 0.5) || (line < 0.5) ||
        (sample > cvp->cubeSamples() + 0.5) ||
        (line > cvp->cubeLines() + 0.5)) {
      return;
    }

    int isamp = (int)(sample + 0.5);
    QString text;
    text.setNum(isamp);
    text = "S " + text;
    p_sampLabel->setText(text);

    int iline = (int)(line + 0.5);
    text.setNum(iline);
    text = "L " + text;
    p_lineLabel->setText(text);


    // Do we have a projection?
    if(cvp->projection() != NULL) {
      // Set up for projection types
      Projection::ProjectionType projType = cvp->projection()->projectionType();
      p_latLabel->show();
      p_lonLabel->show();

      if(cvp->projection()->SetWorld(sample, line)) {
        if (projType == Projection::Triaxial) {
          TProjection *tproj = (TProjection *) cvp->projection();
          double lat = tproj->Latitude();
          double lon = tproj->Longitude();
          p_latLabel->setText(QString("Lat %1").arg(lat));
          p_lonLabel->setText(QString("Lon %1").arg(lon));
        }
        else { // RingPlane TODO write out radius azimuth instead of lat/lon
          RingPlaneProjection *rproj = (RingPlaneProjection *) cvp->projection();
          double rad = rproj->RingRadius();
          double lon = rproj->RingLongitude();
          //??? p_latLabel->setToolTip("Radius Position");
          p_latLabel->setText(QString("Rad %1").arg(rad));
          p_lonLabel->setText(QString("Lon %1").arg(lon));
        }
      }
      else {
        p_latLabel->setText("Lat N/A");
        p_lonLabel->setText("Lon N/A");
      }
    }
    // Do we have a camera model?
    else if(cvp->camera() != NULL) {
      p_latLabel->show();
      p_lonLabel->show();

      if(cvp->camera()->SetImage(sample, line)) {
        if (cvp->camera()->target()->shape()->name() != "Plane") {
          double lat = cvp->camera()->UniversalLatitude();
          double lon = cvp->camera()->UniversalLongitude();
          p_latLabel->setText(QString("Lat %1").arg(lat));
          p_lonLabel->setText(QString("Lon %1").arg(lon));
        }
        else {
          double rad = cvp->camera()->LocalRadius().meters();
          double lon = cvp->camera()->UniversalLongitude();
          //??? p_latLabel->setToolTip("Radius Position");
          p_latLabel->setText(QString("Rad %1").arg(rad));
          p_lonLabel->setText(QString("Lon %1").arg(lon));
        }
      }
      else {
        p_latLabel->setText("Lat N/A");
        p_lonLabel->setText("Lon N/A");
      }
    }

    else {
      p_latLabel->hide();
      p_lonLabel->hide();
    }

    if(cvp->isGray()) {
      p_grayLabel->show();
      p_redLabel->hide();
      p_grnLabel->hide();
      p_bluLabel->hide();

      ViewportBuffer *grayBuf = cvp->grayBuffer();

      if(grayBuf->working()) {
        p_grayLabel->setText("BUSY");
      }
      else {
        const QRect rect(grayBuf->bufferXYRect());

        if(p.x() >= rect.left() && p.x() <= rect.right() &&
            p.y() >= rect.top() && p.y() <= rect.bottom()) {
          const int bufX = p.x() - rect.left();
          const int bufY = p.y() - rect.top();
          QString pixelString = IString(PixelToString(
                                                grayBuf->getLine(bufY)[bufX])).ToQt();
          p_grayLabel->setText(pixelString);
        }
      }
    }
    else {
      p_grayLabel->hide();
      p_redLabel->show();
      p_grnLabel->show();
      p_bluLabel->show();

      ViewportBuffer *redBuf = cvp->redBuffer();

      if(redBuf->working()) {
        p_grayLabel->setText("BUSY");
      }
      else {
        const QRect rRect = redBuf->bufferXYRect();

        if(p.x() >= rRect.left() && p.x() < rRect.right() &&
            p.y() >= rRect.top() && p.y() < rRect.bottom()) {
          const int rBufX = p.x() - rRect.left();
          const int rBufY = p.y() - rRect.top();
          QString rLab = "R ";
          rLab += IString(PixelToString(
                                  redBuf->getLine(rBufY)[rBufX])).ToQt();
          p_redLabel->setText(rLab);
        }
      }

      ViewportBuffer *greenBuf = cvp->greenBuffer();

      if(greenBuf->working()) {
        p_grayLabel->setText("BUSY");
      }
      else {
        const QRect gRect = greenBuf->bufferXYRect();

        if(p.x() >= gRect.left() && p.x() < gRect.right() &&
            p.y() >= gRect.top() && p.y() < gRect.bottom()) {
          const int gBufX = p.x() - gRect.left();
          const int gBufY = p.y() - gRect.top();
          QString gLab = "G ";
          gLab += IString(PixelToString(
                                  greenBuf->getLine(gBufY)[gBufX])).ToQt();
          p_grnLabel->setText(gLab);
        }
      }

      ViewportBuffer *blueBuf = cvp->blueBuffer();

      if(blueBuf->working()) {
        p_grayLabel->setText("BUSY");
      }
      else {
        const QRect bRect = blueBuf->bufferXYRect();

        if(p.x() >= bRect.left() && p.x() < bRect.right() &&
            p.y() >= bRect.top() && p.y() < bRect.bottom()) {
          const int bBufX = p.x() - bRect.left();
          const int bBufY = p.y() - bRect.top();
          QString bLab = "B ";
          bLab += IString(PixelToString(
                                  blueBuf->getLine(bBufY)[bBufX])).ToQt();
          p_bluLabel->setText(bLab);
        }
      }
    }
  }
Пример #4
0
  /**
   * Paint the pixmap
   *
   */
  void VisualDisplay::paintPixmap() {
    p_pixmap = QPixmap(p_boxSamps * p_boxWidth, p_boxLines * p_boxHeight);
    p_pixmap.fill();
    QPainter p(&p_pixmap);
    QRect rect(0, 0, p_boxWidth, p_boxHeight);

    int midX = p_pixmap.width() / 2 - ((p_boxWidth / 2) * (p_boxSamps % 2));
    int midY = p_pixmap.height() / 2 - ((p_boxHeight / 2) * (p_boxLines % 2));

    int x, y;
    y = 0;

    for(int i = 0; i < p_boxLines; i++) {
      x = 0;
      for(int j = 0; j < p_boxSamps; j++) {
        double dn = p_pixelData[i][j];
        QColor c;
        if(p_showPixels || p_showDeviation) {
          if(p_showDeviation) {
            if(!IsSpecial(dn) && p_stats.TotalPixels() > 0 && p_stats.StandardDeviation() != 0) {
              double diff;

              if(dn < p_stats.Average()) {
                diff = p_stats.Average() - dn;
                diff /= p_stats.Average() - p_stats.Minimum();
              }
              else {
                diff = dn - p_stats.Average();
                diff /= p_stats.Maximum() - p_stats.Average();
              }

              int i = (int)(diff * 255.0);
              c = QColor(i, 255 - i, 0);
            }
            else {
              c = QColor(0, 0, 0);
            }
          }
          else {
            double visualValue = p_stretch.Map(dn);

            c = QColor(visualValue, visualValue, visualValue);
          }
        }
        p.save();
        p.translate(x, y);

        if(p_showText) {
          p.drawRect(rect);

          if (!IsSpecial(dn))
            p.drawText(rect, Qt::AlignCenter, QString::number(dn));
          else
            p.drawText(rect, Qt::AlignCenter, PixelToString(dn));
        }
        else {
          p.fillRect(rect, c);
        }

        p.restore();
        x += p_boxWidth;
      }
      y += p_boxHeight;
    }

    p.setPen(QPen(Qt::red, 1));
    p.save();
    p.translate(midX, midY);
    p.drawRect(rect);
    p.restore();
    update();
  }
Пример #5
0
  /**
   * GetPointInfo builds the PvlGroup containing all the important
   * information derived from the Camera.
   *
   * @return PvlGroup* Data taken directly from the Camera and
   *         drived from Camera information. Ownership passed.
   */
  PvlGroup *CameraPointInfo::GetPointInfo(bool passed, bool allowOutside, bool allowErrors) {
    PvlGroup *gp = new PvlGroup("GroundPoint");
    {
      gp->addKeyword(PvlKeyword("Filename"));
      gp->addKeyword(PvlKeyword("Sample"));
      gp->addKeyword(PvlKeyword("Line"));
      gp->addKeyword(PvlKeyword("PixelValue"));
      gp->addKeyword(PvlKeyword("RightAscension"));
      gp->addKeyword(PvlKeyword("Declination"));
      gp->addKeyword(PvlKeyword("PlanetocentricLatitude"));
      gp->addKeyword(PvlKeyword("PlanetographicLatitude"));
      gp->addKeyword(PvlKeyword("PositiveEast360Longitude"));
      gp->addKeyword(PvlKeyword("PositiveEast180Longitude"));
      gp->addKeyword(PvlKeyword("PositiveWest360Longitude"));
      gp->addKeyword(PvlKeyword("PositiveWest180Longitude"));
      gp->addKeyword(PvlKeyword("BodyFixedCoordinate"));
      gp->addKeyword(PvlKeyword("LocalRadius"));
      gp->addKeyword(PvlKeyword("SampleResolution"));
      gp->addKeyword(PvlKeyword("LineResolution"));
      gp->addKeyword(PvlKeyword("SpacecraftPosition"));
      gp->addKeyword(PvlKeyword("SpacecraftAzimuth"));
      gp->addKeyword(PvlKeyword("SlantDistance"));
      gp->addKeyword(PvlKeyword("TargetCenterDistance"));
      gp->addKeyword(PvlKeyword("SubSpacecraftLatitude"));
      gp->addKeyword(PvlKeyword("SubSpacecraftLongitude"));
      gp->addKeyword(PvlKeyword("SpacecraftAltitude"));
      gp->addKeyword(PvlKeyword("OffNadirAngle"));
      gp->addKeyword(PvlKeyword("SubSpacecraftGroundAzimuth"));
      gp->addKeyword(PvlKeyword("SunPosition"));
      gp->addKeyword(PvlKeyword("SubSolarAzimuth"));
      gp->addKeyword(PvlKeyword("SolarDistance"));
      gp->addKeyword(PvlKeyword("SubSolarLatitude"));
      gp->addKeyword(PvlKeyword("SubSolarLongitude"));
      gp->addKeyword(PvlKeyword("SubSolarGroundAzimuth"));
      gp->addKeyword(PvlKeyword("Phase"));
      gp->addKeyword(PvlKeyword("Incidence"));
      gp->addKeyword(PvlKeyword("Emission"));
      gp->addKeyword(PvlKeyword("NorthAzimuth"));
      gp->addKeyword(PvlKeyword("EphemerisTime"));
      gp->addKeyword(PvlKeyword("UTC"));
      gp->addKeyword(PvlKeyword("LocalSolarTime"));
      gp->addKeyword(PvlKeyword("SolarLongitude"));
      if (allowErrors) gp->addKeyword(PvlKeyword("Error"));
    }

    bool noErrors = passed;
    QString error = "";
    if (!m_camera->HasSurfaceIntersection()) {
      error = "Requested position does not project in camera model; no surface intersection";
      noErrors = false;
      if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_);
    }
    if (!m_camera->InCube() && !allowOutside) {
      error = "Requested position does not project in camera model; not inside cube";
      noErrors = false;
      if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_);
    }

    if (!noErrors) {
      for (int i = 0; i < gp->keywords(); i++) {
        QString name = (*gp)[i].name();
        // These three keywords have 3 values, so they must have 3 N/As
        if (name == "BodyFixedCoordinate" || name == "SpacecraftPosition" ||
            name == "SunPosition") {
          (*gp)[i].addValue("N/A");
          (*gp)[i].addValue("N/A");
          (*gp)[i].addValue("N/A");
        }
        else {
          (*gp)[i].setValue("N/A");
        }
      }
      // Set all keywords that still have valid information
      gp->findKeyword("Error").setValue(error);
      gp->findKeyword("FileName").setValue(m_currentCube->fileName());
      gp->findKeyword("Sample").setValue(toString(m_camera->Sample()));
      gp->findKeyword("Line").setValue(toString(m_camera->Line()));
      gp->findKeyword("EphemerisTime").setValue(
                      toString(m_camera->time().Et()), "seconds");
      gp->findKeyword("EphemerisTime").addComment("Time");
      QString utc = m_camera->time().UTC();
      gp->findKeyword("UTC").setValue(utc);
      gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information");
      gp->findKeyword("SunPosition").addComment("Sun Information");
      gp->findKeyword("Phase").addComment("Illumination and Other");
    }

    else {

      Brick b(3, 3, 1, m_currentCube->pixelType());

      int intSamp = (int)(m_camera->Sample() + 0.5);
      int intLine = (int)(m_camera->Line() + 0.5);
      b.SetBasePosition(intSamp, intLine, 1);
      m_currentCube->read(b);

      double pB[3], spB[3], sB[3];
      QString utc;
      double ssplat, ssplon, sslat, sslon, pwlon, oglat;

      {
        gp->findKeyword("FileName").setValue(m_currentCube->fileName());
        gp->findKeyword("Sample").setValue(toString(m_camera->Sample()));
        gp->findKeyword("Line").setValue(toString(m_camera->Line()));
        gp->findKeyword("PixelValue").setValue(PixelToString(b[0]));
        gp->findKeyword("RightAscension").setValue(toString(
                        m_camera->RightAscension()));
        gp->findKeyword("Declination").setValue(toString(
                        m_camera->Declination()));
        gp->findKeyword("PlanetocentricLatitude").setValue(toString(
                        m_camera->UniversalLatitude()));

        // Convert lat to planetographic
        Distance radii[3];
        m_camera->radii(radii);
        oglat = TProjection::ToPlanetographic(m_camera->UniversalLatitude(),
                                                    radii[0].kilometers(), 
                                                    radii[2].kilometers());
        gp->findKeyword("PlanetographicLatitude").setValue(toString(oglat));

        gp->findKeyword("PositiveEast360Longitude").setValue(toString(
                        m_camera->UniversalLongitude()));

        //Convert lon to -180 - 180 range
        gp->findKeyword("PositiveEast180Longitude").setValue(toString(
                        TProjection::To180Domain(m_camera->UniversalLongitude())));

        //Convert lon to positive west
        pwlon = TProjection::ToPositiveWest(
                               m_camera->UniversalLongitude(), 360);
        gp->findKeyword("PositiveWest360Longitude").setValue(toString(pwlon));

        //Convert pwlon to -180 - 180 range
        gp->findKeyword("PositiveWest180Longitude").setValue(toString(
                        TProjection::To180Domain(pwlon)));

        m_camera->Coordinate(pB);
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[0]), "km");
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[1]), "km");
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[2]), "km");

        gp->findKeyword("LocalRadius").setValue(toString(
                        m_camera->LocalRadius().meters()), "meters");
        gp->findKeyword("SampleResolution").setValue(toString(
                        m_camera->SampleResolution()), "meters/pixel");
        gp->findKeyword("LineResolution").setValue(toString(
                        m_camera->LineResolution()), "meters/pixel");

        //body fixed
        m_camera->instrumentPosition(spB);
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[0]), "km");
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[1]), "km");
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[2]), "km");
        gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information");

        gp->findKeyword("SpacecraftAzimuth").setValue(toString(
                        m_camera->SpacecraftAzimuth()));
        gp->findKeyword("SlantDistance").setValue(toString(
                        m_camera->SlantDistance()), "km");
        gp->findKeyword("TargetCenterDistance").setValue(toString(
                        m_camera->targetCenterDistance()), "km");
        m_camera->subSpacecraftPoint(ssplat, ssplon);
        gp->findKeyword("SubSpacecraftLatitude").setValue(toString(ssplat));
        gp->findKeyword("SubSpacecraftLongitude").setValue(toString(ssplon));
        gp->findKeyword("SpacecraftAltitude").setValue(toString(
                        m_camera->SpacecraftAltitude()), "km");
        gp->findKeyword("OffNadirAngle").setValue(toString(
                        m_camera->OffNadirAngle()));
        double subspcgrdaz;
        subspcgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), 
                                              m_camera->UniversalLongitude(),
                                              ssplat, ssplon);
        gp->findKeyword("SubSpacecraftGroundAzimuth").setValue(toString(subspcgrdaz));

        m_camera->sunPosition(sB);
        gp->findKeyword("SunPosition").addValue(toString(sB[0]), "km");
        gp->findKeyword("SunPosition").addValue(toString(sB[1]), "km");
        gp->findKeyword("SunPosition").addValue(toString(sB[2]), "km");
        gp->findKeyword("SunPosition").addComment("Sun Information");

        gp->findKeyword("SubSolarAzimuth").setValue(toString(m_camera->SunAzimuth()));
        gp->findKeyword("SolarDistance").setValue(toString(
                        m_camera->SolarDistance()), "AU");
        m_camera->subSolarPoint(sslat, sslon);
        gp->findKeyword("SubSolarLatitude").setValue(toString(sslat));
        gp->findKeyword("SubSolarLongitude").setValue(toString(sslon));
        double subsolgrdaz;
        subsolgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), 
                                              m_camera->UniversalLongitude(),
                                              sslat, sslon);
        gp->findKeyword("SubSolarGroundAzimuth").setValue(toString(subsolgrdaz));

        gp->findKeyword("Phase").setValue(toString(m_camera->PhaseAngle()));
        gp->findKeyword("Phase").addComment("Illumination and Other");
        gp->findKeyword("Incidence").setValue(toString(
                        m_camera->IncidenceAngle()));
        gp->findKeyword("Emission").setValue(toString(
                        m_camera->EmissionAngle()));
        gp->findKeyword("NorthAzimuth").setValue(toString(
                        m_camera->NorthAzimuth()));

        gp->findKeyword("EphemerisTime").setValue(toString(
                        m_camera->time().Et()), "seconds");
        gp->findKeyword("EphemerisTime").addComment("Time");
        utc = m_camera->time().UTC();
        gp->findKeyword("UTC").setValue(utc);
        gp->findKeyword("LocalSolarTime").setValue(toString(
                        m_camera->LocalSolarTime()), "hour");
        gp->findKeyword("SolarLongitude").setValue(toString(
                        m_camera->solarLongitude().degrees()));
        if (allowErrors) gp->findKeyword("Error").setValue("N/A");
      }
    }
    return gp;
  }