Пример #1
0
  /**
   * Set the output cube to specified file name and specified input images
   * and output attributes and lat,lons
   */
  Isis::Cube *ProcessMapMosaic::SetOutputCube(const QString &inputFile,
      double xmin, double xmax, double ymin, double ymax,
      double slat, double elat, double slon, double elon, int nbands,
      CubeAttributeOutput &oAtt, const QString &mosaicFile) {
    Pvl fileLab(inputFile);
    PvlGroup &mapping = fileLab.findGroup("Mapping", Pvl::Traverse);

    mapping["UpperLeftCornerX"] = toString(xmin);
    mapping["UpperLeftCornerY"] = toString(ymax);
    mapping.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
    mapping.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
    mapping.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
    mapping.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);

    Projection *firstProj = ProjectionFactory::CreateFromCube(fileLab);
    int samps = (int)(ceil(firstProj->ToWorldX(xmax) - firstProj->ToWorldX(xmin)) + 0.5);
    int lines = (int)(ceil(firstProj->ToWorldY(ymin) - firstProj->ToWorldY(ymax)) + 0.5);
    delete firstProj;

    if (p_createMosaic) {
      Pvl newMap;
      newMap.addGroup(mapping);

      // Initialize the mosaic
      CubeAttributeInput inAtt;

      ProcessByLine p;
      p.SetInputCube(inputFile, inAtt);
      p.PropagateHistory(false);
      p.PropagateLabels(false);
      p.PropagateTables(false);
      p.PropagatePolygons(false);
      p.PropagateOriginalLabel(false);

      // If track set, create the origin band
      if (GetTrackFlag()) {
        nbands += 1;
      }
      // For average priority, get the new band count
      else if (GetImageOverlay() == AverageImageWithMosaic) {
        nbands *= 2;
      }

      Cube *ocube = p.SetOutputCube(mosaicFile, oAtt, samps, lines, nbands);
      p.Progress()->SetText("Initializing mosaic");
      p.ClearInputCubes();
      p.StartProcess(ProcessMapMosaic::FillNull);

      // CreateForCube created some keywords in the mapping group that needs to be added
      ocube->putGroup(newMap.findGroup("Mapping", Pvl::Traverse));
      p.EndProcess();
    }

    Cube *mosaicCube = new Cube();
    mosaicCube->open(mosaicFile, "rw");
    mosaicCube->addCachingAlgorithm(new UniqueIOCachingAlgorithm(2));

    AddOutputCube(mosaicCube);
    return mosaicCube;
  }
Пример #2
0
 /**
  * Update the cube labels so that this cube indicates what tile size it used.
  *
  * @param labels The "Core" object in this Pvl will be updated
  */
 void CubeTileHandler::updateLabels(Pvl &labels) {
   PvlObject &core = labels.findObject("IsisCube").findObject("Core");
   core.addKeyword(PvlKeyword("Format", "Tile"),
                   PvlContainer::Replace);
   core.addKeyword(PvlKeyword("TileSamples", toString(getSampleCountInChunk())),
                   PvlContainer::Replace);
   core.addKeyword(PvlKeyword("TileLines", toString(getLineCountInChunk())),
                   PvlContainer::Replace);
 }
Пример #3
0
  PvlObject MosaicAreaTool::toPvl() const {
    PvlObject obj(projectPvlObjectName());

    if(m_box) {
      obj += PvlKeyword("Latitude", m_latLineEdit->text());
      obj += PvlKeyword("Longitude", m_lonLineEdit->text());
      obj += PvlKeyword("Area", m_areaLineEdit->text());
      obj += PvlKeyword("Visible", toString((int)(m_box != NULL)));
    }

    return obj;
  }
