7#include "ProjectionFactory.h" 
   16#include "Displacement.h" 
   19#include "IException.h" 
   21#include "Projection.h" 
   22#include "RingPlaneProjection.h" 
   23#include "TProjection.h" 
   28  Plugin ProjectionFactory::m_projPlugin;
 
   57    if (m_projPlugin.fileName() == 
"") {
 
   58      FileName localFile(
"Projection.plugin");
 
   60        m_projPlugin.read(localFile.
expanded());
 
   62      FileName systemFile(
"$ISISROOT/lib/Projection.plugin");
 
   64        m_projPlugin.read(systemFile.
expanded());
 
   70      QString proj = mapGroup[
"ProjectionName"];
 
   75        ptr = m_projPlugin.GetPlugin(proj);
 
   78        QString msg = 
"Unsupported projection, unable to find plugin for [" +
 
   91      QString message = 
"Unable to initialize Projection information ";
 
   92      message += 
"from group [Mapping]";
 
 
  120      bool allowDefaults) {
 
  125    if (m_projPlugin.fileName() == 
"") {
 
  126      FileName localFile(
"Projection.plugin");
 
  128        m_projPlugin.read(localFile.
expanded());
 
  130      FileName systemFile(
"$ISISROOT/lib/Projection.plugin");
 
  132        m_projPlugin.read(systemFile.
expanded());
 
  138      QString proj = mapGroup[
"ProjectionName"];
 
  141      QFunctionPointer ptr;
 
  143        ptr = m_projPlugin.GetPlugin(proj);
 
  146        QString msg = 
"Unsupported projection, unable to find plugin for [" +
 
  155      return (
Projection *) (*plugin)(label, allowDefaults);
 
  158      QString message = 
"Unable to initialize Projection information ";
 
  159      message += 
"from group [Mapping]";
 
 
  189      int &samples, 
int &lines,
 
  194    double localRadius = proj->
LocalRadius(trueScaleLat);
 
  200      double scale, pixelResolution;
 
  203        pixelResolution = mapGroup[
"PixelResolution"];
 
  204        scale = (2.0 * 
Isis::PI * localRadius) / (360.0 * pixelResolution);
 
  211        scale = mapGroup[
"Scale"];
 
  212        pixelResolution = (2.0 * 
Isis::PI * localRadius) / (360.0 * scale);
 
  224      bool sizeFound = 
false;
 
  225      double upperLeftX = 
Null, upperLeftY = 
Null;
 
  228        samples = dims[
"Samples"];
 
  229        lines = dims[
"Lines"];
 
  231        upperLeftX = mapGroup[
"UpperLeftCornerX"];
 
  232        upperLeftY = mapGroup[
"UpperLeftCornerY"];
 
  235      if (!sizeMatch) sizeFound = 
false;
 
  243          QString msg = 
"Invalid ground range [MinimumLatitude,MaximumLatitude,";
 
  244          msg += 
"MinimumLongitude,MaximumLongitude] missing or invalid";
 
  248        double minX, maxX, minY, maxY;
 
  249        if (!proj->
XYRange(minX, maxX, minY, maxY)) {
 
  250          QString msg = 
"Invalid ground range [MinimumLatitude,MaximumLatitude,";
 
  251          msg += 
"MinimumLongitude,MaximumLongitude] cause invalid computation ";
 
  252          msg += 
"of image size";
 
  267        double minXFlipped = minX;
 
  268        double maxXFlipped = maxX;
 
  269        double minYFlipped = minY;
 
  270        double maxYFlipped = maxY;
 
  281          if (fabs(fmod(minXFlipped, pixelResolution)) > 1.0e-6) {
 
  282            if (pixelResolution - fabs(fmod(minXFlipped, pixelResolution)) > 1.0e-6) {            
 
  283              double sampleOffset = floor(minXFlipped / pixelResolution);
 
  285              minXFlipped = sampleOffset * pixelResolution;
 
  295        if (maxXFlipped < minXFlipped + pixelResolution) {
 
  296          maxXFlipped = minXFlipped + pixelResolution;
 
  308        if (fabs(fmod(maxYFlipped, pixelResolution)) > 1.0e-6) {
 
  309          if (abs(pixelResolution - fabs(fmod(maxYFlipped, pixelResolution))) > 1.0e-6) {
 
  310            double lineOffset = ceil(maxYFlipped / pixelResolution);        
 
  311            maxYFlipped =  lineOffset * pixelResolution;
 
  319        if (minYFlipped > maxYFlipped - pixelResolution) {
 
  320          minYFlipped = maxYFlipped - pixelResolution;
 
  325         samples = (int)((maxXFlipped - minXFlipped) / pixelResolution + 0.5);
 
  326         lines = (int)((maxYFlipped - minYFlipped) / pixelResolution + 0.5);
 
  335            upperLeftX = minXFlipped;
 
  345           upperLeftY = maxYFlipped;
 
  366                                           (QString) mapGroup[
"PixelResolution"],
 
  367                                           "meters/pixel"), Isis::Pvl::Replace);
 
  370                                           (QString) mapGroup[
"Scale"],
 
  371                                           "pixels/degree"), Isis::Pvl::Replace);
 
  374                                           (QString) mapGroup[
"UpperLeftCornerX"],
 
  375                                           "meters"), Isis::Pvl::Replace);
 
  378                                           (QString) mapGroup[
"UpperLeftCornerY"],
 
  379                                           "meters"), Isis::Pvl::Replace);
 
  382                                           (QString) mapGroup[
"EquatorialRadius"],
 
  383                                           "meters"), Isis::Pvl::Replace);
 
  386                                           (QString) mapGroup[
"PolarRadius"],
 
  387                                           "meters"), Isis::Pvl::Replace);
 
  397      QString msg = 
