Isis 3 Programmer Reference
NaifDskPlateModel.cpp
Go to the documentation of this file.
1 
25 // Uncomment this definition and you get thread-safe methods. Note this is not
26 // done in the header as it would change the header footprint and require a
27 // complete system recompile. Done here only invokes locking with defined mutex
28 // classes in the header. To make this happen on demand, uncomment the define,
29 // recompile, reinsert in libisisx.y.z.a and recreate the shared library.
30 //
31 // #define MAKE_THREAD_SAFE 1
32 
33 #include "NaifDskPlateModel.h"
34 
35 #include <iostream>
36 #include <iomanip>
37 #include <numeric>
38 #include <sstream>
39 
40 #if defined(MAKE_THREAD_SAFE)
41 #include <QMutexLocker>
42 #endif
43 #include <QScopedPointer>
44 
45 #include "FileName.h"
46 #include "IException.h"
47 #include "Intercept.h"
48 #include "IString.h"
49 #include "Latitude.h"
50 #include "Longitude.h"
51 #include "NaifDskApi.h"
52 #include "NaifStatus.h"
53 #include "SurfacePoint.h"
54 #include "TriangularPlate.h"
55 
56 using namespace std;
57 
58 namespace Isis {
59 
61  NaifDskPlateModel::NaifDskPlateModel() : m_dsk(0) { }
62 
63 
64 
66  NaifDskPlateModel::NaifDskPlateModel(const QString &dskfile) : m_dsk(0) {
68  if ( !isValid() ) {
69  QString mess = "Could not open DSK file " + dskfile;
71  }
72  }
73 
74 
75 
76  NaifDskPlateModel::~NaifDskPlateModel() { }
77 
78 
79 
82  return ( !m_dsk.isNull() );
83  }
84 
85 
86 
88  QString NaifDskPlateModel::filename() const {
89  if ( isValid() ) { return (m_dsk->m_dskfile); }
90  return ( QString() );
91  }
92 
93 
94 
97  return ( numberPlates() );
98  }
99 
100 
101 
104  if ( !isValid() ) return (0);
105  return ( m_dsk->m_plates );
106  }
107 
108 
109 
112  if ( !isValid() ) return (0);
113  return ( m_dsk->m_vertices );
114  }
115 
116 
117 
139  const Longitude &lon) const {
140 
141  // Sanity check on input point
142  verify ( lat.isValid(), "Latitude parameter invalid in NaifDskPlateMode::point()" );
143  verify ( lon.isValid(), "Longitude parameter invalid in NaifDskPlateMode::point()" );
144 
145  // Ensure a DSK file is opened or exception is thrown
146  verify( isValid(), "NAIF DSK file not opened/valid!");
147 
148  // Get the lon/lat point in radians
149  SpiceDouble lonlat[2];
150  lonlat[0] = lon.positiveEast(Angle::Radians);
151  lonlat[1] = lat.planetocentric(Angle::Radians);
152  SpiceInt npoints(1);
153  NaifVertex spoint(3, 0.0);
154  SpiceInt plateId(-1);
155 
156  #if defined(MAKE_THREAD_SAFE)
157  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
158  #endif
159 
160  llgrid_pl02( m_dsk->m_handle, &m_dsk->m_dladsc, npoints,
161  (ConstSpiceDouble (*)[2]) lonlat,
162  (SpiceDouble (*)[3]) &spoint[0], &plateId);
164 
165  #if 0
166  if ( !isPlateIdValid(plateId) ) {
167  QString mess = "Plateid = " + QString::number(plateId) + " is invalid";
169  }
170  #endif
171 
172  // Other error checks???
173  return ( makePoint(spoint) );
174  }
175 
176 
177 
197  const NaifVector &raydir) const {
198  // Get the plate
199  NaifVertex xpoint;
200  SpiceInt plateid = plateIdOfIntercept(vertex, raydir, xpoint);
201  if ( !isPlateIdValid(plateid) ) return (0);
202 
203  NaifTriangle triangle = plate(plateid);
204 
205  // Return the intercept
206  return (new Intercept(vertex, raydir, makePoint(xpoint),
207  new TriangularPlate(triangle, plateid)));
208  }
209 
210 
211 
230  bool NaifDskPlateModel::isPlateIdValid(const SpiceInt plateid) const {
231  if ( !isValid() ) return (false);
232  return ( (plateid >= 1) && (plateid <= m_dsk->m_plates) );
233  }
234 
235 
236 
254  const NaifVector &raydir,
255  NaifVertex &xpoint) const {
256 
257  // Sanity check on input parameters
258  try {
259  verify( validate(vertex), "Invalid/bad dimensions on intercept source point");
260  verify( validate(raydir), "Invalid/bad dimensions on ray direction vector");
261  }
262  catch ( IException &ie ) {
264  "Invalid point source data to determine intercept",
265  _FILEINFO_);
266  }
267 
268  // Ensure a DSK file is opened or exception is thrown
269  verify( isValid(), "NAIF DSK file not opened/valid!");
270 
271  // Get the lon/lat point in radians
272  SpiceInt plateid;
273  NaifVertex xpt(3, 0.0);
274  SpiceBoolean found;
275 
276  #if defined(MAKE_THREAD_SAFE)
277  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
278  #endif
279  // Find the plate of intersection and intercept point
281  dskx02_c( m_dsk->m_handle, &m_dsk->m_dladsc, &vertex[0], &raydir[0],
282  &plateid, &xpt[0], &found);
283  // Check status
285  if ( !found ) return (0);
286 
287  // Return succesful results
288  xpoint = xpt;
289  return ( plateid );
290  }
291 
292 
293 
307  NaifTriangle NaifDskPlateModel::plate(SpiceInt plateid) const {
308 
309  // Ensure a DSK file is opened or exception is thrown
310  verify( isValid(), "NAIF DSK file not opened/valid!");
311 
312  // Sanity check on plateid
313  if ( !isPlateIdValid(plateid) ) {
314  QString mess = "Plateid = " + QString::number(plateid) + " is invalid";
316  }
317 
318  // Get the plate
319  SpiceInt nplates;
320  SpiceInt iplate[3];
321 
322  #if defined(MAKE_THREAD_SAFE)
323  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
324  #endif
325 
327  dskp02_c(m_dsk->m_handle, &m_dsk->m_dladsc, plateid, 1, &nplates,
328  ( SpiceInt(*)[3] )(iplate));
330 
331  // Get the verticies of the plates
332  NaifTriangle plate(3, 3);
333  SpiceInt n;
334  for (int i = 0 ; i < 3 ; i++) {
335  dskv02_c(m_dsk->m_handle, &m_dsk->m_dladsc, iplate[i], 1, &n,
336  ( SpiceDouble(*)[3] )(plate[i]));
337  }
339 
340  return (plate);
341  }
342 
343 
344 
363 
364  // Sanity check
365  FileName dskFile(dskfile);
366  if ( !dskFile.fileExists() ) {
367  QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
368  throw IException(IException::User, mess, _FILEINFO_);
369  }
370 
371  // Open the NAIF Digital Shape Kernel (DSK)
372  QScopedPointer<NaifDskDescriptor> dsk(new NaifDskDescriptor());
373  dsk->m_dskfile = dskfile;
375  dasopr_c( dskFile.expanded().toLatin1().data(), &dsk->m_handle );
377 
378  // Search to the first DLA segment
379  SpiceBoolean found;
380  dlabfs_c( dsk->m_handle, &dsk->m_dladsc, &found );
382  if ( !found ) {
383  QString mess = "No segments found in DSK file " + dskfile ;
384  throw IException(IException::User, mess, _FILEINFO_);
385  }
386 
388  dskgd_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_dskdsc );
389 
390  // Get size/counts
391  dskz02_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_vertices,
392  &dsk->m_plates );
394 
395  // return pointer
396  return ( dsk.take() );
397  }
398 
399 
400 
402  bool NaifDskPlateModel::verify(const bool &test, const QString &errmsg,
403  const NaifDskPlateModel::ErrAction &action)
404  const {
405  if ( ( Throw == action ) && ( !test ) ) {
407  }
408 
409  // Looks good
410  return ( test );
411  }
412 
413 
414 
417  verify( validate(v), "Vertex/point invalid - not a 3 vector" );
421 
422  }
423 
424 
425  NaifDskPlateModel::NaifDskDescriptor::NaifDskDescriptor() : m_dskfile(), m_handle(-1),
426  m_dladsc(), m_dskdsc(), m_plates(0),
427  m_vertices(0), m_mutex() {
428  }
429 
430 
431  NaifDskPlateModel::NaifDskDescriptor::~NaifDskDescriptor() {
432  if ( -1 != m_handle ) {
434  dascls_c ( m_handle );
436  }
437  }
438 
439 
440 } // namespace Isis
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:148
SpiceInt numberPlates() const
Returns the number of plates in the model.
The distance is being specified in kilometers.
Definition: Displacement.h:54
File name manipulation and expansion.
Definition: FileName.h:116
NaifDskDescriptor * openDSK(const QString &dskfile)
Opens a valid NAIF DSK plate model file.
Throw an exception if an error occurs.
SurfacePoint * makePoint(const NaifVertex &v) const
Construct and return a SurfacePoint pointer.
double planetocentric(Angle::Units units=Angle::Radians) const
Get the latitude in the planetocentric (universal) coordinate system.
Definition: Latitude.cpp:295
Namespace for the standard library.
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:63
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
SpiceInt m_handle
The DAS file handle of the DSK file.
TNT::Array1D< SpiceDouble > NaifVector
Namespace to contain type definitions of NAIF DSK fundamentals.
Definition: NaifDskApi.h:61
Intercept * intercept(const NaifVertex &vertex, const NaifVector &raydir) const
Determine a target body intercept point from an observer and look direction.
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
TNT::Array1D< SpiceDouble > NaifVertex
1-D Buffer[3]
Definition: NaifDskApi.h:62
SpiceInt numberVertices() const
Returns the number of vertices in the plate model.
SurfacePoint * point(const Latitude &lat, const Longitude &lon) const
Get surface intersection for a lat/lon grid point.
NaifTriangle plate(SpiceInt plateid) const
Retrieve the triangular plate identified by its ID.
bool isValid() const
Checks validity of the object.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
Container for a intercept condition.
Definition: Intercept.h:51
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
double positiveEast(Angle::Units units=Angle::Radians) const
Get the longitude in the PositiveEast coordinate system.
Definition: Longitude.cpp:159
bool validate(const NaifVertex &v)
Verifies that the given NaifVector or NaifVertex is 3 dimensional.
Definition: NaifDskApi.cpp:45
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
SharedNaifDskDescriptor m_dsk
Shared pointer to the NaifDskDescriptor for this plate.
ErrAction
Enumeration to indicate whether to throw an exception if an error occurs.
NaifDskPlateModel()
Default empty constructor.
int size() const
Returns the number of plates in the DSK file - mostly for conformity.
Displacement is a signed length, usually in meters.
Definition: Displacement.h:43
Specification for an abstract triangular plate.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
QString filename() const
Returns the nane of the NAIF DSK file.
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:80
bool verify(const bool &test, const QString &errmsg, const ErrAction &action=Throw) const
Convenience method for generalized error reporting.
bool isPlateIdValid(const SpiceInt plateid) const
Determines if the plate ID is valid.
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465
TNT::Array2D< SpiceDouble > NaifTriangle
3-D triangle[3][3]
Definition: NaifDskApi.h:63
SpiceInt plateIdOfIntercept(const NaifVertex &vertex, const NaifVector &raydir, NaifVertex &xpoint) const
Primary API to determine ray intercept from observer/look direction.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.