Unverified Commit a3d900db authored by Kelvin Rodriguez's avatar Kelvin Rodriguez Committed by GitHub
Browse files

mappt will now report physical band number (#3890)

* mappt will now report physical band number

* added filter name output

* translated tests

* allowoutside tests now check pvl

* now more tests

* removed prints
parent b92d876b
Loading
Loading
Loading
Loading
+15 −321
Original line number Diff line number Diff line
@@ -2,17 +2,10 @@

#include "Isis.h"

#include <QString>
#include <cmath>
#include "mappt.h"

#include "Brick.h"
#include "FileName.h"
#include "IException.h"
#include "IString.h"
#include "Process.h"
#include "TProjection.h"
#include "ProjectionFactory.h"
#include "SpecialPixel.h"
#include "Application.h"
#include "Pvl.h"

using namespace std;
using namespace Isis;
@@ -25,324 +18,25 @@ map <QString, void *> GuiHelpers() {
  return helper;
}

void IsisMain() {
  // Use a regular Process
  Process p;

  // Open the input cube and initialize the projection
  Cube *icube = p.SetInputCube("FROM");
  TProjection *proj = (TProjection *) icube->projection();

  // Get the coordinate
void IsisMain() {
  UserInterface &ui = Application::GetUserInterface();
  bool outsideAllowed = ui.GetBoolean("ALLOWOUTSIDE");
  int cubeLineLimit = icube->lineCount() + .5;
  int cubeSampleLimit = icube->sampleCount() + .5;

  // Get the sample/line position if we have an image point
  if(ui.GetString("TYPE") == "IMAGE") {
    double samp = ui.GetDouble("SAMPLE");
    double line = ui.GetDouble("LINE");
    if (!outsideAllowed) {
      if (samp < .5 || line < .5 || samp > cubeSampleLimit || line > cubeLineLimit) {
        QString error = "Requested line,sample is not on the image";
        throw IException(IException::Unknown, error, _FILEINFO_);
      }
    }
    proj->SetWorld(samp, line);
  }

  // Get the lat/lon position if we have a ground point
  else if(ui.GetString("TYPE") == "GROUND") {
    double lat = ui.GetDouble("LATITUDE");
    double lon = ui.GetDouble("LONGITUDE");

    // Make sure we have a valid latitude value
    if(fabs(lat) > 90.0) {
      QString msg = "Invalid value for LATITUDE ["
                   + toString(lat) + "] outside range of ";
      msg += "[-90,90]";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    IString coordsys = ui.GetString("COORDSYS");
    coordsys.UpCase();

    // All of these ifs will finish by setting the ground in the projection,
    // there are 4 options, Universal, InputFileSystem, Mapfile, and
    // Userdefined.

    // Positive East, 0-360, Planetocentric
    if(coordsys == "UNIVERSAL") {
      proj->SetUniversalGround(lat, lon);
    }

    // Use the coordinate system of the input file
    else if(coordsys == "INPUTFILESYS") {
      proj->SetGround(lat, lon);
    }

    // Use the mapping group from a given file
    else if(coordsys == "MAP") {
      FileName mapFile = ui.GetFileName("MAP");

      // Does it exist?
      if(!mapFile.fileExists()) {
        QString msg = "Filename [" + ui.GetFileName("MAP") + "] does not exist";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      // Load it up into a new projection
      Pvl mapPvl;
      mapPvl.read(mapFile.expanded());
      TProjection *altmap = (TProjection *) ProjectionFactory::CreateFromCube(mapPvl);

      // Set lat and lon in its system
      altmap->SetGround(lat, lon);

      // Set universal in input cube from universal from given
      // mapping/projection
      proj->SetUniversalGround(
        altmap->UniversalLatitude(), altmap->UniversalLongitude());

      // I think this is right, no cube owns it, and the factory doesn't.
      delete altmap;
      altmap = NULL;
    }

    // User defined coordinate system, 8 possible combinations
    // we only have to make changes for some of them.
    // Convert from given system to universal and then set.
    else if(coordsys == "USERDEFINED") {
      double lat2 = lat;
      double lon2 = lon;

      if(ui.GetString("LATTYPE") == "PLANETOGRAPHIC") {
        lat2 = proj->ToPlanetocentric(lat);
  Pvl appLog;
  try {
    mappt(ui, &appLog);
  }

      if(ui.GetString("LONDOM") == "180") {
        lon2 = proj->To360Domain(lon);
  catch (...) {
    for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) {
      Application::Log(*grpIt);
    }

      if(ui.GetString("LONDIR") == "POSITIVEWEST") {
        // Use lon2, we know its already in 0-360
        lon2 = proj->ToPositiveEast(lon2, 360);
      }

      proj->SetUniversalGround(lat2, lon2);
    }
  }

  // Get the x/y position if we have a projection point
  else {
    double x = ui.GetDouble("X");
    double y = ui.GetDouble("Y");
    proj->SetCoordinate(x, y);
    throw;
  }
  
  PvlGroup results("Results");
  if (proj->WorldX() < .5 || proj->WorldY() < .5 || proj->WorldX() > cubeSampleLimit ||
      proj->WorldY() > cubeLineLimit) {
    if (!outsideAllowed) {
      QString error = "Resulting line,sample is not on the image";
      throw IException(IException::Unknown, error, _FILEINFO_);
  for (auto grpIt = appLog.beginGroup(); grpIt!= appLog.endGroup(); grpIt++) {
    Application::Log(*grpIt);
  }
    else {
      results += PvlKeyword("OutsideOfImage", "Requested point falls outside of image boundaries");
}
  }

  // Create Brick on samp, line to get the dn value of the pixel
  Brick b(1, 1, 1, icube->pixelType());
  int intSamp = (int)(proj->WorldX() + 0.5);
  int intLine = (int)(proj->WorldY() + 0.5);
  b.SetBasePosition(intSamp, intLine, 1);
  icube->read(b);

  // Log the position
  if(proj->IsGood()) {
    results += PvlKeyword("Filename",
                          FileName(ui.GetFileName("FROM")).expanded());
    results += PvlKeyword("Sample", toString(proj->WorldX()));
    results += PvlKeyword("Line", toString(proj->WorldY()));
    results += PvlKeyword("PixelValue", PixelToString(b[0]));
    results += PvlKeyword("X", toString(proj->XCoord()));
    results += PvlKeyword("Y", toString(proj->YCoord()));

    // Put together all the keywords for different coordinate systems.
    PvlKeyword centLat =
      PvlKeyword("PlanetocentricLatitude", toString(proj->UniversalLatitude()));

    PvlKeyword graphLat =
      PvlKeyword("PlanetographicLatitude",
                 toString(proj->ToPlanetographic(proj->UniversalLatitude())));

    PvlKeyword pE360 =
      PvlKeyword("PositiveEast360Longitude", toString(proj->UniversalLongitude()));

    PvlKeyword pW360 =
      PvlKeyword("PositiveWest360Longitude",
                 toString(proj->ToPositiveWest(proj->UniversalLongitude(), 360)));

    PvlKeyword pE180 =
      PvlKeyword("PositiveEast180Longitude",
                 toString(proj->To180Domain(proj->UniversalLongitude())));

    PvlKeyword pW180 =
      PvlKeyword("PositiveWest180Longitude",
                 toString(proj->To180Domain(proj->ToPositiveEast(
                            proj->UniversalLongitude(), 360))));

    // Input map coordinate system location
    // Latitude
    if(proj->IsPlanetocentric()) {
      centLat.addComment("Input map coordinate system");
      results += centLat;
    }
    else {
      graphLat.addComment("Input map coordinate system");
      results += graphLat;
    }

    // Longitude
    if(proj->IsPositiveEast()) {
      if(proj->Has360Domain()) {
        results += pE360;
      }
      else {
        results += pE180;
      }
    }
    else {
      if(proj->Has360Domain()) {
        results += pW360;
      }
      else {
        results += pW180;
      }
    }

    // Non input corrdinate system locations
    // Latitude
    if(proj->IsPlanetocentric()) {
      graphLat.addComment("Location in other coordinate systems");
      results += graphLat;
    }
    else {
      centLat.addComment("Location in other coordinate systems");
      results += centLat;
    }

    // Longitude
    if(proj->IsPositiveEast()) {
      if(proj->Has360Domain()) {
        results += pW360;
        results += pE180;
        results += pW180;
      }
      else {
        results += pE360;
        results += pW360;
        results += pW180;
      }
    }
    else {
      if(proj->Has360Domain()) {
        results += pE360;
        results += pE180;
        results += pW180;
      }
      else {
        results += pE360;
        results += pE180;
        results += pW360;
      }
    }
        
    Application::Log(results);

    // Write an output label file if necessary
    if(ui.WasEntered("TO")) {
      // Get user params from ui
      QString outFile = FileName(ui.GetFileName("TO")).expanded();
      bool exists = FileName(outFile).fileExists();
      bool append = ui.GetBoolean("APPEND");

      // Write the pvl group out to the file
      if(ui.GetString("FORMAT") == "PVL") {
        Pvl temp;
        temp.addGroup(results);
        if(append) {
          temp.append(outFile);
        }
        else {
          temp.write(outFile);
        }
      }

      // Create a flatfile of the same data
      // The flatfile is comma delimited and can be imported into Excel
      else {
        ofstream os;
        bool writeHeader = false;
        if(append) {
          os.open(outFile.toLatin1().data(), ios::app);
          if(!exists) {
            writeHeader = true;
          }
        }
        else {
          os.open(outFile.toLatin1().data(), ios::out);
          writeHeader = true;
        }

        // Rearrange the order of the lat/lons for the csv
        results.deleteKeyword( pE360.name() );
        results.deleteKeyword( pE180.name() );
        results.deleteKeyword( pW360.name() );
        results.deleteKeyword( pW180.name() );
        results.deleteKeyword( centLat.name() );
        results.deleteKeyword( graphLat.name() );
        //Correct order.
        results += centLat;
        results += graphLat;
        results += pE360;
        results += pE180;
        results += pW360;
        results += pW180;

        if(writeHeader) {
          for(int i = 0; i < results.keywords(); i++) {
            os << results[i].name();

            if(i < results.keywords() - 1) {
              os << ",";
            }
          }
          os << endl;
        }

        for(int i = 0; i < results.keywords(); i++) {
          os << (QString)results[i];

          if(i < results.keywords() - 1) {
            os << ",";
          }
        }
        os << endl;
      }
    }
    else if(ui.GetString("FORMAT") == "FLAT") {
      QString msg = "Flat file must have a name.";
      throw IException(IException::User, msg, _FILEINFO_);
    }
  }
  else {
    QString msg = "Could not project requested position";
    throw IException(IException::Unknown, msg, _FILEINFO_);
  }
}

// Helper function to print out mapfile to session log
void PrintMap() {
+356 −0
Original line number Diff line number Diff line
#include <QString>
#include <cmath>

#include "Brick.h"
#include "FileName.h"
#include "IException.h"
#include "IString.h"
#include "Process.h"
#include "TProjection.h"
#include "ProjectionFactory.h"
#include "SpecialPixel.h"

#include "mappt.h"

using namespace std;

namespace Isis {
void mappt(UserInterface &ui, Pvl *log) {
  Cube *cube = new Cube();
  CubeAttributeInput inAtt = ui.GetInputAttribute("FROM");

  if (inAtt.bands().size() != 0) {
    cube->setVirtualBands(inAtt.bands());
  }
  
  cube->open(ui.GetFileName("FROM"), "r");
  mappt(cube, ui, log, &inAtt);
}

void mappt(Cube *icube, UserInterface &ui, Pvl *log, CubeAttributeInput* inAtt) {
  // Open the input cube and initialize the projection
  TProjection *proj = (TProjection *) icube->projection();


  // Get the coordinate
  bool outsideAllowed = ui.GetBoolean("ALLOWOUTSIDE");
  int cubeLineLimit = icube->lineCount() + .5;
  int cubeSampleLimit = icube->sampleCount() + .5;

  // Get the sample/line position if we have an image point
  if(ui.GetString("TYPE") == "IMAGE") {
    double samp = ui.GetDouble("SAMPLE");
    double line = ui.GetDouble("LINE");

    if (!outsideAllowed) {
      if (samp < .5 || line < .5 || samp > cubeSampleLimit || line > cubeLineLimit) {
        QString error = "Requested line,sample is not on the image";
        throw IException(IException::Unknown, error, _FILEINFO_);
      }
    }
    proj->SetWorld(samp, line);
  }

  // Get the lat/lon position if we have a ground point
  else if(ui.GetString("TYPE") == "GROUND") {
    double lat = ui.GetDouble("LATITUDE");
    double lon = ui.GetDouble("LONGITUDE");

    // Make sure we have a valid latitude value
    if(fabs(lat) > 90.0) {
      QString msg = "Invalid value for LATITUDE ["
                   + toString(lat) + "] outside range of ";
      msg += "[-90,90]";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    IString coordsys = ui.GetString("COORDSYS");
    coordsys.UpCase();

    // All of these ifs will finish by setting the ground in the projection,
    // there are 4 options, Universal, InputFileSystem, Mapfile, and
    // Userdefined.

    // Positive East, 0-360, Planetocentric
    if(coordsys == "UNIVERSAL") {
      proj->SetUniversalGround(lat, lon);
    }

    // Use the coordinate system of the input file
    else if(coordsys == "INPUTFILESYS") {
      proj->SetGround(lat, lon);
    }

    // Use the mapping group from a given file
    else if(coordsys == "MAP") {
      FileName mapFile = ui.GetFileName("MAP");

      // Does it exist?
      if(!mapFile.fileExists()) {
        QString msg = "Filename [" + ui.GetFileName("MAP") + "] does not exist";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      // Load it up into a new projection
      Pvl mapPvl;
      mapPvl.read(mapFile.expanded());
      TProjection *altmap = (TProjection *) ProjectionFactory::CreateFromCube(mapPvl);

      // Set lat and lon in its system
      altmap->SetGround(lat, lon);

      // Set universal in input cube from universal from given
      // mapping/projection
      proj->SetUniversalGround(
        altmap->UniversalLatitude(), altmap->UniversalLongitude());

      // I think this is right, no cube owns it, and the factory doesn't.
      delete altmap;
      altmap = NULL;
    }

    // User defined coordinate system, 8 possible combinations
    // we only have to make changes for some of them.
    // Convert from given system to universal and then set.
    else if(coordsys == "USERDEFINED") {
      double lat2 = lat;
      double lon2 = lon;

      if(ui.GetString("LATTYPE") == "PLANETOGRAPHIC") {
        lat2 = proj->ToPlanetocentric(lat);
      }

      if(ui.GetString("LONDOM") == "180") {
        lon2 = proj->To360Domain(lon);
      }

      if(ui.GetString("LONDIR") == "POSITIVEWEST") {
        // Use lon2, we know its already in 0-360
        lon2 = proj->ToPositiveEast(lon2, 360);
      }

      proj->SetUniversalGround(lat2, lon2);
    }
  }

  // Get the x/y position if we have a projection point
  else {
    double x = ui.GetDouble("X");
    double y = ui.GetDouble("Y");
    proj->SetCoordinate(x, y);
  }

  PvlGroup results("Results");
  if (proj->WorldX() < .5 || proj->WorldY() < .5 || proj->WorldX() > cubeSampleLimit ||
      proj->WorldY() > cubeLineLimit) {
    if (!outsideAllowed) {
      QString error = "Resulting line,sample is not on the image";
      throw IException(IException::Unknown, error, _FILEINFO_);
    }
    else {
      results += PvlKeyword("OutsideOfImage", "Requested point falls outside of image boundaries");
    }
  }

  // Create Brick on samp, line to get the dn value of the pixel
  Brick b(1, 1, 1, icube->pixelType());
  int intSamp = (int)(proj->WorldX() + 0.5);
  int intLine = (int)(proj->WorldY() + 0.5);
  
  b.SetBasePosition(intSamp, intLine, 1);
  icube->read(b);
  
  QString filterName = "Null";
  PvlGroup bandBin = icube->label()->findObject("IsisCube").findGroup("BandBin");
  if (bandBin.hasKeyword("FilterName")) {
      filterName = bandBin.findKeyword("FilterName")[0];
  }

  // Log the position
  if(proj->IsGood()) {
    results += PvlKeyword("Filename",
                          FileName(icube->fileName()).expanded());
    results += PvlKeyword("Sample", toString(proj->WorldX()));
    results += PvlKeyword("Line", toString(proj->WorldY()));
    results += PvlKeyword("Band", toString(icube->physicalBand(1)));
    results += PvlKeyword("FilterName", filterName);
    results += PvlKeyword("PixelValue", PixelToString(b[0]));
    results += PvlKeyword("X", toString(proj->XCoord()));
    results += PvlKeyword("Y", toString(proj->YCoord()));

    // Put together all the keywords for different coordinate systems.
    PvlKeyword centLat =
      PvlKeyword("PlanetocentricLatitude", toString(proj->UniversalLatitude()));

    PvlKeyword graphLat =
      PvlKeyword("PlanetographicLatitude",
                 toString(proj->ToPlanetographic(proj->UniversalLatitude())));

    PvlKeyword pE360 =
      PvlKeyword("PositiveEast360Longitude", toString(proj->UniversalLongitude()));

    PvlKeyword pW360 =
      PvlKeyword("PositiveWest360Longitude",
                 toString(proj->ToPositiveWest(proj->UniversalLongitude(), 360)));

    PvlKeyword pE180 =
      PvlKeyword("PositiveEast180Longitude",
                 toString(proj->To180Domain(proj->UniversalLongitude())));

    PvlKeyword pW180 =
      PvlKeyword("PositiveWest180Longitude",
                 toString(proj->To180Domain(proj->ToPositiveEast(
                            proj->UniversalLongitude(), 360))));

    // Input map coordinate system location
    // Latitude
    if(proj->IsPlanetocentric()) {
      centLat.addComment("Input map coordinate system");
      results += centLat;
    }
    else {
      graphLat.addComment("Input map coordinate system");
      results += graphLat;
    }

    // Longitude
    if(proj->IsPositiveEast()) {
      if(proj->Has360Domain()) {
        results += pE360;
      }
      else {
        results += pE180;
      }
    }
    else {
      if(proj->Has360Domain()) {
        results += pW360;
      }
      else {
        results += pW180;
      }
    }

    // Non input corrdinate system locations
    // Latitude
    if(proj->IsPlanetocentric()) {
      graphLat.addComment("Location in other coordinate systems");
      results += graphLat;
    }
    else {
      centLat.addComment("Location in other coordinate systems");
      results += centLat;
    }

    // Longitude
    if(proj->IsPositiveEast()) {
      if(proj->Has360Domain()) {
        results += pW360;
        results += pE180;
        results += pW180;
      }
      else {
        results += pE360;
        results += pW360;
        results += pW180;
      }
    }
    else {
      if(proj->Has360Domain()) {
        results += pE360;
        results += pE180;
        results += pW180;
      }
      else {
        results += pE360;
        results += pE180;
        results += pW360;
      }
    }
    
    if (log) {
      log->addGroup(results);
    }

    // Write an output label file if necessary
    if(ui.WasEntered("TO")) {
      // Get user params from ui
      QString outFile = FileName(ui.GetFileName("TO")).expanded();
      bool exists = FileName(outFile).fileExists();
      bool append = ui.GetBoolean("APPEND");

      // Write the pvl group out to the file
      if(ui.GetString("FORMAT") == "PVL") {
        Pvl temp;
        temp.addGroup(results);
        if(append) {
          temp.append(outFile);
        }
        else {
          temp.write(outFile);
        }
      }

      // Create a flatfile of the same data
      // The flatfile is comma delimited and can be imported into Excel
      else {
        ofstream os;
        bool writeHeader = false;
        if(append) {
          os.open(outFile.toLatin1().data(), ios::app);
          if(!exists) {
            writeHeader = true;
          }
        }
        else {
          os.open(outFile.toLatin1().data(), ios::out);
          writeHeader = true;
        }

        // Rearrange the order of the lat/lons for the csv
        results.deleteKeyword( pE360.name() );
        results.deleteKeyword( pE180.name() );
        results.deleteKeyword( pW360.name() );
        results.deleteKeyword( pW180.name() );
        results.deleteKeyword( centLat.name() );
        results.deleteKeyword( graphLat.name() );
        //Correct order.
        results += centLat;
        results += graphLat;
        results += pE360;
        results += pE180;
        results += pW360;
        results += pW180;

        if(writeHeader) {
          for(int i = 0; i < results.keywords(); i++) {
            os << results[i].name();

            if(i < results.keywords() - 1) {
              os << ",";
            }
          }
          os << endl;
        }

        for(int i = 0; i < results.keywords(); i++) {
          os << (QString)results[i];

          if(i < results.keywords() - 1) {
            os << ",";
          }
        }
        os << endl;
      }
    }
    else if(ui.GetString("FORMAT") == "FLAT") {
      QString msg = "Flat file must have a name.";
      throw IException(IException::User, msg, _FILEINFO_);
    }
  }
  else {
    QString msg = "Could not project requested position";
    throw IException(IException::Unknown, msg, _FILEINFO_);
  }
}
}
+12 −0
Original line number Diff line number Diff line
#ifndef campt_h
#define campt_h

#include "Pvl.h"
#include "UserInterface.h"

namespace Isis{
  extern void mappt(Cube *cube, UserInterface &ui, Pvl *log=nullptr, CubeAttributeInput* inAtt = nullptr);
  extern void mappt(UserInterface &ui, Pvl *log= nullptr);
}

#endif
+0 −4
Original line number Diff line number Diff line
BLANKS = "%-6s"    
LENGTH = "%-40s"

include $(ISISROOT)/make/isismake.tststree
+0 −10
Original line number Diff line number Diff line
APPNAME = mappt

include $(ISISROOT)/make/isismake.tsts

commands:
	$(APPNAME) from=$(INPUT)/mola_clon0.cub \
	  append=false \
	  type=ground \
	  latitude=17 \
	  longitude=10 > $(OUTPUT)/mappt.pvl;
Loading