Isis 3.0 Programmer Reference
Back | Home
ShapeModelFactory.cpp
Go to the documentation of this file.
1 
24 #include "ShapeModelFactory.h"
25 
26 #include <string>
27 
28 #include "Cube.h"
29 #include "DemShape.h"
30 #include "EllipsoidShape.h"
32 #include "FileName.h"
33 #include "IException.h"
34 #include "IString.h"
35 #include "NaifDskShape.h"
36 #include "NaifStatus.h"
37 #include "PlaneShape.h"
38 #include "Projection.h"
39 #include "Pvl.h"
40 #include "PvlGroup.h"
41 #include "Target.h"
42 
43 using namespace std;
44 
45 namespace Isis {
51  ShapeModelFactory::ShapeModelFactory() {}
52 
54  ShapeModelFactory::~ShapeModelFactory() {}
55 
59  ShapeModel *ShapeModelFactory::create(Target *target, Pvl &pvl) {
60 
61  // get kernels and instrument Pvl groups
62  PvlGroup &kernelsPvlGroup = pvl.findGroup("Kernels", Pvl::Traverse);
63  // Do we need a sky shape model, member variable, or neither? For now treat sky as ellipsoid
64  bool skyTarget = target->isSky();
65 
66  // Determine if target is a plane??? target name has rings in it?
67  // Another keyword in label to indicate plane? What about lander/rovers?
68  // bool planeTarget = false;
69 
70  // shape model file name
71  QString shapeModelFilenames = "";
72 
73  // TODO: We differentiate between "Elevation" and "Shape" models on the
74  // labels, but we assign either one to the shapeModelFilename. Do we
75  // need a shapeModelFilename AND an elevationModelFilename?
76  // is this historical? Interchangeable?
77  if (skyTarget) {
78  // Sky targets are ellipsoid shapes
79  }
80  else if (kernelsPvlGroup.hasKeyword("ElevationModel") &&
81  !kernelsPvlGroup["ElevationModel"].isNull()) {
82  shapeModelFilenames = (QString) kernelsPvlGroup["ElevationModel"];
83  }
84  else if (kernelsPvlGroup.hasKeyword("ShapeModel") &&
85  !kernelsPvlGroup["ShapeModel"].isNull()) {
86  shapeModelFilenames = (QString) kernelsPvlGroup["ShapeModel"];
87  }
88 
89  // Create shape model
90  ShapeModel *shapeModel = NULL;
91 
92  // TODO: If there is no shape model filename, the shape model type defaults to an
93  // ellipsoid (should it?).
94 
95  // This exception will be thrown at the end of this method if no shape model is constructed.
96  // More specific exceptions will be appended before throwing this error.
97  IException finalError(IException::Programmer,
98  "Unable to create a shape model from given target and pvl.",
99  _FILEINFO_);
100 
101  if (shapeModelFilenames == "") {
102  // No file name given. If EllipsoidShape throws an error or returns null, the following
103  // exception will be appended to the finalError.
104  QString msg = "Unable to construct an Ellipsoid shape model.";
105 
106  try {
107  shapeModel = new EllipsoidShape(target);
108  }
109  catch (IException &e) {
110  // No file name given and ellipsoid fails. Append e to new exception
111  // with above message. Append this to finalError and throw.
112  finalError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
113  throw finalError;
114  }
115  // in case no error was thrown, but constructor returned NULL
116  finalError.append(IException(IException::Unknown, msg, _FILEINFO_));
117  }
118  else if (shapeModelFilenames == "RingPlane") {
119  // No file name given, RingPlane indicated. If PlaneShape throws an error or returns
120  // null, the following exception will be appended to the finalError.
121  QString msg = "Unable to construct a RingPlane shape model.";
122 
123  try {
124  shapeModel = new PlaneShape(target, pvl);
125  }
126  catch (IException &e) {
127  // No file name given, RingPlane specified. Append a message to the finalError and throw it.
128  finalError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
129  throw finalError;
130  }
131  // in case no error was thrown, but constructor returned NULL
132  finalError.append(IException(IException::Unknown, msg, _FILEINFO_));
133  }
134  else { // assume shape model given is a NAIF DSK or DEM cube file name
135 
136  // A file error message will be appened to the finalError, if no shape model is constructed.
137  QString fileErrorMsg = "Invalid shape model file ["
138  + shapeModelFilenames + "] in Kernels group.";
139  IException fileError(IException::Io, fileErrorMsg, _FILEINFO_);
140 
141  //-------------- Is the shape model a NAIF DSK? ------------------------------//
142 
143  // If NaifDskShape throws an error or returns null and DEM construction is
144  // unsuccessful, the following exception will be appended to the fileError.
145  QString msg = "The given shape model file is not a valid NAIF DSK file. "
146  "Unable to construct a NAIF DSK shape model.";
147  IException dskError(IException::Unknown, msg, _FILEINFO_);
148 
149  try {
150  // try to create a NaifDskShape object
151  shapeModel = new NaifDskShape(target, pvl);
152  }
153  catch (IException &e) {
154  // append a message to the fileError, but don't throw it.
155  // We will make sure it's not a DEM before throwing the error.
156  dskError.append(e);
157  }
158 
159  if (shapeModel == NULL) {
160 
161  // in case no error was thrown, but constructor returned NULL
162  fileError.append(dskError);
163 
164  //-------------- Is the shape model an ISIS DEM? ------------------------------//
165  // TODO Deal with stacks -- this could be a list of DEMs
166  Isis::Cube* shapeModelCube = new Isis::Cube;
167  try {
168  // first, try to open the shape model file as an Isis3 cube
169  shapeModelCube->open(FileName(shapeModelFilenames).expanded(), "r" );
170  }
171  catch (IException &e) {
172  // The file is neither a valid DSK nor an ISIS cube. Append a message and throw the error.
173  QString msg = "The given shape model file is not a valid ISIS DEM. "
174  "Unable to open as an ISIS cube.";
175  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
176  finalError.append(fileError);
177  throw finalError;
178  }
179 
180  Projection *projection = NULL;
181  try {
182  // get projection of shape model cube
183  projection = shapeModelCube->projection();
184  }
185  catch (IException &e) {
186  // The file is neither a valid DSK nor a valid ISIS DEM. Append message and throw the error.
187  QString msg = "The given shape model file is not a valid ISIS DEM cube. "
188  "It is not map-projected.";
189  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
190  finalError.append(fileError);
191  throw finalError;
192  }
193 
194  if (projection->IsEquatorialCylindrical()) {
195 
196  delete shapeModelCube;
197 
198  // If the EquatorialCylindricalShape constructor throws an error or returns null, the
199  // following exception will be appended to the fileError. (Later added to the finalError)
200  QString msg = "Unable to construct a DEM shape model from the given "
201  "EquatorialCylindrical projected ISIS cube.";
202 
203  try {
204  shapeModel = new EquatorialCylindricalShape(target, pvl);
205  }
206  catch (IException &e) {
207  // The file is an equatorial cylindrical ISIS cube. Append fileError and throw.
208  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
209  finalError.append(fileError);
210  throw finalError;
211  }
212  // in case no error was thrown, but constructor returned NULL
213  fileError.append(IException(IException::Unknown, msg, _FILEINFO_));
214  }
215  else {
216  // If the DemShape constructor throws an error or returns null, the following
217  // exception will be appended to the fileError. (Later added to the finalError)
218  QString msg = "Unable to construct a DEM shape model "
219  "from the given projected ISIS cube file.";
220 
221  try {
222  shapeModel = new DemShape(target, pvl);
223  }
224  catch (IException &e) {
225  // The file is projected ISIS cube (assumed to be DEM). Append fileError and throw.
226  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
227  finalError.append(fileError);
228  throw finalError;
229  }
230  // in case no error was thrown, but constructor returned NULL
231  fileError.append(IException(IException::Unknown, msg, _FILEINFO_));
232  }
233 
234  }
235 
236  // in case no error was thrown, but DSK, Equatorial, or DEM constructor returned NULL
237  finalError.append(fileError);
238  }
239 
240  // TODO Add Naif DSK shape and stack?
241 
242  if (shapeModel == NULL) {
243  throw finalError;
244  }
245 
246  return shapeModel;
247  }
248 } // end namespace isis
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
Projection * projection()
Definition: Cube.cpp:1391
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
void open(const QString &cfile, QString access="r")
This method will open an isis cube for reading or reading/writing.
Definition: Cube.cpp:509
bool isSky() const
Return if our target is the sky.
Definition: Target.cpp:180
Container for cube-like labels.
Definition: Pvl.h:135
This class is used to create and store valid Isis3 targets.
Definition: Target.h:63
Define shapes and provide utilities for Isis3 targets.
Definition: ShapeModel.h:68
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:29:10