示例#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
  /**
   * Mosaic Processing method, returns false if the cube is not inside the mosaic
   */
  bool ProcessMapMosaic::StartProcess(QString inputFile) {
    if (InputCubes.size() != 0) {
      QString msg = "Input cubes already exist; do not call SetInputCube when using ";
      msg += "ProcessMosaic::StartProcess(QString)";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    if (OutputCubes.size() == 0) {
      QString msg = "An output cube must be set before calling StartProcess";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    CubeAttributeInput inAtt(inputFile);
    Cube *inCube = ProcessMosaic::SetInputCube(inputFile, inAtt);

    Cube *mosaicCube = OutputCubes[0];
    Projection *iproj = inCube->projection();
    Projection *oproj = mosaicCube->projection();
    int nsMosaic = mosaicCube->sampleCount();
    int nlMosaic = mosaicCube->lineCount();

    if (*iproj != *oproj) {
      QString msg = "Mapping groups do not match between cube [" + inputFile + "] and mosaic";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    int outSample, outSampleEnd, outLine, outLineEnd;
    outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) + 0.5);
    outLine   = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) + 0.5);

    int ins = InputCubes[0]->sampleCount();
    int inl =  InputCubes[0]->lineCount();
    outSampleEnd = outSample + ins;
    outLineEnd   = outLine + inl;

    bool wrapPossible = iproj->IsEquatorialCylindrical();
    int worldSize = 0;
    if (wrapPossible) {
      // Figure out how many samples 360 degrees is
      wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 0);
      int worldStart = (int)(oproj->WorldX() + 0.5);
      wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 180);
      int worldEnd = (int)(oproj->WorldX() + 0.5);

      worldSize = abs(worldEnd - worldStart) * 2;

      wrapPossible = wrapPossible && (worldSize > 0);

      // This is EquatorialCylindrical, so shift to the left all the way
      if (wrapPossible) {
        // While some data would still be put in the mosaic, move left
        //  >1 for end because 0 still means no data, whereas 1 means 1 line of data
        while (outSampleEnd - worldSize > 1) {
          outSample -= worldSize;
          outSampleEnd -= worldSize;
        }
        // Now we have the sample range to the furthest left
      }
    }

    // Check overlaps of input image along the mosaic edges before
    // calling ProcessMosaic::StartProcess
    // Left edge
    if (outSample < 1) {
      ins = ins + outSample - 1;
    }

    // Top edge
    if (outLine < 1) {
      inl = inl + outLine - 1;
    }

    // Right edge
    if ((outSample + ins - 1) > nsMosaic) {
      ins = nsMosaic - outSample + 1;
    }

    // Bottom edge
    if ((outLine + inl - 1) > nlMosaic) {
      inl = nlMosaic - outLine + 1;
    }

    if (outSampleEnd < 1 || outLineEnd < 1 || outSample > nsMosaic || outLine > nlMosaic || ins < 1 || inl < 1) {
      // Add a PvlKeyword naming which files are not included in output mosaic
      ClearInputCubes();
      return false;
    }
    else {
      // Place the input in the mosaic
      Progress()->SetText("Mosaicking " + FileName(inputFile).name());

      try {
        do {
          int outBand = 1;
          ProcessMosaic::StartProcess(outSample, outLine, outBand);

          // Increment for projections where occurrances may happen multiple times
          outSample += worldSize;
          outSampleEnd += worldSize;
        }
        while (wrapPossible && outSample < nsMosaic);
      }
      catch (IException &e) {
        QString msg = "Unable to mosaic cube [" + FileName(inputFile).name() + "]";
        throw IException(e, IException::User, msg, _FILEINFO_);
      }
    }

    WriteHistory(*mosaicCube);

    // Don't propagate any more histories now that we've done one
    p_propagateHistory = false;

    ClearInputCubes();

    return true;
  }
