コード例 #1
0
ファイル: Latitude.cpp プロジェクト: jlaura/isis3
  /**
   * Checks if this latitude value is within the given range.  Defines the
   * range as the change from the minimum latitude to the maximum latitude (an
   * angle), and returns whether the change from the minimum latitude to this
   * latitude is less than or equal to the maximum change allowed (the range).
   *
   * @param min The beginning of the valid latitude range
   * @param max The end of the valid latitude range
   *
   * @return Whether the latitude is in the given range
   */
  bool Latitude::inRange(Latitude min, Latitude max) const {
    // Validity check on the range
    if (min > max) {
      IString msg = "Minimum latitude [" + IString(min.degrees()) +
        "] degrees is greater than maximum latitude [" +
        IString(max.degrees()) + "] degrees";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // Provide a little wriggle room for precision problems
    Angle epsilon(DBL_EPSILON, Angle::Degrees);
    Latitude adjustedMin = min - epsilon;
    Latitude adjustedMax = max + epsilon;

    // Is this latitude between the min and the max
    return *this >= adjustedMin && *this <= adjustedMax;
  }
コード例 #2
0
ファイル: deltack.cpp プロジェクト: jlaura/isis3
// Compute the radius at the lat/lon
Distance GetRadius(QString filename, Latitude lat, Longitude lon) {
  Cube cube(filename, "r");
  Sensor sensor(cube);
  sensor.SetGround(SurfacePoint(lat, lon, sensor.LocalRadius(lat, lon)));
  Distance radius = sensor.LocalRadius();
  if(!radius.isValid()) {
    QString msg = "Could not determine radius from DEM at lat/lon [";
    msg += toString(lat.degrees()) + "," + toString(lon.degrees()) + "]";
    throw IException(IException::Unknown, msg, _FILEINFO_);
  }
  return radius;
}
コード例 #3
0
ファイル: UniversalGroundMap.cpp プロジェクト: jlaura/isis3
 /**
  * Returns whether the lat/lon position was set successfully in the camera
  * model or projection.
  *
  * @param lat The universal latitude or ring radius for ring planes
  * @param lon The universal longitude or ring longitude (azimuth) for ring planes
  *
  * @return Returns true if the lat/lon position was set successfully, and
  *         false if it was not
  */
 bool UniversalGroundMap::SetGround(Latitude lat, Longitude lon) {
   if(p_camera != NULL) {
     if(p_camera->SetGround(lat, lon)) {  // This should work for rings (radius,azimuth)
       return p_camera->InCube();
     }
     else {
       return false;
     }
   }
   else {
     double universalLat = lat.degrees();
     double universalLon = lon.degrees();
     return p_projection->SetUniversalGround(universalLat, universalLon);  // This should work for rings (radius,azimuth)
   }
 }
コード例 #4
0
ファイル: VimsGroundMap.cpp プロジェクト: jlaura/isis3
  /** Compute undistorted focal plane coordinate from ground position
   *
   * @param lat Planetocentric latitude in degrees
   * @param lon Planetocentric longitude in degrees
   *
   * @return @b bool Indicates whether the conversion was successful
   *
   * @internal
   * @history 2007-04-18  Tracie Sucharski - Added check for reasonable
   *                             match when attempting to find closest
   *                             lat/lon in map arrays.
   * @history 2007-09-14  Tracie Sucharski - Added check for longitude
   *                             outside min/max bounds.  Don't know why
   *                             this wasn't put in before (lat check was
   *                             in), was it oversight, or did I take it out
   *                             for some reason???
   * @history 2007-12-14  Tracie Sucharski - Remove resolution test, too
   *                            image dependent and the resolution for vims is
   *                            incorrect due to the instrument having
   *                            rectangular pixels.
   * @history 2008-01-02  Tracie Sucharski -  Check validity of resulting
   *                            sample and line against edge of starting
   *                            ending pixels (0.5/Parent+0.5) instead of
   *                            center of pixels.
   * @history 2012-12-03  Tracie Sucharski - Check for valid minLat/maxLat, minLon/maxLon.  If 
   *                            none are valid, this means the latMap and lonMap have no valid
   *                            data, therefore we cannot back project, so return false.
   *
   */
  bool VimsGroundMap::SetGround(const Latitude &lat, const Longitude &lon) {

    QVector3D xyz;
    if (p_camera->target()->shape()->name() == "Plane") {
        double radius = lat.degrees();
        if(radius <= 0.0)
          return false;

        double xCheck = radius * 0.001 * cos(lon.radians());
        double yCheck = radius * 0.001 * sin(lon.radians());

        xyz.setX(xCheck);
        xyz.setY(yCheck);
        xyz.setZ(0.);
      }
    else {
        //  Convert lat/lon to x/y/z
        Distance radius = p_camera->LocalRadius(lat, lon);
        SpiceDouble pB[3];
        latrec_c(radius.kilometers(), lon.radians(), lat.radians(), pB);

        xyz.setX(pB[0]);
        xyz.setY(pB[1]);
        xyz.setZ(pB[2]);
    }

    double minDist = DBL_MAX;
    int minSamp = -1;
    int minLine = -1;

    //  Find closest points  ??? what tolerance ???
    for (int line = 0; line < p_camera->ParentLines(); line++) {
      for (int samp = 0; samp < p_camera->ParentSamples(); samp++) {

        if (p_xyzMap[line][samp].isNull()) continue;

        //  Subtract map from coordinate then get length
        QVector3D deltaXyz = xyz - p_xyzMap[line][samp];
        if (deltaXyz.length() < minDist) {
          minDist = deltaXyz.length();
          minSamp = samp;
          minLine = line;
        }
      }
    }

    //-----------------------------------------------------------------
    //  If dist is less than some ??? tolerance ??? this is the
    //  closest point.  Use this point and surrounding 8 pts as
    //  control pts.
    //----------------------------------------------------------------
    if (minDist >= DBL_MAX) return false;

    //-------------------------------------------------------------
    //  Set-up for LU decomposition (least2 fit).
    //  Assume we will have 9 control points, this may not be true
    //  and will need to be adjusted before the final solution.
    //-------------------------------------------------------------
    BasisFunction sampXyzBasis("Sample", 4, 4);
    BasisFunction lineXyzBasis("Line", 4, 4);
    LeastSquares sampXyzLsq(sampXyzBasis);
    LeastSquares lineXyzLsq(lineXyzBasis);
    vector<double> knownXyz(4);

    //  Solve using x/y/z
    for (int line = minLine - 1; line < minLine + 2; line++) {
      if (line < 0 || line > p_camera->ParentLines() - 1) continue;
      for (int samp = minSamp - 1; samp < minSamp + 2; samp++) {
        //  Check for edges
        if (samp < 0 || samp > p_camera->ParentSamples() - 1) continue;
        if (p_xyzMap[line][samp].isNull()) continue;

        knownXyz[0] = p_xyzMap[line][samp].x();
        knownXyz[1] = p_xyzMap[line][samp].y();
        knownXyz[2] = p_xyzMap[line][samp].z();
        knownXyz[3] = 1;
        sampXyzLsq.AddKnown(knownXyz, samp + 1);
        lineXyzLsq.AddKnown(knownXyz, line + 1);
      }
    }

    if (sampXyzLsq.Knowns() < 4) return false;

    sampXyzLsq.Solve();
    lineXyzLsq.Solve();

    //  Solve for sample, line position corresponding to input lat, lon
    knownXyz[0] = xyz.x();
    knownXyz[1] = xyz.y();
    knownXyz[2] = xyz.z();
    knownXyz[3] = 1;
    double inSamp = sampXyzLsq.Evaluate(knownXyz);
    double inLine = lineXyzLsq.Evaluate(knownXyz);


    if (inSamp < 0.5 || inSamp > p_camera->ParentSamples() + 0.5 ||
        inLine < 0.5 || inLine > p_camera->ParentLines() + 0.5) {
      return false;
    }

    p_camera->IgnoreProjection(true);
    p_camera->SetImage(inSamp, inLine);
    p_camera->IgnoreProjection(false);
    if (!p_camera->HasSurfaceIntersection()) return false;

    p_focalPlaneX = inSamp;
    p_focalPlaneY = inLine;

    return true;
  }
コード例 #5
0
ファイル: cnetadd.cpp プロジェクト: corburn/ISIS
void IsisMain() {

  UserInterface &ui = Application::GetUserInterface();

  FileList addList(ui.GetFileName("ADDLIST"));

  bool log = false;
  FileName logFile;
  if (ui.WasEntered("LOG")) {
    log = true;
    logFile = ui.GetFileName("LOG");
  }
  Pvl results;
  results.setName("cnetadd_Results");
  PvlKeyword added("FilesAdded");
  PvlKeyword omitted("FilesOmitted");
  PvlKeyword pointsModified("PointsModified");

  bool checkMeasureValidity = ui.WasEntered("DEFFILE");
  ControlNetValidMeasure validator;
  if (checkMeasureValidity) {
    Pvl deffile(ui.GetFileName("DEFFILE"));
    validator = ControlNetValidMeasure(deffile);
  }

  SerialNumberList *fromSerials = ui.WasEntered("FROMLIST") ?
    new SerialNumberList(ui.GetFileName("FROMLIST")) : new SerialNumberList();

  ControlNet inNet = ControlNet(ui.GetFileName("CNET"));
  inNet.SetUserName(Application::UserName());
  inNet.SetModifiedDate(iTime::CurrentLocalTime()); //This should be done in ControlNet's Write fn

  QString retrievalOpt = ui.GetString("RETRIEVAL");
  PvlKeyword duplicates("DupSerialNumbers");
  if (retrievalOpt == "REFERENCE") {
    FileList list1(ui.GetFileName("FROMLIST"));
    SerialNumberList addSerials(ui.GetFileName("ADDLIST"));

    //Check for duplicate files in the lists by serial number
    for (int i = 0; i < addSerials.Size(); i++) {

      // Check for duplicate SNs accross the lists
      if (fromSerials->HasSerialNumber(addSerials.SerialNumber(i))) {
        duplicates.addValue(addSerials.FileName(i));
      }

      // Check for duplicate SNs within the addlist
      for (int j = i + 1; j < addSerials.Size(); j++) {
        if (addSerials.SerialNumber(i) == addSerials.SerialNumber(j)) {
          QString msg = "Add list files [" + addSerials.FileName(i) + "] and [";
          msg += addSerials.FileName(j) + "] share the same serial number.";
          throw IException(IException::User, msg, _FILEINFO_);
        }
      }
    }

    // Get the lat/long coords from the existing reference measure
    setControlPointLatLon(*fromSerials, inNet);
  }
  else {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      // Get the surface point from the current control point
      ControlPoint *point = inNet.GetPoint(cp);
      SurfacePoint surfacePoint = point->GetBestSurfacePoint();

      if (!surfacePoint.Valid()) {
        QString msg = "Unable to retreive lat/lon from Control Point [";
        msg += point->GetId() + "]. RETREIVAL=POINT cannot be used unless ";
        msg += "all Control Points have Latitude/Longitude keywords.";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      g_surfacePoints[point->GetId()] = surfacePoint;
    }
  }

  FileName outNetFile(ui.GetFileName("ONET"));

  Progress progress;
  progress.SetText("Adding Images");
  progress.SetMaximumSteps(addList.size());
  progress.CheckStatus();

  STRtree coordTree;
  QList<ControlPoint *> pointList;
  bool usePolygon = ui.GetBoolean("POLYGON");
  if (usePolygon) {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      ControlPoint *point = inNet.GetPoint(cp);
      SurfacePoint surfacePoint = g_surfacePoints[point->GetId()];

      Longitude lon = surfacePoint.GetLongitude();
      Latitude lat = surfacePoint.GetLatitude();

      Coordinate *coord = new Coordinate(lon.degrees(), lat.degrees());
      Envelope *envelope = new Envelope(*coord);
      coordTree.insert(envelope, point);
    }
  }
  else {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      pointList.append(inNet.GetPoint(cp));
    }
  }

  // Loop through all the images
  for (int img = 0; img < addList.size(); img++) {
    Cube cube;
    cube.open(addList[img].toString());
    Pvl *cubepvl = cube.label();
    QString sn = SerialNumber::Compose(*cubepvl);
    Camera *cam = cube.camera();

    // Loop through all the control points
    QList<ControlPoint *> validPoints = usePolygon ?
        getValidPoints(cube, coordTree) : pointList;

    bool imageAdded = false;
    for (int cp = 0; cp < validPoints.size(); cp++) {
      ControlPoint *point = validPoints[cp];

      // If the point is locked and Apriori source is "AverageOfMeasures"
      // then do not add the measures.
      if (point->IsEditLocked() &&
          point->GetAprioriSurfacePointSource() ==
              ControlPoint::SurfacePointSource::AverageOfMeasures) {
        continue;
      }

      if (point->HasSerialNumber(sn)) continue;

      // Only use the surface point's latitude and longitude, rely on the DEM
      // for computing the radius.  We do this because otherwise we will receive
      // inconsistent results from successive runs of this program if the
      // different DEMs are used, or the point X, Y, Z was generated from the
      // ellipsoid.
      SurfacePoint surfacePoint = g_surfacePoints[point->GetId()];
      if (cam->SetGround(
              surfacePoint.GetLatitude(), surfacePoint.GetLongitude())) {

        // Make sure the samp & line are inside the image
        if (cam->InCube()) {
          ControlMeasure *newCm = new ControlMeasure();
          newCm->SetCoordinate(cam->Sample(), cam->Line(), ControlMeasure::Candidate);
          newCm->SetAprioriSample(cam->Sample());
          newCm->SetAprioriLine(cam->Line());
          newCm->SetCubeSerialNumber(sn);
          newCm->SetDateTime();
          newCm->SetChooserName("Application cnetadd");

          // Check the measure for DEFFILE validity
          if (checkMeasureValidity) {
            if (!validator.ValidEmissionAngle(cam->EmissionAngle())) {
              //TODO: log that it was Emission Angle that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.ValidIncidenceAngle(cam->IncidenceAngle())) {
              //TODO: log that it was Incidence Angle that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.ValidResolution(cam->resolution())) {
              //TODO: log that it was Resolution that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.PixelsFromEdge((int)cam->Sample(), (int)cam->Line(), &cube)) {
              //TODO: log that it was Pixels from Edge that failed the check
              newCm->SetIgnored(true);
            }
            else {
              Portal portal(1, 1, cube.pixelType());
              portal.SetPosition(cam->Sample(), cam->Line(), 1);
              cube.read(portal);
              if (!validator.ValidDnValue(portal[0])) {
                //TODO: log that it was DN that failed the check
                newCm->SetIgnored(true);
              }
            }
          }

          point->Add(newCm); // Point takes ownership

          // Record the modified Point and Measure
          g_modifications[point->GetId()].insert(newCm->GetCubeSerialNumber());
          newCm = NULL; // Do not delete because the point has ownership

          if (retrievalOpt == "POINT" && point->GetNumMeasures() == 1)
            point->SetIgnored(false);

          imageAdded = true;
        }
      }
    }

    cubepvl = NULL;
    cam = NULL;

    if (log) {
      PvlKeyword &logKeyword = (imageAdded) ? added : omitted;
      logKeyword.addValue(addList[img].baseName());
    }

    progress.CheckStatus();
  }

  if (log) {
    // Add the list of modified points to the output log file
    QList<QString> modifiedPointsList = g_modifications.keys();
    for (int i = 0; i < modifiedPointsList.size(); i++)
      pointsModified += modifiedPointsList[i];

    results.addKeyword(added);
    results.addKeyword(omitted);
    results.addKeyword(pointsModified);
    if (duplicates.size() > 0) {
      results.addKeyword(duplicates);
    }

    results.write(logFile.expanded());
  }

  // List the modified points
  if (ui.WasEntered("MODIFIEDPOINTS")) {
    FileName pointList(ui.GetFileName("MODIFIEDPOINTS"));

    // Set up the output file for writing
    std::ofstream out_stream;
    out_stream.open(pointList.expanded().toAscii().data(), std::ios::out);
    out_stream.seekp(0, std::ios::beg);   //Start writing from beginning of file

    QList<QString> modifiedPointsList = g_modifications.keys();
    for (int i = 0; i < modifiedPointsList.size(); i++)
      out_stream << modifiedPointsList[i].toStdString() << std::endl;

    out_stream.close();
  }

  // Modify the inNet to only have modified points/measures
  if (ui.GetString("EXTRACT") == "MODIFIED") {
    for (int cp = inNet.GetNumPoints() - 1; cp >= 0; cp--) {
      ControlPoint *point = inNet.GetPoint(cp);

      // If the point was not modified, delete
      // Even get rid of edit locked points in this case
      if (!g_modifications.contains(point->GetId())) {
        point->SetEditLock(false);
        inNet.DeletePoint(cp);
      }
      // Else, remove the unwanted measures from the modified point
      else {
        for (int cm = point->GetNumMeasures() - 1; cm >= 0; cm--) {
          ControlMeasure *measure = point->GetMeasure(cm);

          // Even get rid of edit locked measures in this case
          if (point->GetRefMeasure() != measure &&
              !g_modifications[point->GetId()].contains(
                  measure->GetCubeSerialNumber())) {
            measure->SetEditLock(false);
            point->Delete(cm);
          }
        }
      }
    }
  }

  // Generate the TOLIST if wanted
  if (ui.WasEntered("TOLIST")) {
    SerialNumberList toList;

    SerialNumberList addSerials(ui.GetFileName("ADDLIST"));

    const QList<QString> snList = inNet.GetCubeSerials();
    for (int i = 0; i < snList.size(); i++) {
      QString sn = snList[i];

      if (addSerials.HasSerialNumber(sn))
        toList.Add(addSerials.FileName(sn));
      else if (fromSerials->HasSerialNumber(sn))
        toList.Add(fromSerials->FileName(sn));
    }

    IString name(ui.GetFileName("TOLIST"));
    std::fstream out_stream;
    out_stream.open(name.c_str(), std::ios::out);
    out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file

    for (int f = 0; f < (int) toList.Size(); f++)
      out_stream << toList.FileName(f) << std::endl;

    out_stream.close();
  }

  inNet.Write(outNetFile.expanded());

  delete fromSerials;
}