Пример #4
0
    /**
     * @brief Return parameters used for all bands
     *
     * Method creates keyword vectors of band specific parameters
     * used in the photometric correction.
     *
     * @author Kris Becker - 2/22/2010
     *
     * @param pvl Output PVL container write keywords
     */
    void Hillier::Report ( PvlContainer &pvl ) {
        pvl.addComment("I/F = mu0/(mu0+mu) * F(phase)");
                pvl.addComment(" where:");
                pvl.addComment("  mu0 = cos(incidence)");
                pvl.addComment("  mu = cos(incidence)");
                pvl.addComment("  F(phase) = B0*exp(-B1*phase) + A0 + A1*phase + A2*phase^2 + A3*phase^3 + A4*phase^4");

                pvl += PvlKeyword("Algorithm", "Hillier");
                pvl += PvlKeyword("IncRef", toString(_iRef), "degrees");
                pvl += PvlKeyword("EmaRef", toString(_eRef), "degrees");
                pvl += PvlKeyword("PhaRef", toString(_gRef), "degrees");
                PvlKeyword units("HillierUnits");
                PvlKeyword phostd("PhotometricStandard");
                PvlKeyword bbc("BandBinCenter");
                PvlKeyword bbct("BandBinCenterTolerance");
                PvlKeyword bbn("BandNumber");
                PvlKeyword b0("B0");
                PvlKeyword b1("B1");
                PvlKeyword a0("A0");
                PvlKeyword a1("A1");
                PvlKeyword a2("A2");
                PvlKeyword a3("A3");
                PvlKeyword a4("A4");
                for (unsigned int i = 0; i < _bandpho.size(); i++) {
                    Parameters &p = _bandpho[i];
                    units.addValue(p.units);
                    phostd.addValue(toString(p.phoStd));
                    bbc.addValue(toString(p.wavelength));
                    bbct.addValue(toString(p.tolerance));
                    bbn.addValue(toString(p.band));
                    b0.addValue(toString(p.b0));
                    b1.addValue(toString(p.b1));
                    a0.addValue(toString(p.a0));
                    a1.addValue(toString(p.a1));
                    a2.addValue(toString(p.a2));
                    a3.addValue(toString(p.a3));
                    a4.addValue(toString(p.a4));
                }
                pvl += units;
                pvl += phostd;
                pvl += bbc;
                pvl += bbct;
                pvl += bbn;
                pvl += b0;
                pvl += b1;
                pvl += a0;
                pvl += a1;
                pvl += a2;
                pvl += a3;
                pvl += a4;
                return;
            }
Пример #5
0
  /**
   * Convert to Pvl for project files. This stores all of the data associated
   *   with all of the properties (but not what is supported). This also stores
   *   the cube filename.
   */
  PvlObject DisplayProperties::toPvl() const {
    PvlObject output("DisplayProperties");
    output += PvlKeyword("DisplayName", displayName());

    QBuffer dataBuffer;
    dataBuffer.open(QIODevice::ReadWrite);

    QDataStream propsStream(&dataBuffer);
    propsStream << *m_propertyValues;
    dataBuffer.seek(0);

    output += PvlKeyword("Values", QString(dataBuffer.data().toHex()));

    return output;
  }
Пример #6
0
  /**
   * 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_);
    }
  }
Пример #7
0
  /**
   * Constructs a Sinusoidal object.
   *
   * @param label This argument must be a Label containing the proper mapping
   *              information as indicated in the Projection class. Additionally,
   *              the sinusoidal 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
   */
  Sinusoidal::Sinusoidal(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));
      }

      // Get the center longitude
      m_centerLongitude = mapGroup["CenterLongitude"];

      // convert to radians, adjust for longitude direction
      m_centerLongitude *= PI / 180.0;
      if (m_longitudeDirection == PositiveWest) m_centerLongitude *= -1.0;
    }
    catch(IException &e) {
      QString message = "Invalid label group [Mapping]";
      throw IException(e, IException::Io, message, _FILEINFO_);
    }
  }
Пример #8
0
  KernelSet Kernels::findKernels(const std::string &kname, 
                                 KernelSet::KernelType ktype, Pvl &pvl,
                                 const std::string &blobname) const {
    // Get the kernel group and load main kernels
    PvlGroup &kernels = pvl.FindGroup("Kernels",Pvl::Traverse);
    KernelSet kkey(PvlKeyword(kname), ktype);

    // Check for the keyword
    if (kernels.HasKeyword(kname)) {
      kkey = KernelSet(kernels[kname], ktype);
      // Check for keyword design < 3.1.19 and update it to current state
      if (kkey.inTable() && (kkey.size() == 0)) {
        string bname(blobname);
        if (bname.empty()) bname = kname;
        const PvlObject &blob = findTable(bname, pvl);
        if (blob.HasKeyword("Kernels")) {
          PvlKeyword bkey = blob["Kernels"];
          PvlKeyword newkey = kernels[kname];
          // Found the Kernels keyword in BLOB.  Get the filenames
          for (int i = 0 ; i < bkey.Size() ; i++) {
            newkey.AddValue(bkey[i]);
          }
          kkey = KernelSet(newkey, ktype);
        }
        else {
          kkey.Missing("Image has been jigsawed and/or kernels are gone");
        }
      }
    }

    return (kkey);
  }