示例#3
0
文件: himos.cpp 项目: assutech/isis3
void IsisMain() {

  // Get the list of cubes to mosaic

  UserInterface &ui = Application::GetUserInterface();
  FileList flist(ui.GetFilename("FROMLIST"));


  vector<Cube *> clist;
  try {
    if (flist.size() < 1) {
      string msg = "the list file [" +ui.GetFilename("FROMLIST") +
                   "does not contain any data";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }

    // open all the cube and place in vector clist  

    for (int i=0; i<(int)flist.size(); i++) {
      Cube *c = new Cube();
      clist.push_back(c);
      c->Open(flist[i]);
    }



    // run the compair function here.  This will conpair the 
    // labels of the first cube to the labels of each following cube. 
    PvlKeyword sourceProductId("SourceProductId");
    string ProdId;
    for (int i=0; i<(int)clist.size(); i++) {
      Pvl *pmatch = clist[0]->Label();
      Pvl *pcomp = clist[i]->Label();
      CompareLabels(*pmatch, *pcomp);
      PvlGroup g = pcomp->FindGroup("Instrument",Pvl::Traverse);
      if (g.HasKeyword("StitchedProductIds")) {
        PvlKeyword k = g["StitchedProductIds"];
        for (int j=0; j<(int)k.Size(); j++) {
          sourceProductId += g["stitchedProductIds"][j];
        }     
      }
      ProdId = (string)pmatch->FindGroup("Archive",Pvl::Traverse)["ObservationId"];
      iString bandname = (string)pmatch->FindGroup("BandBin",Pvl::Traverse)["Name"];
      bandname = bandname.UpCase();
      ProdId = ProdId + "_" + bandname;
    }
    bool runXY=true;

    //calculate the min and max lon
    double minLat = DBL_MAX;
    double maxLat = -DBL_MAX;
    double minLon = DBL_MAX;
    double maxLon = -DBL_MAX;
    double avgLat;
    double avgLon;
    for (int i=0; i<(int)clist.size(); i++) {
      Projection *proj = clist[i]->Projection();
      if (proj->MinimumLatitude() < minLat) minLat = proj->MinimumLatitude();
      if (proj->MaximumLatitude() > maxLat) maxLat = proj->MaximumLatitude();
      if (proj->MinimumLongitude() < minLon) minLon = proj->MinimumLongitude();
      if (proj->MaximumLongitude() > maxLon) maxLon = proj->MaximumLongitude();
    }
    avgLat = (minLat + maxLat) / 2;
    avgLon = (minLon + maxLon) / 2;
    Projection *proj = clist[0]->Projection();
    proj->SetGround(avgLat,avgLon);
    avgLat = proj->UniversalLatitude();
    avgLon = proj->UniversalLongitude();

    // Use camera class to get Inc., emi., phase, and other values
    double Cemiss;
    double Cphase;
    double Cincid;
    double ClocalSolTime;
    double CsolarLong;
    double CsunAzimuth;
    double CnorthAzimuth;
    for (int i=0; i<(int)clist.size(); i++) {
      Camera *cam = clist[i]->Camera();
      if (cam->SetUniversalGround(avgLat,avgLon)) {
        Cemiss = cam->EmissionAngle();
        Cphase = cam->PhaseAngle();
        Cincid = cam->IncidenceAngle();
        ClocalSolTime = cam->LocalSolarTime();
        CsolarLong = cam->SolarLongitude();
        CsunAzimuth = cam->SunAzimuth();
        CnorthAzimuth = cam->NorthAzimuth();
        runXY = false;
        break;
      }
    }

    //The code within the if runXY was added in 10/07 to find an intersect with
    //pole images that would fail when using projection set universal ground.  
    // This is run if no intersect is found when using lat and lon in 
    // projection space.
    if (runXY) {
      double startX = DBL_MAX;
      double endX = DBL_MIN;
      double startY = DBL_MAX;
      double endY =  DBL_MIN;
      for (int i=0; i<(int)clist.size(); i++) {
        Projection *proj = clist[i]->Projection();
        proj->SetWorld(0.5,0.5);
        if (i==0) {
          startX = proj->XCoord();
          endY = proj->YCoord();
        }
        else {
          if (proj->XCoord() < startX) startX =  proj->XCoord();
          if (proj->YCoord() > endY) endY = proj->YCoord();
        }
        Pvl *p = clist[i]->Label();
        double nlines = p->FindGroup("Dimensions",Pvl::Traverse)["Lines"];
        double nsamps = p->FindGroup("Dimensions",Pvl::Traverse)["Samples"];

        proj->SetWorld((nsamps+0.5),(nlines+0.5));
        if (i==0) {
          endX = proj->XCoord();
          startY = proj->YCoord();
        }
        else {
          if (proj->XCoord() > endX) endX =  proj->XCoord();
          if (proj->YCoord() < startY) startY = proj->YCoord();
        }
      }

      double avgX = (startX + endX) / 2;
      double avgY = (startY + endY) / 2;
      double sample = proj->ToWorldX(avgX);
      double line = proj->ToWorldY(avgY);

      for (int i=0; i<(int)clist.size(); i++) {
        Camera *cam = clist[i]->Camera();
        if (cam->SetImage(sample,line)) {
          Cemiss = cam->EmissionAngle();
          Cphase = cam->PhaseAngle();
          Cincid = cam->IncidenceAngle();
          ClocalSolTime = cam->LocalSolarTime();
          CsolarLong = cam->SolarLongitude();
          CsunAzimuth = cam->SunAzimuth();
          CnorthAzimuth = cam->NorthAzimuth();
          runXY = false;
          break;
        }
      }
    }
    if (runXY) {
      string msg = "Camera did not intersect images to gather stats";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }

    // get the min and max SCLK values ( do this with string comp.)
    // get the value from the original label blob
    string startClock;
    string stopClock;
    string startTime;
    string stopTime;
    for (int i=0; i<(int)clist.size(); i++) {
      OriginalLabel origLab;
      clist[i]->Read(origLab);
      PvlGroup timegrp = origLab.ReturnLabels().FindGroup("TIME_PARAMETERS",Pvl::Traverse);
      if (i==0) {
        startClock = (string)timegrp["SpacecraftClockStartCount"];
        stopClock = (string)timegrp["SpacecraftClockStopCount"];
        startTime = (string)timegrp["StartTime"];
        stopTime = (string)timegrp["StopTime"];
      }
      else {
        string testStartTime = (string)timegrp["StartTime"];
        string testStopTime = (string)timegrp["StopTime"];
        if (testStartTime < startTime) {
          startTime = testStartTime;
          startClock = (string)timegrp["SpacecraftClockStartCount"];
        }
        if (testStopTime > stopTime) {
          stopTime = testStopTime;
          stopClock = (string)timegrp["spacecraftClockStopCount"];
        }
      }
    }

    //  Concatenate all TDI's and summing and specialProcessingFlat into one keyword 
    PvlKeyword cpmmTdiFlag("cpmmTdiFlag");
    PvlKeyword cpmmSummingFlag("cpmmSummingFlag");
    PvlKeyword specialProcessingFlag("SpecialProcessingFlag");
    for (int i=0; i<14; i++) {
      cpmmTdiFlag +=(string)"";
      cpmmSummingFlag +=(string)"";
      specialProcessingFlag +=(string)"";
    }

    for (int i=0; i<(int)clist.size(); i++) {
      Pvl *clab = clist[i]->Label();
      PvlGroup cInst = clab->FindGroup("Instrument",Pvl::Traverse);
      OriginalLabel cOrgLab;
      clist[i]->Read(cOrgLab);
      PvlGroup cGrp = cOrgLab.ReturnLabels().FindGroup("INSTRUMENT_SETTING_PARAMETERS",Pvl::Traverse);
      cpmmTdiFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:TDI"];
      cpmmSummingFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:BINNING"];

      if (cInst.HasKeyword("Special_Processing_Flag")) {
        specialProcessingFlag[cInst["CpmmNumber"]] = (string) cInst["Special_Processing_Flag"];
      }
      else {
        // there may not be the keyword Special_Processing_Flag if no
        //keyword then set the output to NOMINAL
        specialProcessingFlag[cInst["CpmmNumber"]] = "NOMINAL";
      }
    }


    // Get the blob of original labels from first image in list
    OriginalLabel org;
    clist[0]->Read(org);

    //close all cubes
    for (int i=0; i<(int)clist.size(); i++) {
      clist[i]->Close();
      delete clist[i];
    }
    clist.clear();

    // automos step
    string list = ui.GetFilename("FROMLIST");
    string toMosaic = ui.GetFilename("TO");
    string MosaicPriority = ui.GetString("PRIORITY");

    string parameters = "FROMLIST=" + list + " MOSAIC=" + toMosaic + " PRIORITY=" + MosaicPriority;
    Isis::iApp ->Exec("automos",parameters);

    // write out new information to new group mosaic 

    PvlGroup mos("Mosaic");
    mos += PvlKeyword("ProductId ", ProdId);
    mos += PvlKeyword(sourceProductId); 
    mos += PvlKeyword("StartTime ", startTime);
    mos += PvlKeyword("SpacecraftClockStartCount ", startClock);
    mos += PvlKeyword("StopTime ", stopTime);
    mos += PvlKeyword("SpacecraftClockStopCount ", stopClock);
    mos += PvlKeyword("IncidenceAngle ", Cincid, "DEG");
    mos += PvlKeyword("EmissionAngle ", Cemiss, "DEG");
    mos += PvlKeyword("PhaseAngle ", Cphase, "DEG");
    mos += PvlKeyword("LocalTime ", ClocalSolTime, "LOCALDAY/24");
    mos += PvlKeyword("SolarLongitude ", CsolarLong, "DEG");
    mos += PvlKeyword("SubSolarAzimuth ", CsunAzimuth, "DEG");
    mos += PvlKeyword("NorthAzimuth ", CnorthAzimuth, "DEG");
    mos += cpmmTdiFlag;
    mos += cpmmSummingFlag;
    mos += specialProcessingFlag;

    Cube mosCube;
    mosCube.Open(ui.GetFilename("TO"), "rw");
    PvlObject &lab=mosCube.Label()->FindObject("IsisCube");
    lab.AddGroup(mos);
    //add orginal label blob to the output cube
    mosCube.Write(org);
    mosCube.Close();

  }
  catch (iException &e) {
    for (int i=0; i<(int)clist.size(); i++) {
      clist[i]->Close();
      delete clist[i];
    }
    string msg = "The mosaic [" + ui.GetFilename("TO") + "] was NOT created";
    throw iException::Message(iException::User,msg,_FILEINFO_);
  }
} // end of isis main
示例#4
0
/**
 * Constructs an OverlapStatistics object.  Compares the two input cubes and
 * finds where they overlap.
 *
 * @param x The first input cube
 * @param y The second input cube
 * @param progressMsg (Default value of "Gathering Overlap Statistics") Text
 *         for indicating progress during statistic gathering
 * @param sampPercent (Default value of 100.0) Sampling percent, or the percentage
 *       of lines to consider during the statistic gathering procedure
 *
 * @throws Isis::iException::User - All images must have the same number of
 *                                  bands
 */