"Unable to create projection";
 
  400      finalError.
append(errors);
 
 
  433      int &samples, 
int &lines, 
bool sizeMatch) {
 
  445      double scale, pixelResolution;
 
  448        pixelResolution = mapGroup[
"PixelResolution"];
 
  449        scale = (2.0 * 
Isis::PI * localRadius) / (360.0 * pixelResolution);
 
  455        scale = mapGroup[
"Scale"];
 
  456        pixelResolution = (2.0 * 
Isis::PI * localRadius) / (360.0 * scale);
 
  472      bool sizeFound = 
false;
 
  473      double upperLeftX = 
Null, upperLeftY = 
Null;
 
  476        samples = dims[
"Samples"];
 
  477        lines = dims[
"Lines"];
 
  479        upperLeftX = mapGroup[
"UpperLeftCornerX"];
 
  480        upperLeftY = mapGroup[
"UpperLeftCornerY"];
 
  494          QString msg = 
"Invalid ring range [MinimumRingRadius,MaximumRingRadius,";
 
  495          msg += 
"MinimumRingLongitude,MaximumRingLongitude] missing or invalid";
 
  499        double minX, maxX, minY, maxY;
 
  500        if (!proj->
XYRange(minX, maxX, minY, maxY)) {
 
  501          QString msg = 
"Invalid ring range [MinimumRingRadius,MaximumRingRadius,";
 
  502          msg += 
"MinimumRingLongitude,MaximumRingLongitude] cause invalid computation ";
 
  503          msg += 
"of image size";
 
  513        if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  514          if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  515            double sampleOffset = floor(minX / pixelResolution);
 
  516            minX = sampleOffset * pixelResolution;
 
  521        if (maxX < minX + pixelResolution) {
 
  522          maxX = minX + pixelResolution;
 
  524        if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
  525          if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
  526            double lineOffset = -1.0 * ceil(maxY / pixelResolution);
 
  527            maxY = -1.0 * lineOffset * pixelResolution;
 
  532        if (minY > maxY - pixelResolution) {
 
  533          minY = maxY - pixelResolution;
 
  537        samples = (int)((maxX - minX) / pixelResolution + 0.5);
 
  538        lines = (int)((maxY - minY) / pixelResolution + 0.5);
 
  555        mapGroup.AddKeyword(
Isis::PvlKeyword(
"SampleProjectionOffset", sampleOffset),
 
  563                                           (QString) mapGroup[
"PixelResolution"],
 
  564                                           "meters/pixel"), Isis::Pvl::Replace);
 
  567                                           (QString) mapGroup[
"Scale"],
 
  568                                           "pixels/degree"), Isis::Pvl::Replace);
 
  571                                           (QString) mapGroup[
"UpperLeftCornerX"],
 
  572                                           "meters"), Isis::Pvl::Replace);
 
  575                                           (QString) mapGroup[
"UpperLeftCornerY"],
 
  576                                           "meters"), Isis::Pvl::Replace);
 
  586      QString msg = 
