Unverified Commit 8c8df01c authored by acpaquette's avatar acpaquette Committed by GitHub
Browse files

Phocube Slope and Normal Calculations (#4605)



* First pass at slope in phocube

* Added slope and azimuth cals to phocube.cpp

* Added local normal and ellipsoid normal back plan calculations to phocube

* Force pulled upstream new phocube main.cpp

* Removed unused includes and moved a few lines around

* Fixed up the includes one more time

* Updated phocube docs based on PR feedback

* Added changelog entry

Co-authored-by: default avatarJesse Mapel <jmapel@usgs.gov>
parent 228a5423
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ release.

### Added
- Added the ability to search filenames in measure's drop down boxes in Qnet Point Editor. [#4581](https://github.com/USGS-Astrogeology/ISIS3/issues/4581)
- Added slope, local normal, and ellipsoid normal calculations to phocube. [#3635](https://github.com/USGS-Astrogeology/ISIS3/issues/3645)

## [6.0.0] - 2021-08-27

+86 −6
Original line number Diff line number Diff line
@@ -5,10 +5,12 @@
#include "Cube.h"
#include "FileName.h"
#include "IException.h"
#include "LinearAlgebra.h"
#include "ProjectionFactory.h"
#include "ProcessByBrick.h"
#include "ProcessByLine.h"
#include "SpecialPixel.h"
#include "Target.h"
#include "TProjection.h"

#include <cmath>
@@ -85,6 +87,9 @@ namespace Isis {
    bool phase = false;
    bool emission = false;
    bool incidence = false;
    bool ellipsoidNormal = false;
    bool localNormal = false;
    bool slope = false;
    bool localEmission = false;
    bool localIncidence = false;
    bool lineResolution = false;
@@ -120,6 +125,9 @@ namespace Isis {
      if ((sunAzimuth = ui.GetBoolean("SUNAZIMUTH"))) nbands++;
      if ((spacecraftAzimuth = ui.GetBoolean("SPACECRAFTAZIMUTH"))) nbands++;
      if ((offnadirAngle = ui.GetBoolean("OFFNADIRANGLE"))) nbands++;
      if ((slope = ui.GetBoolean("SLOPE"))) nbands++;
      if ((localNormal = ui.GetBoolean("LOCALNORMAL"))) nbands = nbands + 3;
      if ((ellipsoidNormal = ui.GetBoolean("ELLIPSOIDNORMAL"))) nbands = nbands + 3;
      if ((subSpacecraftGroundAzimuth = ui.GetBoolean("SUBSPACECRAFTGROUNDAZIMUTH"))) nbands++;
      if ((subSolarGroundAzimuth = ui.GetBoolean("SUBSOLARGROUNDAZIMUTH"))) nbands++;
      if ((morphologyRank = ui.GetBoolean("MORPHOLOGYRANK"))) nbands++;
@@ -182,6 +190,30 @@ namespace Isis {
      name += "Incidence Angle";
      raBandNum++;
    }
    if (ellipsoidNormal) {
      name += "Ellipsoid Normal X";
      raBandNum++;

      name += "Ellipsoid Normal Y";
      raBandNum++;

      name += "Ellipsoid Normal Z";
      raBandNum++;
    }
    if (localNormal) {
      name += "Local Normal X";
      raBandNum++;

      name += "Local Normal Y";
      raBandNum++;

      name += "Local Normal Z";
      raBandNum++;
    }
    if (slope) {
      name += "Slope";
      raBandNum++;
    }
    if (localEmission) {
      name += "Local Emission Angle";
      raBandNum++;
@@ -327,6 +359,23 @@ namespace Isis {
              out[index] = cam->IncidenceAngle();
              index += 64 * 64;
            }
            if (ellipsoidNormal) {
              ShapeModel *shapeModel = cam->target()->shape();
              std::vector<double> ellipsoidNormal = shapeModel->normal();

              LinearAlgebra::Vector ellipsoidNormalXYZ = LinearAlgebra::vector(ellipsoidNormal[0], ellipsoidNormal[1], ellipsoidNormal[2]);
              ellipsoidNormalXYZ = LinearAlgebra::normalize(ellipsoidNormalXYZ);

              // Generate X, Y, and Z back plan
              out[index] = ellipsoidNormalXYZ[0];
              index += 64 * 64;

              out[index] = ellipsoidNormalXYZ[1];
              index += 64 * 64;

              out[index] = ellipsoidNormalXYZ[2];
              index += 64 * 64;
            }
            if (localEmission || localIncidence) {
              Angle phase;
              Angle incidence;
@@ -344,6 +393,37 @@ namespace Isis {
                index += 64 * 64;
              }
            }
            // This if block sets the normal within the camera/shapemodel to the
            // local normal, any code that needs the ellipsoid normal should be
            // placed before this if block
            if (localNormal) {
              double localNormal[3];
              cam->GetLocalNormal(localNormal);
              LinearAlgebra::Vector localNormalXYZ = LinearAlgebra::vector(localNormal[0], localNormal[1], localNormal[2]);
              localNormalXYZ = LinearAlgebra::normalize(localNormalXYZ);

              // Generate X, Y, and Z back plan
              out[index] = localNormalXYZ[0];
              index += 64 * 64;

              out[index] = localNormalXYZ[1];
              index += 64 * 64;

              out[index] = localNormalXYZ[2];
              index += 64 * 64;
            }
            if (slope) {
              double slope;
              bool success;
              cam->Slope(slope, success);
              if (success) {
                out[index] = slope;
              }
              else {
                out[index] = Isis::Null;
              }
              index += 64 * 64;
            }
            if (latitude) {
              if (noCamera) {
                out[index] = proj->UniversalLatitude();
+239 −175
Original line number Diff line number Diff line
@@ -319,6 +319,10 @@ xsi:noNamespaceSchemaLocation=
    <change name="Kaitlyn Lee" date="2020-03-15">
      Converted application and tests for Gtest conversion.
    </change>
    <change name="Adam Paquette" date="2020-08-23">
      Added initial slope and backplane options for the local normal and the
      ellipsoid normal.
    </change>
  </history>

  <category>
@@ -633,6 +637,66 @@ xsi:noNamespaceSchemaLocation=
          in degrees.
        </description>
      </parameter>
      <parameter name="SLOPE">
        <type>boolean</type>
        <default><item>FALSE</item></default>
        <brief>Create a slope band</brief>
        <description>
          If this parameter is true, the slope will be computed for every pixel
          and placed in a band in the output cube. The output cube labels will
          contain "Slope" in the BandBin group, in band sequence of the output
          file. The slope is in degrees with 0 degrees being perfectly flat and
          90 degrees being sheer vertical.

          <p>
            Note: The slope is measured relative to a sphere and not a more
            complex datum like the gravity model
          </p>

          If computing slopes, the input image must be a level1 image. To
          compute slopes for a level2 DEM use
          <a href="../slpmap/slpmap.html" target="_blank">slpmap</a>.
        </description>
      </parameter>
      <parameter name="LOCALNORMAL">
        <type>boolean</type>
        <default><item>FALSE</item></default>
        <brief>
          Create X, Y, and Z back planes from the local normal vector
        </brief>
        <description>
          If this parameter is true, a local normal will be computed for
          every pixel based on the shapemodel of the cube, and placed in
          three bands (X, Y, Z) in the output cube. Meaning if your cube has an
          ellipsoid shapemodel rather than a DEM, the local normal and the
          ellipsoid normal will look the same. The output cube labels will contain
          three "Local Normal (coord)" keywordsin the BandBin group, in band
          sequence of the output file.

          <p>
            Note: These X, Y, and Z bands are in the body fixed reference frame.
          </p>
        </description>
      </parameter>
      <parameter name="ELLIPSOIDNORMAL">
        <type>boolean</type>
        <default><item>FALSE</item></default>
        <brief>
          Create X, Y, and Z back planes from the ellipsoid normal vector
        </brief>
        <description>
          If this parameter is true, the ellipsoid normal will be computed for
          every pixel and placed in three bands (X, Y, Z) in the output cube.
          This normal will always be computed with a triaxial ellipsoid
          regardless of shapemodel. The output cube labels will contain three
          "Ellipsoid Normal (coord)" keywords in the BandBin group, in band
          sequence of the output file.

          <p>
            Note: These X, Y, and Z bands are in the body fixed reference frame.
          </p>
        </description>
      </parameter>
      <parameter name="SUBSPACECRAFTGROUNDAZIMUTH">
        <type>boolean</type>
        <default><item>FALSE</item></default>
+35 −0
Original line number Diff line number Diff line
@@ -1694,6 +1694,41 @@ namespace Isis {
  }


  /**
   * Calculates the slope at the current point
   * by computing the angle between the local surface normal and the ellipsoid
   * surface normal. If there is a failure during the process, such as there
   * not being an intersection, then success will be false and slope will not
   * be modified.
   *
   * @param[out] slope The slope angle in degrees
   * @param[out] success If the slope was successfully calculated
   */
  void Camera::Slope(double &slope, bool &success) {
    ShapeModel *shapeModel = target()->shape();
    if ( !shapeModel->hasIntersection()) {
      success = false;
      return;
    }
    shapeModel->calculateSurfaceNormal();
    if (!shapeModel->hasNormal()) {
      success = false;
      return;
    }
    std::vector<double> ellipsoidNormal = shapeModel->normal();

    double localNormal[3];
    GetLocalNormal(localNormal);
    if (localNormal[0] == 0.0 && localNormal[1] == 0.0 && localNormal[2] == 0.0) {
      success = false;
      return;
    }

    slope = vsep_c(localNormal, &ellipsoidNormal[0]) * 180.0 / PI;;
    success = true;
  }


  /**
   * Computes the RaDec range
   *
+1 −2
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ namespace Isis {

      void LocalPhotometricAngles(Angle & phase, Angle & incidence,
                                  Angle & emission, bool &success);
      void Slope(double &slope, bool &success);

      void GetLocalNormal(double normal[3]);

@@ -576,5 +577,3 @@ namespace Isis {
};

#endif