Пример #9
0
  PvlObject MosaicControlNetTool::toPvl() const {
    PvlObject obj(projectPvlObjectName());

    obj += PvlKeyword("FileName", m_controlNetFile);
    obj += PvlKeyword("Visible",
        Isis::toString((int)(m_controlNetGraphics && m_controlNetGraphics->isVisible())));
    obj += PvlKeyword("Movement", toString(m_movementArrowColorSource));

    if (maxMovementColorMeasureCount() != -1) {
      obj += PvlKeyword("MovementColorMaxMeasureCount", Isis::toString(m_measureCount));
    }

    if (maxMovementColorResidualMagnitude() != Null) {
      obj += PvlKeyword("MovementColorMaxResidualMagnitude",
                        Isis::toString(m_residualMagnitude));
    }

    return obj;
  }
Пример #10
0
  /** 
   * This method looks for any naif errors that might have occurred. It 
   * then compares the error to a list of known naif errors and converts
   * the error into an iException.
   * 
   * @param resetNaif True if the NAIF error status should be reset (naif calls valid)
   */
  void NaifStatus::CheckErrors(bool resetNaif) {
    if(!initialized) {
      SpiceChar returnAct[32] = "RETURN";
      SpiceChar printAct[32] = "NONE";
      erract_c ( "SET", sizeof(returnAct), returnAct); // Reset action to return
      errprt_c ( "SET", sizeof(printAct), printAct);   // ... and print nothing
      initialized = true;
    }

    // Do nothing if NAIF didn't fail
    //getmsg_c("", 0, NULL);
    if(!failed_c()) return;

    // This method has been documented with the information provided
    //   from the NAIF documentation at:
    //    naif/cspice61/packages/cspice/doc/html/req/error.html


    // This message is a character string containing a very terse, usually 
    // abbreviated, description of the problem. The message is a character 
    // string of length not more than 25 characters. It always has the form:
    // SPICE(...)
    // Short error messages used in CSPICE are CONSTANT, since they are 
    // intended to be used in code. That is, they don't contain any data which 
    // varies with the specific instance of the error they indicate.
    // Because of the brief format of the short error messages, it is practical 
    // to use them in a test to determine which type of error has occurred. 
    const int SHORT_DESC_LEN = 26;
    SpiceChar naifShort[SHORT_DESC_LEN];
    getmsg_c("SHORT", SHORT_DESC_LEN, naifShort);

    // This message may be up to 1840 characters long. The CSPICE error handling 
    // mechanism makes no use of its contents. Its purpose is to provide human-readable 
    // information about errors. Long error messages generated by CSPICE routines often 
    // contain data relevant to the specific error they describe.
    const int LONG_DESC_LEN = 1841;
    SpiceChar naifLong[LONG_DESC_LEN];
    getmsg_c("LONG", LONG_DESC_LEN, naifLong);

    // Search for known naif errors...
    iString errMsg;

    Pvl error;
    PvlGroup errorDescription("ErrorDescription");
    errorDescription.AddKeyword(PvlKeyword("ShortMessage", naifShort));
    errorDescription.AddKeyword(PvlKeyword("LongMessage", naifLong));
    error.AddGroup(errorDescription);

    PvlTranslationManager trans(error, "$base/translations/NaifErrors.trn");

    try {
      errMsg = trans.Translate("ShortMessage");
    }
    catch(iException &e) {
      e.Clear();
      errMsg = "An unknown NAIF error has been encountered.";
    }

    try {
      errMsg += " " + trans.Translate("LongMessage");
    }
    catch(iException &e) {
      e.Clear();
    }

    // Now process the error
    if(resetNaif) {
      reset_c();
    }

    errMsg += " The short explanation ";
    errMsg += "provided by NAIF is [" + iString(naifShort) + "]. "; 
    errMsg += "The Naif error is [" + iString(naifLong) + "]";

    throw iException::Message(iException::Spice, errMsg, _FILEINFO_);
  }
