Isis 3 Programmer Reference
NaifDskPlateModel.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 
8 // Uncomment this definition and you get thread-safe methods. Note this is not
9 // done in the header as it would change the header footprint and require a
10 // complete system recompile. Done here only invokes locking with defined mutex
11 // classes in the header. To make this happen on demand, uncomment the define,
12 // recompile, reinsert in libisisx.y.z.a and recreate the shared library.
13 //
14 // #define MAKE_THREAD_SAFE 1
15 
16 #include "NaifDskPlateModel.h"
17 
18 #include <iostream>
19 #include <iomanip>
20 #include <numeric>
21 #include <sstream>
22 
23 #if defined(MAKE_THREAD_SAFE)
24 #include <QMutexLocker>
25 #endif
26 #include <QScopedPointer>
27 
28 #include "FileName.h"
29 #include "IException.h"
30 #include "Intercept.h"
31 #include "IString.h"
32 #include "Latitude.h"
33 #include "Longitude.h"
34 #include "NaifDskApi.h"
35 #include "NaifStatus.h"
36 #include "SurfacePoint.h"
37 #include "TriangularPlate.h"
38 
39 using namespace std;
40 
41 namespace Isis {
42 
44  NaifDskPlateModel::NaifDskPlateModel() : m_dsk(0) { }
45 
46 
47 
49  NaifDskPlateModel::NaifDskPlateModel(const QString &dskfile) : m_dsk(0) {
51  if ( !isValid() ) {
52  QString mess = "Could not open DSK file " + dskfile;
53  throw IException(IException::User, mess, _FILEINFO_);
54  }
55  }
56 
57 
58 
59  NaifDskPlateModel::~NaifDskPlateModel() { }
60 
61 
62 
65  return ( !m_dsk.isNull() );
66  }
67 
68 
69 
71  QString NaifDskPlateModel::filename() const {
72  if ( isValid() ) { return (m_dsk->m_dskfile); }
73  return ( QString() );
74  }
75 
76 
77 
80  return ( numberPlates() );
81  }
82 
83 
84 
87  if ( !isValid() ) return (0);
88  return ( m_dsk->m_plates );
89  }
90 
91 
92 
95  if ( !isValid() ) return (0);
96  return ( m_dsk->m_vertices );
97  }
98 
99 
100 
122  const Longitude &lon) const {
123 
124  // Sanity check on input point
125  verify ( lat.isValid(), "Latitude parameter invalid in NaifDskPlateMode::point()" );
126  verify ( lon.isValid(), "Longitude parameter invalid in NaifDskPlateMode::point()" );
127 
128  // Ensure a DSK file is opened or exception is thrown
129  verify( isValid(), "NAIF DSK file not opened/valid!");
130 
131  // Get the lon/lat point in radians
132  SpiceDouble lonlat[2];
133  lonlat[0] = lon.positiveEast(Angle::Radians);
134  lonlat[1] = lat.planetocentric(Angle::Radians);
135  SpiceInt npoints(1);
136  NaifVertex spoint(3, 0.0);
137  SpiceInt plateId(-1);
138 
139  #if defined(MAKE_THREAD_SAFE)
140  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
141  #endif
142 
143  llgrid_pl02( m_dsk->m_handle, &m_dsk->m_dladsc, npoints,
144  (ConstSpiceDouble (*)[2]) lonlat,
145  (SpiceDouble (*)[3]) &spoint[0], &plateId);
147 
148  #if 0
149  if ( !isPlateIdValid(plateId) ) {
150  QString mess = "Plateid = " + QString::number(plateId) + " is invalid";
151  throw IException(IException::Programmer, mess, _FILEINFO_);
152  }
153  #endif
154 
155  // Other error checks???
156  return ( makePoint(spoint) );
157  }
158 
159 
160 
180  const NaifVector &raydir) const {
181  // Get the plate
182  NaifVertex xpoint;
183  SpiceInt plateid = plateIdOfIntercept(vertex, raydir, xpoint);
184  if ( !isPlateIdValid(plateid) ) return (0);
185 
186  NaifTriangle triangle = plate(plateid);
187 
188  // Return the intercept
189  return (new Intercept(vertex, raydir, makePoint(xpoint),
190  new TriangularPlate(triangle, plateid)));
191  }
192 
193 
194 
213  bool NaifDskPlateModel::isPlateIdValid(const SpiceInt plateid) const {
214  if ( !isValid() ) return (false);
215  return ( (plateid >= 1) && (plateid <= m_dsk->m_plates) );
216  }
217 
218 
219 
237  const NaifVector &raydir,
238  NaifVertex &xpoint) const {
239 
240  // Sanity check on input parameters
241  try {
242  verify( validate(vertex), "Invalid/bad dimensions on intercept source point");
243  verify( validate(raydir), "Invalid/bad dimensions on ray direction vector");
244  }
245  catch ( IException &ie ) {
247  "Invalid point source data to determine intercept",
248  _FILEINFO_);
249  }
250 
251  // Ensure a DSK file is opened or exception is thrown
252  verify( isValid(), "NAIF DSK file not opened/valid!");
253 
254  // Get the lon/lat point in radians
255  SpiceInt plateid;
256  NaifVertex xpt(3, 0.0);
257  SpiceBoolean found;
258 
259  #if defined(MAKE_THREAD_SAFE)
260  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
261  #endif
262  // Find the plate of intersection and intercept point
264  dskx02_c( m_dsk->m_handle, &m_dsk->m_dladsc, &vertex[0], &raydir[0],
265  &plateid, &xpt[0], &found);
266  // Check status
268  if ( !found ) return (0);
269 
270  // Return succesful results
271  xpoint = xpt;
272  return ( plateid );
273  }
274 
275 
276 
290  NaifTriangle NaifDskPlateModel::plate(SpiceInt plateid) const {
291 
292  // Ensure a DSK file is opened or exception is thrown
293  verify( isValid(), "NAIF DSK file not opened/valid!");
294 
295  // Sanity check on plateid
296  if ( !isPlateIdValid(plateid) ) {
297  QString mess = "Plateid = " + QString::number(plateid) + " is invalid";
298  throw IException(IException::Programmer, mess, _FILEINFO_);
299  }
300 
301  // Get the plate
302  SpiceInt nplates;
303  SpiceInt iplate[3];
304 
305  #if defined(MAKE_THREAD_SAFE)
306  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
307  #endif
308 
310  dskp02_c(m_dsk->m_handle, &m_dsk->m_dladsc, plateid, 1, &nplates,
311  ( SpiceInt(*)[3] )(iplate));
313 
314  // Get the verticies of the plates
315  NaifTriangle plate(3, 3);
316  SpiceInt n;
317  for (int i = 0 ; i < 3 ; i++) {
318  dskv02_c(m_dsk->m_handle, &m_dsk->m_dladsc, iplate[i], 1, &n,
319  ( SpiceDouble(*)[3] )(plate[i]));
320  }
322 
323  return (plate);
324  }
325 
326 
327 
346 
347  // Sanity check
348  FileName dskFile(dskfile);
349  if ( !dskFile.fileExists() ) {
350  QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
351  throw IException(IException::User, mess, _FILEINFO_);
352  }
353 
354  // Open the NAIF Digital Shape Kernel (DSK)
355  QScopedPointer<NaifDskDescriptor> dsk(new NaifDskDescriptor());
356  dsk->m_dskfile = dskfile;
358  dasopr_c( dskFile.expanded().toLatin1().data(), &dsk->m_handle );
360 
361  // Search to the first DLA segment
362  SpiceBoolean found;
363  dlabfs_c( dsk->m_handle, &dsk->m_dladsc, &found );
365  if ( !found ) {
366  QString mess = "No segments found in DSK file " + dskfile ;
367  throw IException(IException::User, mess, _FILEINFO_);
368  }
369 
371  dskgd_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_dskdsc );
372 
373  // Get size/counts
374  dskz02_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_vertices,
375  &dsk->m_plates );
377 
378  // return pointer
379  return ( dsk.take() );
380  }
381 
382 
383 
385  bool NaifDskPlateModel::verify(const bool &test, const QString &errmsg,
386  const NaifDskPlateModel::ErrAction &action)
387  const {
388  if ( ( Throw == action ) && ( !test ) ) {
389  throw IException(IException::Programmer, errmsg, _FILEINFO_);
390  }
391 
392  // Looks good
393  return ( test );
394  }
395 
396 
397 
400  verify( validate(v), "Vertex/point invalid - not a 3 vector" );
404 
405  }
406 
407 
408  NaifDskPlateModel::NaifDskDescriptor::NaifDskDescriptor() : m_dskfile(), m_handle(-1),
409  m_dladsc(), m_dskdsc(), m_plates(0),
410  m_vertices(0), m_mutex() {
411  }
412 
413 
414  NaifDskPlateModel::NaifDskDescriptor::~NaifDskDescriptor() {
415  if ( -1 != m_handle ) {
417  dascls_c ( m_handle );
419  }
420  }
421 
422 
423 } // namespace Isis
Isis::NaifDskPlateModel::verify
bool verify(const bool &test, const QString &errmsg, const ErrAction &action=Throw) const
Convenience method for generalized error reporting.
Definition: NaifDskPlateModel.cpp:385
Isis::NaifVertex
TNT::Array1D< SpiceDouble > NaifVertex
1-D Buffer[3]
Definition: NaifDskApi.h:47
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::NaifDskPlateModel::NaifDskDescriptor
NAIF DSK file descriptor.
Definition: NaifDskPlateModel.h:96
Isis::Longitude::positiveEast
double positiveEast(Angle::Units units=Angle::Radians) const
Get the longitude in the PositiveEast coordinate system.
Definition: Longitude.cpp:146
Isis::NaifDskPlateModel::plate
NaifTriangle plate(SpiceInt plateid) const
Retrieve the triangular plate identified by its ID.
Definition: NaifDskPlateModel.cpp:290
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::NaifDskPlateModel::numberVertices
SpiceInt numberVertices() const
Returns the number of vertices in the plate model.
Definition: NaifDskPlateModel.cpp:94
Isis::NaifDskPlateModel::plateIdOfIntercept
SpiceInt plateIdOfIntercept(const NaifVertex &vertex, const NaifVector &raydir, NaifVertex &xpoint) const
Primary API to determine ray intercept from observer/look direction.
Definition: NaifDskPlateModel.cpp:236
QSharedPointer< NaifDskDescriptor >
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::NaifDskPlateModel::size
int size() const
Returns the number of plates in the DSK file - mostly for conformity.
Definition: NaifDskPlateModel.cpp:79
Isis::Longitude
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:40
Isis::Displacement
Displacement is a signed length, usually in meters.
Definition: Displacement.h:31
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::NaifDskPlateModel::intercept
Intercept * intercept(const NaifVertex &vertex, const NaifVector &raydir) const
Determine a target body intercept point from an observer and look direction.
Definition: NaifDskPlateModel.cpp:179
Isis::NaifDskPlateModel::NaifDskPlateModel
NaifDskPlateModel()
Default empty constructor.
Definition: NaifDskPlateModel.cpp:44
Isis::NaifDskPlateModel::filename
QString filename() const
Returns the nane of the NAIF DSK file.
Definition: NaifDskPlateModel.cpp:71
Isis::NaifDskPlateModel::isValid
bool isValid() const
Checks validity of the object.
Definition: NaifDskPlateModel.cpp:64
Isis::NaifTriangle
TNT::Array2D< SpiceDouble > NaifTriangle
3-D triangle[3][3]
Definition: NaifDskApi.h:48
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::NaifDskPlateModel::openDSK
NaifDskDescriptor * openDSK(const QString &dskfile)
Opens a valid NAIF DSK plate model file.
Definition: NaifDskPlateModel.cpp:345
Isis::NaifDskPlateModel::isPlateIdValid
bool isPlateIdValid(const SpiceInt plateid) const
Determines if the plate ID is valid.
Definition: NaifDskPlateModel.cpp:213
Isis::NaifDskPlateModel::m_dsk
SharedNaifDskDescriptor m_dsk
Shared pointer to the NaifDskDescriptor for this plate.
Definition: NaifDskPlateModel.h:113
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
std
Namespace for the standard library.
Isis::Angle::isValid
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
Definition: Angle.cpp:95
Isis::NaifDskPlateModel::Throw
@ Throw
Throw an exception if an error occurs.
Definition: NaifDskPlateModel.h:81
Isis::Intercept
Container for a intercept condition.
Definition: Intercept.h:36
Isis::Latitude::planetocentric
double planetocentric(Angle::Units units=Angle::Radians) const
Get the latitude in the planetocentric (universal) coordinate system.
Definition: Latitude.cpp:282
Isis::NaifDskPlateModel::ErrAction
ErrAction
Enumeration to indicate whether to throw an exception if an error occurs.
Definition: NaifDskPlateModel.h:81
Isis::NaifDskPlateModel::makePoint
SurfacePoint * makePoint(const NaifVertex &v) const
Construct and return a SurfacePoint pointer
Definition: NaifDskPlateModel.cpp:399
Isis::NaifVector
TNT::Array1D< SpiceDouble > NaifVector
Namespace to contain type definitions of NAIF DSK fundamentals.
Definition: NaifDskApi.h:46
Isis::NaifDskPlateModel::NaifDskDescriptor::m_handle
SpiceInt m_handle
The DAS file handle of the DSK file.
Definition: NaifDskPlateModel.h:102
Isis::validate
bool validate(const NaifVertex &v)
Verifies that the given NaifVector or NaifVertex is 3 dimensional.
Definition: NaifDskApi.cpp:28
Isis::Displacement::Kilometers
@ Kilometers
The distance is being specified in kilometers.
Definition: Displacement.h:42
Isis::NaifDskPlateModel::point
SurfacePoint * point(const Latitude &lat, const Longitude &lon) const
Get surface intersection for a lat/lon grid point.
Definition: NaifDskPlateModel.cpp:121
Isis::SurfacePoint
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:132
Isis::TriangularPlate
Specification for an abstract triangular plate.
Definition: TriangularPlate.h:34
Isis::Angle::Radians
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:63
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126
Isis::NaifDskPlateModel::numberPlates
SpiceInt numberPlates() const
Returns the number of plates in the model.
Definition: NaifDskPlateModel.cpp:86