OverlapStatistics::OverlapStatistics(Isis::Cube &x, Isis::Cube &y,
                                     std::string progressMsg, double sampPercent) {
    // Test to ensure sampling percent in bound
    if (sampPercent <= 0.0 || sampPercent > 100.0) {
        string msg = "The sampling percent must be a decimal (0.0, 100.0]";
        throw iException::Message(iException::Programmer,msg,_FILEINFO_);
    }

    p_sampPercent = sampPercent;

    // Extract filenames and band number from cubes
    p_xFile = x.Filename();
    p_yFile = y.Filename();

    // Make sure number of bands match
    if (x.Bands() != y.Bands()) {
        string msg = "Number of bands do not match between cubes [" +
                     p_xFile.Name() + "] and [" + p_yFile.Name() + "]";
        throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    p_bands = x.Bands();
    p_stats.resize(p_bands);

    //Create projection from each cube
    Projection *projX = x.Projection();
    Projection *projY = y.Projection();

    // Test to make sure projection parameters match
    if (*projX != *projY) {
        string msg = "Mapping groups do not match between cubes [" +
                     p_xFile.Name() + "] and [" + p_yFile.Name() + "]";
        throw iException::Message(iException::Programmer,msg,_FILEINFO_);
    }

    // Figure out the x/y range for both images to find the overlap
    double Xmin1 = projX->ToProjectionX(0.5);
    double Ymax1 = projX->ToProjectionY(0.5);
    double Xmax1 = projX->ToProjectionX(x.Samples()+0.5);
    double Ymin1 = projX->ToProjectionY(x.Lines()+0.5);

    double Xmin2 = projY->ToProjectionX(0.5);
    double Ymax2 = projY->ToProjectionY(0.5);
    double Xmax2 = projY->ToProjectionX(y.Samples()+0.5);
    double Ymin2 = projY->ToProjectionY(y.Lines()+0.5);

    // Find overlap
    if ((Xmin1<Xmax2) && (Xmax1>Xmin2) && (Ymin1<Ymax2) && (Ymax1>Ymin2)) {
        double minX = Xmin1 > Xmin2 ? Xmin1 : Xmin2;
        double minY = Ymin1 > Ymin2 ? Ymin1 : Ymin2;
        double maxX = Xmax1 < Xmax2 ? Xmax1 : Xmax2;
        double maxY = Ymax1 < Ymax2 ? Ymax1 : Ymax2;

        // Find Sample range of the overlap
        p_minSampX = (int)(projX->ToWorldX(minX) + 0.5);
        p_maxSampX = (int)(projX->ToWorldX(maxX) + 0.5);
        p_minSampY = (int)(projY->ToWorldX(minX) + 0.5);
        p_maxSampY = (int)(projY->ToWorldX(maxX) + 0.5);
        p_sampRange = p_maxSampX - p_minSampX + 1;

        // Test to see if there was only sub-pixel overlap
        if (p_sampRange <= 0) return;

        // Find Line range of overlap
        p_minLineX = (int)(projX->ToWorldY(maxY) + 0.5);
        p_maxLineX = (int)(projX->ToWorldY(minY) + 0.5);
        p_minLineY = (int)(projY->ToWorldY(maxY) + 0.5);
        p_maxLineY = (int)(projY->ToWorldY(minY) + 0.5);
        p_lineRange = p_maxLineX - p_minLineX + 1;

        // Print percent processed
        Progress progress;
        progress.SetText(progressMsg);

        int linc = (int)(100.0 / sampPercent + 0.5); // Calculate our line increment

        // Define the maximum number of steps to be our line range divided by the
        // line increment, but if they do not divide evenly, then because of
        // rounding, we need to do an additional step for each band
        int maxSteps = (int)(p_lineRange / linc + 0.5);

        if (p_lineRange % linc != 0) maxSteps += 1;
        maxSteps *= p_bands;


        progress.SetMaximumSteps(maxSteps);
        progress.CheckStatus();

        // Collect and store off the overlap statistics
        for (int band=1; band<=p_bands; band++) {
            Brick b1(p_sampRange,1,1,x.PixelType());
            Brick b2(p_sampRange,1,1,y.PixelType());

            int i=0;
            while (i<p_lineRange) {
                b1.SetBasePosition(p_minSampX,(i+p_minLineX),band);
                b2.SetBasePosition(p_minSampY,(i+p_minLineY),band);
                x.Read(b1);
                y.Read(b2);
                p_stats[band-1].AddData(b1.DoubleBuffer(), b2.DoubleBuffer(), p_sampRange);

                // Make sure we consider the last line
                if (i+linc > p_lineRange-1 && i != p_lineRange-1) {
                    i = p_lineRange-1;
                    progress.AddSteps(1);
                }
                else i+=linc; // Increment the current line by our incrementer

                progress.CheckStatus();
            }
        }
    }
}