Пример #11
0
  /**
   * Get Groups by translating from correct Translation table
   *
   * @param label A pvl formatted label to be used to generate the serial number
   */
  PvlGroup ObservationNumber::FindObservationTranslation(Pvl &label) {
    Pvl outLabel;
    static PvlGroup dataDir(Preference::Preferences().findGroup("DataDirectory"));

    // Get the mission name
    static QString missionTransFile = (QString) dataDir["base"] + "/translations/MissionName2DataDir.trn";
    static PvlTranslationManager missionXlater(missionTransFile);
    missionXlater.SetLabel(label);
    QString mission = missionXlater.Translate("MissionName");

    // Get the instrument name
    static QString instTransFile = (QString) dataDir["base"] + "/translations/Instruments.trn";
    static PvlTranslationManager instrumentXlater(instTransFile);
    instrumentXlater.SetLabel(label);
    QString instrument = instrumentXlater.Translate("InstrumentName");

    // We want to use this instrument's translation manager. It's much faster for
    //   ObservationNumberList if we keep the translation manager in memory, so re-reading
    //   from the disk is not necessary every time. To do this, we'll use a map to store
    //   the translation managers and observation number keys with a string identifier to find them.
    //   This identifier needs to have the mission name and the instrument name.
    static std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> > missionTranslators;
    QString key = mission + "_" + instrument;
    std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> >::iterator
    translationIterator = missionTranslators.find(key);

    if(translationIterator == missionTranslators.end()) {
      // Get the file
      FileName snFile((QString) dataDir[mission] + "/translations/" +
                                    instrument + "SerialNumber????.trn");
      snFile = snFile.highestVersion();

      // Delets the extra
      Pvl translation(snFile.expanded());
      PvlKeyword observationKeys;
      if(translation.hasKeyword("ObservationKeys")) {
        observationKeys = translation["ObservationKeys"];
      }

      // use the translation file to generate keywords
      missionTranslators.insert(
        std::pair<QString, std::pair<PvlTranslationManager, PvlKeyword> >
        (key, std::pair<PvlTranslationManager, PvlKeyword>(PvlTranslationManager(snFile.expanded()), observationKeys))
      );

      translationIterator = missionTranslators.find(key);
    }

    translationIterator->second.first.SetLabel(label);
    translationIterator->second.first.Auto(outLabel);
    PvlGroup snGroup = outLabel.findGroup("SerialNumberKeywords");

    // Delets the extra
    if(!translationIterator->second.second.name().isEmpty()) {
      snGroup += translationIterator->second.second;
    }
    else {
      snGroup += PvlKeyword("ObservationKeys", toString(snGroup.keywords()));
    }

    return snGroup;
  }