"Unable to create projection";
 
  589      finalError.
append(errors);
 
 
  622      int &samples, 
int &lines,
 
  627    double localRadius = proj->
LocalRadius(trueScaleLat);
 
  632      double scale, pixelResolution;
 
  635        pixelResolution = mapGroup[
"PixelResolution"];
 
  636        scale = (2.0 * 
Isis::PI * localRadius) / (360.0 * pixelResolution);
 
  641        scale = mapGroup[
"Scale"];
 
  642        pixelResolution = (2.0 * 
Isis::PI * localRadius) / (360.0 * scale);
 
  653      double minX = DBL_MAX;
 
  654      double maxX = -DBL_MAX;
 
  655      double minY = DBL_MAX;
 
  656      double maxY = -DBL_MAX;
 
  659      int eband = cam.
Bands();
 
  661      for(
int band = 1; band <= eband; band++) {
 
  665        for(
int line = 0; line <= cam.
Lines(); line++) {
 
  669          for(samp = 0; samp <= cam.
Samples(); samp++) {
 
  670            if (cam.
SetImage((
double)samp + 0.5, (
double)line + 0.5)) {
 
  679                if ((line != 0) && (line != cam.
Lines())) 
break;
 
  686            for(samp = cam.
Samples(); samp >= 0; samp--) {
 
  687              if (cam.
SetImage((
double)samp + 0.5, (
double)line + 0.5)) {
 
  705          if (cam.
Sample() >= 0.5 && cam.
Line() >= 0.5 &&
 
  720          if (cam.
Sample() >= 0.5 && cam.
Line() >= 0.5 &&
 
  738        for(
double lat = p_minlat; lat <= p_maxlat; lat += (p_maxlat - p_minlat) / 10.0) {
 
  739          if (SetUniversalGround(lat, 0.0)) {
 
  740            if (Sample() >= 0.5 && Line() >= 0.5 &&
 
  741                Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
 
  752        for(
double lat = p_minlat; lat <= p_maxlat; lat += (p_maxlat - p_minlat) / 10.0) {
 
  753          if (SetUniversalGround(lat, 180.0)) {
 
  754            if (Sample() >= 0.5 && Line() >= 0.5 &&
 
  755                Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
 
  756              p_minlon180 = -180.0;
 
  771      if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  772        if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  773          double sampleOffset = floor(minX / pixelResolution);
 
  774          minX = sampleOffset * pixelResolution;
 
  779      if (maxX < minX + pixelResolution) {
 
  780        maxX = minX + pixelResolution;
 
  782      if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
  783        if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
  784          double lineOffset = -1.0 * ceil(maxY / pixelResolution);
 
  785          maxY = -1.0 * lineOffset * pixelResolution;
 
  790      if (minY > maxY - pixelResolution) {
 
  791        minY = maxY - pixelResolution;
 
  795      samples = (int)((maxX - minX) / pixelResolution + 0.5);
 
  796      lines = (int)((maxY - minY) / pixelResolution + 0.5);
 
  799      double upperLeftX = minX;
 
  803      double upperLeftY = maxY;
 
  809                                           (QString) mapGroup[
"PixelResolution"],
 
  810                                           "meters/pixel"), Isis::Pvl::Replace);
 
  813                                           (QString) mapGroup[
"Scale"],
 
  814                                           "pixels/degree"), Isis::Pvl::Replace);
 
  817                                           (QString) mapGroup[
"UpperLeftCornerX"],
 
  818                                           "meters"), Isis::Pvl::Replace);
 
  821                                           (QString) mapGroup[
"UpperLeftCornerY"],
 
  822                                           "meters"), Isis::Pvl::Replace);
 
  825                                           (QString) mapGroup[
"EquatorialRadius"],
 
  826                                           "meters"), Isis::Pvl::Replace);
 
  829                                           (QString) mapGroup[
"PolarRadius"],
 
  830                                           "meters"), Isis::Pvl::Replace);
 
  840      QString msg = 
"Unable to create projection";
 
 
  873      int &samples, 
int &lines, 
Camera &cam) {
 
  883      double scale, pixelResolution;
 
  886        pixelResolution = mapGroup[
"PixelResolution"];
 
  887        scale = (2.0 * 
Isis::PI * localRadius) / (360.0 * pixelResolution);
 
  894        scale = mapGroup[
"Scale"];
 
  895        pixelResolution = (2.0 * 
Isis::PI * localRadius) / (360.0 * scale);
 
  899                                           "meters/pixel"), Isis::Pvl::Replace);
 
  905      double minX = DBL_MAX;
 
  906      double maxX = -DBL_MAX;
 
  907      double minY = DBL_MAX;
 
  908      double maxY = -DBL_MAX;
 
  911      int eband = cam.
Bands();
 
  913      for(
int band = 1; band <= eband; band++) {
 
  917        for(
int line = 0; line <= cam.
Lines(); line++) {
 
  921          for(samp = 0; samp <= cam.
Samples(); samp++) {
 
  922            if (cam.
SetImage((
double)samp + 0.5, (
double)line + 0.5)) {
 
  931                if ((line != 0) && (line != cam.
Lines())) 
break;
 
  938            for(samp = cam.
Samples(); samp >= 0; samp--) {
 
  939              if (cam.
SetImage((
double)samp + 0.5, (
double)line + 0.5)) {
 
  959        for(
double rad = p_minRadius; rad <= p_maxRadius; rad += (p_maxRadius - p_minRadius) / 10.0) {
 
  960          if (SetUniversalGround(rad, 0.0)) {
 
  961            if (Sample() >= 0.5 && Line() >= 0.5 &&
 
  962                Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
 
  973        for(
double rad = p_minrad; rad <= p_maxrad; rad += (p_maxrad - p_minrad) / 10.0) {
 
  974          if (SetUniversalGround(rad, 180.0)) {
 
  975            if (Sample() >= 0.5 && Line() >= 0.5 &&
 
  976                Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
 
  992      if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  993        if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
 
  994          double sampleOffset = floor(minX / pixelResolution);
 
  995          minX = sampleOffset * pixelResolution;
 
 1000      if (maxX < minX + pixelResolution) {
 
 1001        maxX = minX + pixelResolution;
 
 1004      if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
 1005        if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
 
 1006          double lineOffset = -1.0 * ceil(maxY / pixelResolution);
 
 1007          maxY = -1.0 * lineOffset * pixelResolution;
 
 1012      if (minY > maxY - pixelResolution) {
 
 1013        minY = maxY - pixelResolution;
 
 1017      samples = (int)((maxX - minX) / pixelResolution + 0.5);
 
 1018      lines = (int)((maxY - minY) / pixelResolution + 0.5);
 
 1021      double upperLeftX = minX;
 
 1023                          Isis::Pvl::Replace);
 
 1025      double upperLeftY = maxY;
 
 1027                          Isis::Pvl::Replace);
 
 1031                                           (QString) mapGroup[
"PixelResolution"],
 
 1032                                           "meters/pixel"), Isis::Pvl::Replace);
 
 1035                                           (QString) mapGroup[
"Scale"],
 
 1036                                           "pixels/degree"), Isis::Pvl::Replace);
 
 1039                                           (QString) mapGroup[
"UpperLeftCornerX"],
 
 1040                                           "meters"), Isis::Pvl::Replace);
 
 1043                                           (QString) mapGroup[
"UpperLeftCornerY"],
 
 1044                                           "meters"), Isis::Pvl::Replace);
 
 1054      QString msg = 
"Unable to create projection";
 
 1055      if (label.
fileName() != 
"") msg += 
" from file [" + label.
fileName() + 
"]";
 
 
 1100      double pixelResolution = mapGroup[
"PixelResolution"];
 
 1103      double upperLeftX = mapGroup[
"UpperLeftCornerX"];
 
 1104      double upperLeftY = mapGroup[
"UpperLeftCornerY"];
 
 1117      QString msg = 
"Unable to initialize cube projection";
 
 1118      if (label.
fileName() != 
"") msg += 
" from file [" + label.
fileName() + 
"]";
 
 
 1139      double pixelResolution = mapGroup[
"PixelResolution"];
 
 1142      double upperLeftX = mapGroup[
"UpperLeftCornerX"];
 
 1143      double upperLeftY = mapGroup[
"UpperLeftCornerY"];
 
 1156      QString msg = 
"Unable to initialize cube projection";
 
 1157      if (label.
fileName() != 
"") msg += 
" from file [" + label.
fileName() + 
"]";
 
 
virtual double Line() const
Returns the current line number.
 
int Lines() const
Returns the number of lines in the image.
 
virtual double Sample() const
Returns the current sample number.
 
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
 
virtual bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
 
virtual bool IsBandIndependent()
Virtual method that checks if the band is independent.
 
int Samples() const
Returns the number of samples in the image.
 
virtual void SetBand(const int band)
Virtual method that sets the band number.
 
int Bands() const
Returns the number of bands in the image.
 
IO Handler for Isis Cubes.
 
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
 
Displacement is a signed length, usually in meters.
 
@ Meters
The distance is being specified in meters.
 
double meters() const
Get the distance in meters.
 
File name manipulation and expansion.
 
bool fileExists() const
Returns true if the file exists; false otherwise.
 
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
 
@ Unknown
A type of error that cannot be classified as any of the other error types.
 
@ Io
A type of error that occurred when performing an actual I/O operation.
 
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception's causational exc...
 
Loads plugins from a shared library.
 
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
 
static Isis::Projection * RingsCreate(Isis::Pvl &label, bool allowDefaults=false)
This method returns a pointer to a RingPlaneProjection object.
 
static Isis::Projection * Create(Isis::Pvl &label, bool allowDefaults=false)
This method returns a pointer to a Projection object.
 
static Isis::Projection * RingsCreateForCube(Isis::Pvl &label, int &samples, int &lines, bool sizeMatch)
This method creates a projection for a cube to a ring plane given a label.
 
static Isis::Projection * RingsCreateFromCube(Isis::Cube &cube)
This method is a helper method.
 
static Isis::Projection * CreateForCube(Isis::Pvl &label, int &ns, int &nl, bool sizeMatch=true)
This method creates a map projection for a cube given a label.
 
Base class for Map Projections.
 
void SetWorldMapper(WorldMapper *mapper)
If desired the programmer can use this method to set a world mapper to be used in the SetWorld,...
 
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround,...
 
virtual bool HasGroundRange() const
This indicates if the longitude direction type is positive west (as opposed to postive east).
 
void SetUpperLeftCorner(const Displacement &x, const Displacement &y)
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
 
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround,...
 
bool IsGood() const
This indicates if the last invocation of SetGround, SetCoordinate, SetUniversalGround,...
 
QString fileName() const
Returns the filename used to initialise the Pvl object.
 
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
 
Contains multiple PvlContainers.
 
Container for cube-like labels.
 
A single keyword-value pair.
 
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not.
 
@ Traverse
Search child objects.
 
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
 
Base class for Map Projections of plane shapes.
 
virtual double TrueScaleRingRadius() const
This method returns the radius of true scale.
 
virtual bool XYRange(double &minX, double &maxX, double &minY, double &maxY)
This method is used to determine the x/y range which completely covers the area of interest specified...
 
virtual bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the ring radius/longitude (assumed to be of the correct LatitudeType,...
 
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
 
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
 
Distance LocalRadius() const
Returns the local radius at the intersection point.
 
Base class for Map TProjections.
 
virtual bool XYRange(double &minX, double &maxX, double &minY, double &maxY)
This method is used to determine the x/y range which completely covers the area of interest specified...
 
double LocalRadius(double lat) const
This method returns the local radius in meters at the specified latitude position.
 
virtual bool SetUniversalGround(const double lat, const double lon)
This method is used to set the latitude/longitude which must be Planetocentric (latitude) and Positiv...
 
virtual double TrueScaleLatitude() const
This method returns the latitude of true scale.
 
This is free and unencumbered software released into the public domain.
 
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
 
const double Null
Value for an Isis Null pixel.
 
const double PI
The mathematical constant PI.
 
Namespace for the standard library.