USGS

Isis 3.0 Object Programmers' Reference

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 
53 
54 
56  ShapeModelFactory::~ShapeModelFactory() {}
57 
58 
59 
63  ShapeModel *ShapeModelFactory::create(Target *target, Pvl &pvl) {
64 
65  // get kernels and instrument Pvl groups
66  PvlGroup &kernelsPvlGroup = pvl.findGroup("Kernels", Pvl::Traverse);
67  // Do we need a sky shape model, member variable, or neither? For now treat sky as ellipsoid
68  bool skyTarget = target->isSky();
69 
70  // Determine if target is a plane??? target name has rings in it?
71  // Another keyword in label to indicate plane? What about lander/rovers?
72  // bool planeTarget = false;
73 
74  // shape model file name
75  QString shapeModelFilenames = "";
76 
77  // TODO: We differentiate between "Elevation" and "Shape" models on the
78  // labels, but we assign either one to the shapeModelFilename. Do we
79  // need a shapeModelFilename AND an elevationModelFilename?
80  // is this historical? Interchangeable?
81  if (skyTarget) {
82  // Sky targets are ellipsoid shapes
83  }
84  else if (kernelsPvlGroup.hasKeyword("ElevationModel") &&
85  !kernelsPvlGroup["ElevationModel"].isNull()) {
86  shapeModelFilenames = (QString) kernelsPvlGroup["ElevationModel"];
87  }
88  else if (kernelsPvlGroup.hasKeyword("ShapeModel") &&
89  !kernelsPvlGroup["ShapeModel"].isNull()) {
90  shapeModelFilenames = (QString) kernelsPvlGroup["ShapeModel"];
91  }
92 
93  // Create shape model
94  ShapeModel *shapeModel = NULL;
95 
96  // TODO: If there is no shape model filename, the shape model type defaults to an
97  // ellipsoid (should it?).
98 
99  // This exception will be thrown at the end of this method if no shape model is constructed.
100  // More specific exceptions will be appended before throwing this error.
101  IException finalError(IException::Programmer,
102  "Unable to create a shape model from given target and pvl.",
103  _FILEINFO_);
104 
105  if (shapeModelFilenames == "") {
106  // No file name given. If EllipsoidShape throws an error or returns null, the following
107  // exception will be appended to the finalError.
108  QString msg = "Unable to construct an Ellipsoid shape model.";
109 
110  try {
111  shapeModel = new EllipsoidShape(target);
112  }
113  catch (IException &e) {
114  // No file name given and ellipsoid fails. Append e to new exception
115  // with above message. Append this to finalError and throw.
116  finalError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
117  throw finalError;
118  }
119  // in case no error was thrown, but constructor returned NULL
120  finalError.append(IException(IException::Unknown, msg, _FILEINFO_));
121  }
122  else if (shapeModelFilenames == "RingPlane") {
123  // No file name given, RingPlane indicated. If PlaneShape throws an error or returns
124  // null, the following exception will be appended to the finalError.
125  QString msg = "Unable to construct a RingPlane shape model.";
126 
127  try {
128  shapeModel = new PlaneShape(target, pvl);
129  }
130  catch (IException &e) {
131  // No file name given, RingPlane specified. Append a message to the finalError and throw it.
132  finalError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
133  throw finalError;
134  }
135  // in case no error was thrown, but constructor returned NULL
136  finalError.append(IException(IException::Unknown, msg, _FILEINFO_));
137  }
138  else { // assume shape model given is a NAIF DSK or DEM cube file name
139 
140  // A file error message will be appened to the finalError, if no shape model is constructed.
141  QString fileErrorMsg = "Invalid shape model file ["
142  + shapeModelFilenames + "] in Kernels group.";
143  IException fileError(IException::Io, fileErrorMsg, _FILEINFO_);
144 
145  //-------------- Is the shape model a NAIF DSK? ------------------------------//
146 
147  // If NaifDskShape throws an error or returns null and DEM construction is
148  // unsuccessful, the following exception will be appended to the fileError.
149  QString msg = "The given shape model file is not a valid NAIF DSK file. "
150  "Unable to construct a NAIF DSK shape model.";
151  IException dskError(IException::Unknown, msg, _FILEINFO_);
152 
153  try {
154  // try to create a NaifDskShape object
155  shapeModel = new NaifDskShape(target, pvl);
156  }
157  catch (IException &e) {
158  // append a message to the fileError, but don't throw it.
159  // We will make sure it's not a DEM before throwing the error.
160  dskError.append(e);
161  }
162 
163  if (shapeModel == NULL) {
164  // in case no error was thrown, but constructor returned NULL
165  fileError.append(dskError);
166 
167  //-------------- Is the shape model an ISIS DEM? ------------------------------//
168  // TODO Deal with stacks -- this could be a list of DEMs
169  Isis::Cube shapeModelCube;
170  try {
171  // first, try to open the shape model file as an Isis3 cube
172  shapeModelCube.open(FileName(shapeModelFilenames).expanded(), "r" );
173  }
174  catch (IException &e) {
175  // The file is neither a valid DSK nor an ISIS cube. Append a message and throw the error.
176  QString msg = "The given shape model file is not a valid ISIS DEM. "
177  "Unable to open as an ISIS cube.";
178  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
179  finalError.append(fileError);
180  throw finalError;
181  }
182 
183  Projection *projection = NULL;
184  try {
185  // get projection of shape model cube
186  projection = shapeModelCube.projection();
187  }
188  catch (IException &e) {
189  // The file is neither a valid DSK nor a valid ISIS DEM. Append message and throw the error.
190  QString msg = "The given shape model file is not a valid ISIS DEM cube. "
191  "It is not map-projected.";
192  fileError.append(IException(e, IException::Unknown, msg, _FILEINFO_));
193  finalError.append(fileError);
194  throw finalError;
195  }
196 
197  if (projection->IsEquatorialCylindrical()) {
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