Пример #12
0
  /**
   * Find the lat/lon range of the image. This will use the image footprint,
   *   camera, or projection in order to find a good result.
   *
   * @param Cube* This is required for estimation. You can pass in NULL (it will
   *              disable estimation).
   * @param minLat This is an output: minimum latitude
   * @param maxLat This is an output: maximum latitude
   * @param minLon This is an output: minimum longitude
   * @param maxLon This is an output: maximum longitude
   * @param allowEstimation If this is true then extra efforts will be made to
   *     guess the ground range of the input. This can still fail.
   * @return True if a ground range was found, false if no ground range could
   *     be determined. Some lat/lon results may still be populated; their
   *     values are undefined.
   */
  bool UniversalGroundMap::GroundRange(Cube *cube, Latitude &minLat,
      Latitude &maxLat, Longitude &minLon, Longitude &maxLon,
      bool allowEstimation) {
    // Do we need a RingRange method?
    // For now just return false
    if (HasCamera())
      if (p_camera->target()->shape()->name() == "Plane") return false;
    if (HasProjection()) 
      if (p_projection->projectionType() == Projection::RingPlane) return false;

    minLat = Latitude();
    maxLat = Latitude();
    minLon = Longitude();
    maxLon = Longitude();

    // If we have a footprint, use it
    try {
      if (cube) {
        ImagePolygon poly;
        cube->read(poly);
        geos::geom::MultiPolygon *footprint = PolygonTools::MakeMultiPolygon(
            poly.Polys()->clone());

        geos::geom::Geometry *envelope = footprint->getEnvelope();
        geos::geom::CoordinateSequence *coords = envelope->getCoordinates();

        for (unsigned int i = 0; i < coords->getSize(); i++) {
          const geos::geom::Coordinate &coord = coords->getAt(i);

          Latitude coordLat(coord.y, Angle::Degrees);
          Longitude coordLon(coord.x, Angle::Degrees);

          if (!minLat.isValid() || minLat > coordLat)
            minLat = coordLat;
          if (!maxLat.isValid() || maxLat < coordLat)
            maxLat = coordLat;

          if (!minLon.isValid() || minLon > coordLon)
            minLon = coordLon;
          if (!maxLon.isValid() || maxLon < coordLon)
            maxLon = coordLon;
        }

        delete coords;
        coords = NULL;

        delete envelope;
        envelope = NULL;

        delete footprint;
        footprint = NULL;
      }
    }
    catch (IException &) {
    }

    if (!minLat.isValid() || !maxLat.isValid() ||
        !minLon.isValid() || !maxLon.isValid()) {
      if (HasCamera()) {
        // Footprint failed, ask the camera
        PvlGroup mappingGrp("Mapping");
        mappingGrp += PvlKeyword("LatitudeType", "Planetocentric");
        mappingGrp += PvlKeyword("LongitudeDomain", "360");
        mappingGrp += PvlKeyword("LongitudeDirection", "PositiveEast");

        Pvl mappingPvl;
        mappingPvl += mappingGrp;
        double minLatDouble;
        double maxLatDouble;
        double minLonDouble;
        double maxLonDouble;
        p_camera->GroundRange(
            minLatDouble, maxLatDouble,
            minLonDouble, maxLonDouble, mappingPvl);
        minLat = Latitude(minLatDouble, Angle::Degrees);
        maxLat = Latitude(maxLatDouble, Angle::Degrees);
        minLon = Longitude(minLonDouble, Angle::Degrees);
        maxLon = Longitude(maxLonDouble, Angle::Degrees);
      }
      else if (HasProjection()) {
        // Footprint failed, look in the mapping group
        PvlGroup mappingGrp = p_projection->Mapping();
        if (mappingGrp.hasKeyword("MinimumLatitude") &&
            mappingGrp.hasKeyword("MaximumLatitude") &&
            mappingGrp.hasKeyword("MinimumLongitude") &&
            mappingGrp.hasKeyword("MaximumLongitude")) {

          minLat = Latitude(mappingGrp["MinimumLatitude"],
                            mappingGrp, Angle::Degrees);
          maxLat = Latitude(mappingGrp["MaximumLatitude"],
                            mappingGrp, Angle::Degrees);
          minLon = Longitude(mappingGrp["MinimumLongitude"],
                             mappingGrp, Angle::Degrees);
          maxLon = Longitude(mappingGrp["MaximumLongitude"],
                             mappingGrp, Angle::Degrees);

        }
        else if (allowEstimation && cube) {
          // Footprint and mapping failed... no lat/lon range of any kind is
          //   available. Let's test points in the image to try to make our own
          //   extent.
          QList<QPointF> imagePoints;

          // Reset to TProjection
          TProjection *tproj = (TProjection *) p_projection;

                    /*
           * This is where we're testing:
           *
           *  |---------------|
           *  |***************|
           *  |**     *     **|
           *  |*  *   *   *  *|
           *  |*    * * *    *|
           *  |***************|
           *  |*    * * *    *|
           *  |*  *   *   *  *|
           *  |**     *     **|
           *  |***************|
           *  |---------------|
           *
           * We'll test at the edges, a plus (+) and an (X) to help DEMs work.
           */

          int sampleCount = cube->sampleCount();
          int lineCount = cube->lineCount();

          int stepsPerLength = 20; //number of steps per length
          double aspectRatio = (double)lineCount / (double)sampleCount;
          double xStepSize = sampleCount / stepsPerLength;
          double yStepSize = xStepSize * aspectRatio;

          if (lineCount > sampleCount) {
            aspectRatio = (double)sampleCount / (double)lineCount;
            yStepSize = lineCount / stepsPerLength;
            xStepSize = yStepSize * aspectRatio;
          }

          double yWalked = 0.5;

          //3 vertical lines
          for (int i = 0; i < 3; i++) {
            double xValue = 0.5 + ( i * (sampleCount / 2) );

            while (yWalked <= lineCount) {
              imagePoints.append( QPointF(xValue, yWalked) );
              yWalked += yStepSize;
            }

            yWalked = 0.5;
          }

          double xWalked = 0.5;

          //3 horizontal lines
          for (int i = 0; i < 3; i++) {
            double yValue = 0.5 + ( i * (lineCount / 2) );

            while (xWalked <= sampleCount) {
              imagePoints.append( QPointF(xWalked, yValue) );
              xWalked += xStepSize;
            }

            xWalked = 0.5;
          }

          double xDiagonalWalked = 0.5;
          double yDiagonalWalked = 0.5;
          xStepSize = sampleCount / stepsPerLength;
          yStepSize = lineCount / stepsPerLength;

          //Top-Down Diagonal
          while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked <= lineCount) ) {
            imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
            xDiagonalWalked += xStepSize;
            yDiagonalWalked += yStepSize;
          }

          xDiagonalWalked = 0.5;

          //Bottom-Up Diagonal
          while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked >= 0) ) {
            imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
            xDiagonalWalked += xStepSize;
            yDiagonalWalked -= yStepSize;
          }

          foreach (QPointF imagePoint, imagePoints) {
            if (tproj->SetWorld(imagePoint.x(), imagePoint.y())) {
              Latitude latResult(tproj->UniversalLatitude(),
                                 Angle::Degrees);
              Longitude lonResult(tproj->UniversalLongitude(),
                                  Angle::Degrees);
              if (minLat.isValid())
                minLat = qMin(minLat, latResult);
              else
                minLat = latResult;

              if (maxLat.isValid())
                maxLat = qMax(maxLat, latResult);
              else
                maxLat = latResult;

              if (minLon.isValid())
                minLon = qMin(minLon, lonResult);
              else
                minLon = lonResult;

              if (maxLon.isValid())
                maxLon = qMax(maxLon, lonResult);
              else
                maxLon = lonResult;
            }
          }
        }
      }
    }
Пример #13
0
  /**
   * 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_);
    }
  }
Пример #14
0
/**
 * Creates a pvl of various useful data obtained by the overlap statistics
 * class.  The pvl is returned in an output stream
 *
 * @param os The output stream to write to
 * @param stats The OverlapStatistics object to write to os
 * @return ostream Pvl of useful statistics
 */
std::ostream& operator<<(std::ostream &os, Isis::OverlapStatistics &stats) {
    // Output the private variables
    try {
        PvlObject o ("OverlapStatistics");
        PvlGroup gX ("File1");
        PvlKeyword stsX ("StartSample", stats.StartSampleX());
        PvlKeyword ensX ("EndSample", stats.EndSampleX());
        PvlKeyword stlX ("StartLine", stats.StartLineX());
        PvlKeyword enlX ("EndLine", stats.EndLineX());
        PvlKeyword avgX ("Average");
        PvlKeyword stdX ("StandardDeviation");
        PvlKeyword varX ("Variance");
        for (int band=1; band<=stats.Bands(); band++) {
            if (stats.HasOverlap(band)) {
                avgX += stats.GetMStats(band).X().Average();
                stdX += stats.GetMStats(band).X().StandardDeviation();
                varX += stats.GetMStats(band).X().Variance();
            }
        }
        gX += stsX;
        gX += ensX;
        gX += stlX;
        gX += enlX;
        gX += avgX;
        gX += stdX;
        gX += varX;

        PvlGroup gY ("File2");
        PvlKeyword stsY ("StartSample", stats.StartSampleY());
        PvlKeyword ensY ("EndSample", stats.EndSampleY());
        PvlKeyword stlY ("StartLine", stats.StartLineY());
        PvlKeyword enlY ("EndLine", stats.EndLineY());
        PvlKeyword avgY ("Average");
        PvlKeyword stdY ("StandardDeviation");
        PvlKeyword varY ("Variance");
        for (int band=1; band<=stats.Bands(); band++) {
            if (stats.HasOverlap(band)) {
                avgY += stats.GetMStats(band).Y().Average();
                stdY += stats.GetMStats(band).Y().StandardDeviation();
                varY += stats.GetMStats(band).Y().Variance();
            }
        }
        gY += stsY;
        gY += ensY;
        gY += stlY;
        gY += enlY;
        gY += avgY;
        gY += stdY;
        gY += varY;

        o += PvlKeyword("File1", stats.FilenameX().Name());
        o += PvlKeyword("File2", stats.FilenameY().Name());
        o += PvlKeyword("Width", stats.Samples());
        o += PvlKeyword("Height", stats.Lines());
        o += PvlKeyword("SamplingPercent", stats.SampPercent());
        o.AddGroup(gX);
        o.AddGroup(gY);

        PvlKeyword cov ("Covariance");
        PvlKeyword cor ("Correlation");

        PvlKeyword valid ("ValidOverlap");
        PvlKeyword val ("ValidPixels");
        PvlKeyword inv ("InvalidPixels");
        PvlKeyword tot ("TotalPixels");
        for (int band=1; band<=stats.Bands(); band++) {
            if (stats.HasOverlap(band)) {
                std::string validStr = "false";
                if (stats.IsValid(band)) validStr = "true";
                valid += validStr;
                cov += stats.GetMStats(band).Covariance();
                cor += stats.GetMStats(band).Correlation();
                val += stats.GetMStats(band).ValidPixels();
                inv += stats.GetMStats(band).InvalidPixels();
                tot += stats.GetMStats(band).TotalPixels();
            }
        }
        o += valid;
        o += cov;
        o += cor;
        o += val;
        o += inv;
        o += tot;

        for (int band=1; band<=stats.Bands(); band++) {
            if (stats.HasOverlap(band)) {
                iString bandNum (band);
                std::string bandStr = "LinearRegression" + bandNum;
                PvlKeyword LinReg(bandStr);
                double a,b;
                try {
                    stats.GetMStats(band).LinearRegression(a,b);
                    LinReg += a;
                    LinReg += b;
                }
                catch (iException &e) {
                    // It is possible one of the overlaps was constant and therefore
                    // the regression would be a vertical line (x=c instead of y=ax+b)
                    e.Clear();
                }
                o += LinReg;
            }
        }

        os << o << endl;
        return os;
    }
    catch (iException &e) {
        string msg = "Trivial overlap between [" + stats.FilenameX().Name();
        msg += "] and [" + stats.FilenameY().Name() + "]";
        throw iException::Message(iException::User,msg,_FILEINFO_);
    }

}
Пример #15
0
  /**
   * Set the output cube to specified file name and specified input images
   * and output attributes and lat,lons
   */
  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes,
      double slat, double elat, double slon, double elon,
      CubeAttributeOutput &oAtt, const QString &mosaicFile) {
    if (propagationCubes.size() < 1) {
      QString msg = "The list does not contain any data";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    int samples, lines, bands = 0;
    Pvl label;
    label.read(propagationCubes[0].toString());
    PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
    mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);

    if (mGroup.hasKeyword("UpperLeftCornerX"))
      mGroup.deleteKeyword("UpperLeftCornerX");

    if (mGroup.hasKeyword("UpperLeftCornerY"))
      mGroup.deleteKeyword("UpperLeftCornerY");

    Pvl mapPvl;
    mapPvl += mGroup;

    // Use CreateForCube because our range differs from any of the cubes (manually specified)
    Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false);

    double xmin, xmax, ymin, ymax;
    proj->XYRange(xmin, xmax, ymin, ymax);

    // The xmin/ymax should be rounded for the labels
    xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
    ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];

    for (int i = 0; i < propagationCubes.size(); i++) {
      Cube cube;
      cube.open(propagationCubes[i].toString());
      bands = max(cube.bandCount(), bands);

      // See if the cube has a projection and make sure it matches
      // previous input cubes
      Projection *projNew =
          Isis::ProjectionFactory::CreateFromCube(*(cube.label()));

      if (proj == NULL) {
      }
      else if (*proj != *projNew) {
        QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
                     "] and [" + propagationCubes[0].toString() + "]";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      if (proj) delete proj;
      proj = projNew;
    }

    if (proj) delete proj;

    return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
                         slat, elat, slon, elon, bands, oAtt, mosaicFile);
  }
Пример #16
0
  /**
   * Modifies a label for a file containing a subarea. The AlphaCube, Mapping,
   * and Instrument groups are all affected when a subarea is extracted from
   * another file. If the linc is not equal to the sinc, then the Instrument
   * and Mapping groups will be removed from the label because they will no
   * longer be valid. If the linc is equal to the sinc and they are not equal
   * to 1, then the map scale and resolution in the Mapping group needs to be
   * updated. The latitude and longitude ranges become invalid when the subarea
   * does not cover the entire sample and line range of the original cube.
   * Update the upper left corner x,y values if the projection is still valid
   * and the starting line and/or starting sample have been changed from their
   * location in the original file.
   *
   * @param icube This is the input cube that will have the subarea
   *           extracted from it. The label of this cube will be used to
   *           create updated Mapping, Instrument, and AlphaCube groups
   *           for the label of the output cube containing the subarea.
   *
   * @param ocube This is the output cube file containing the subarea. The
   *           label of this cube will be modified by extracting the Mapping,
   *           Instrument, and AlphaCube groups from the input label and
   *           putting them in this label.
   *
   * @param results This is the Results group that will go into the application
   *           log file. This group must be created by the calling application.
   *           Information will be added to it if the Mapping or Instrument
   *           groups are deleted from the output image label.
   *
   */
  void SubArea::UpdateLabel(Cube *icube, Cube *ocube, PvlGroup &results) {

    Pvl inlabel = *icube->label();

    // If the linc and sinc are not equal, then the Instrument and
    // Mapping groups are no longer valid.
    if(p_linc != p_sinc) {
      if(inlabel.findObject("IsisCube").hasGroup("Mapping")) {
        inlabel.findObject("IsisCube").deleteGroup("Mapping");
        results += PvlKeyword("MappingGroupDeleted", "True");

        // We don't want to think our projected cube is unprojected, so if we
        //   delete a mapping group and we have a camera there is a problem.
        //   Remove the camera.
        if(inlabel.findObject("IsisCube").hasGroup("Instrument")) {
          inlabel.findObject("IsisCube").deleteGroup("Instrument");
          results += PvlKeyword("InstrumentGroupDeleted", "True");
        }
      }
    }

    if(inlabel.findObject("IsisCube").hasGroup("Mapping")) {
      // Update the upper left corner X,Y values if the starting line or
      // starting sample are changed.
      if(p_sl != 1 || p_ss != 1) {
        Projection &proj = *icube->projection();
        proj.SetWorld(p_ss - 0.5, p_sl - 0.5);
        PvlGroup &mapgroup = inlabel.findObject("IsisCube").findGroup("Mapping", Pvl::Traverse);
        mapgroup.addKeyword(PvlKeyword("UpperLeftCornerX", toString(proj.XCoord())),
                            Pvl::Replace);
        mapgroup.addKeyword(PvlKeyword("UpperLeftCornerY", toString(proj.YCoord())),
                            Pvl::Replace);
      }

      // If the linc and sinc are not equal to 1, then update the
      // mapping scale and resolution.
      if(p_linc == p_sinc && p_linc != 1.0) {
        PvlGroup &mapgroup = inlabel.findObject("IsisCube").findGroup("Mapping", Pvl::Traverse);
        QString pixresUnit = mapgroup["PixelResolution"].unit();
        double pixres = toDouble(mapgroup["PixelResolution"][0]);
        mapgroup["PixelResolution"] = toString(pixres * p_linc);
        mapgroup["PixelResolution"].setUnits(pixresUnit);
        QString scaleUnit = mapgroup["Scale"].unit();
        double scale = mapgroup["Scale"];
        mapgroup["Scale"] = toString(scale / p_linc);
        mapgroup["Scale"].setUnits(scaleUnit);
      }

      // If the outer bounds of the image are changed, then the
      // latitude,longitude range is no longer valid.
      if(p_sl != 1 || p_ss != 1 || p_el != p_nl || p_es != p_ns) {
        PvlGroup &mapgroup = inlabel.findObject("IsisCube").findGroup("Mapping", Pvl::Traverse);
        if(mapgroup.hasKeyword("MinimumLatitude")) {
          mapgroup.deleteKeyword("MinimumLatitude");
        }
        if(mapgroup.hasKeyword("MaximumLatitude")) {
          mapgroup.deleteKeyword("MaximumLatitude");
        }
        if(mapgroup.hasKeyword("MinimumLongitude")) {
          mapgroup.deleteKeyword("MinimumLongitude");
        }
        if(mapgroup.hasKeyword("MaximumLongitude")) {
          mapgroup.deleteKeyword("MaximumLongitude");
        }
      }
    }

    // Make changes to the output cube label
    if(ocube->hasGroup("Instrument")) {
      ocube->deleteGroup("Instrument");
    }
    if(inlabel.findObject("IsisCube").hasGroup("Instrument")) {
      PvlGroup inst;
      inst = inlabel.findObject("IsisCube").findGroup("Instrument");
      ocube->putGroup(inst);
    }

    if(ocube->hasGroup("Mapping")) {
      ocube->deleteGroup("Mapping");
    }
    if(inlabel.findObject("IsisCube").hasGroup("Mapping")) {
      PvlGroup mapgrp;
      mapgrp = inlabel.findObject("IsisCube").findGroup("Mapping");
      ocube->putGroup(mapgrp);
    }

    // Update the AlphaCube group - this group will only be updated if
    // a Mapping group does not exist in the labels.
    AlphaCube aCube(p_ns, p_nl, ocube->sampleCount(), ocube->lineCount(),
                    p_ss - 0.5, p_sl - 0.5, p_es + 0.5, p_el + 0.5);
    aCube.UpdateGroup(*ocube->label());
  }
Пример #17
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;
  }
Пример #18
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;
  }