Isis 3.0 Programmer Reference
Back | Home
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 <dsk_proto.h>
46 #include <SpiceDLA.h>
47 #include <SpiceDSK.h>
48 #include <SpiceUsr.h>
49 #include <SpiceZfc.h>
50 #include <SpiceZim.h>
51 
52 #include "FileName.h"
53 #include "IException.h"
54 #include "Intercept.h"
55 #include "IString.h"
56 #include "Latitude.h"
57 #include "Longitude.h"
58 #include "NaifDskApi.h"
59 #include "NaifStatus.h"
60 #include "SurfacePoint.h"
61 #include "TriangularPlate.h"
62 
63 using namespace std;
64 
65 namespace Isis {
66 
68  NaifDskPlateModel::NaifDskPlateModel() : m_dsk(0) { }
69 
70 
71 
73  NaifDskPlateModel::NaifDskPlateModel(const QString &dskfile) : m_dsk(0) {
74  m_dsk = SharedNaifDskDescriptor(openDSK(dskfile));
75  if ( !isValid() ) {
76  QString mess = "Could not open DSK file " + dskfile;
78  }
79  }
80 
81 
82 
83  NaifDskPlateModel::~NaifDskPlateModel() { }
84 
85 
86 
89  return ( !m_dsk.isNull() );
90  }
91 
92 
93 
95  QString NaifDskPlateModel::filename() const {
96  if ( isValid() ) { return (m_dsk->m_dskfile); }
97  return ( QString() );
98  }
99 
100 
101 
104  return ( numberPlates() );
105  }
106 
107 
108 
111  if ( !isValid() ) return (0);
112  return ( m_dsk->m_plates );
113  }
114 
115 
116 
119  if ( !isValid() ) return (0);
120  return ( m_dsk->m_vertices );
121  }
122 
123 
124 
146  const Longitude &lon) const {
147 
148  // Sanity check on input point
149  verify ( lat.isValid(), "Latitude parameter invalid in NaifDskPlateMode::point()" );
150  verify ( lon.isValid(), "Longitude parameter invalid in NaifDskPlateMode::point()" );
151 
152  // Ensure a DSK file is opened or exception is thrown
153  verify( isValid(), "NAIF DSK file not opened/valid!");
154 
155  // Get the lon/lat point in radians
156  SpiceDouble lonlat[2];
157  lonlat[0] = lon.positiveEast(Angle::Radians);
158  lonlat[1] = lat.planetocentric(Angle::Radians);
159  SpiceInt npoints(1);
160  NaifVertex spoint(3, 0.0);
161  SpiceInt plateId(-1);
162 
163  #if defined(MAKE_THREAD_SAFE)
164  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
165  #endif
166 
167  llgrid_pl02( m_dsk->m_handle, &m_dsk->m_dladsc, npoints,
168  (ConstSpiceDouble (*)[2]) lonlat,
169  (SpiceDouble (*)[3]) &spoint[0], &plateId);
171 
172  #if 0
173  if ( !isPlateIdValid(plateId) ) {
174  QString mess = "Plateid = " + QString::number(plateId) + " is invalid";
176  }
177  #endif
178 
179  // Other error checks???
180  return ( makePoint(spoint) );
181  }
182 
183 
184 
204  const NaifVector &raydir) const {
205  // Get the plate
206  NaifVertex xpoint;
207  SpiceInt plateid = plateIdOfIntercept(vertex, raydir, xpoint);
208  if ( !isPlateIdValid(plateid) ) return (0);
209 
210  NaifTriangle triangle = plate(plateid);
211 
212  // Return the intercept
213  return (new Intercept(vertex, raydir, makePoint(xpoint),
214  new TriangularPlate(triangle, plateid)));
215  }
216 
217 
218 
237  bool NaifDskPlateModel::isPlateIdValid(const SpiceInt plateid) const {
238  if ( !isValid() ) return (false);
239  return ( (plateid >= 1) && (plateid <= m_dsk->m_plates) );
240  }
241 
242 
243 
261  const NaifVector &raydir,
262  NaifVertex &xpoint) const {
263 
264  // Sanity check on input parameters
265  try {
266  verify( validate(vertex), "Invalid/bad dimensions on intercept source point");
267  verify( validate(raydir), "Invalid/bad dimensions on ray direction vector");
268  }
269  catch ( IException &ie ) {
271  "Invalid point source data to determine intercept",
272  _FILEINFO_);
273  }
274 
275  // Ensure a DSK file is opened or exception is thrown
276  verify( isValid(), "NAIF DSK file not opened/valid!");
277 
278  // Get the lon/lat point in radians
279  SpiceInt plateid;
280  NaifVertex xpt(3, 0.0);
281  SpiceBoolean found;
282 
283  #if defined(MAKE_THREAD_SAFE)
284  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
285  #endif
286  // Find the plate of intersection and intercept point
288  dskx02_c( m_dsk->m_handle, &m_dsk->m_dladsc, &vertex[0], &raydir[0],
289  &plateid, &xpt[0], &found);
290  // Check status
292  if ( !found ) return (0);
293 
294  // Return succesful results
295  xpoint = xpt;
296  return ( plateid );
297  }
298 
299 
300 
314  NaifTriangle NaifDskPlateModel::plate(SpiceInt plateid) const {
315 
316  // Ensure a DSK file is opened or exception is thrown
317  verify( isValid(), "NAIF DSK file not opened/valid!");
318 
319  // Sanity check on plateid
320  if ( !isPlateIdValid(plateid) ) {
321  QString mess = "Plateid = " + QString::number(plateid) + " is invalid";
323  }
324 
325  // Get the plate
326  SpiceInt nplates;
327  SpiceInt iplate[3];
328 
329  #if defined(MAKE_THREAD_SAFE)
330  QMutexLocker lock(&m_dsk->m_mutex); // Thread locking for NAIF I/O
331  #endif
332 
334  dskp02_c(m_dsk->m_handle, &m_dsk->m_dladsc, plateid, 1, &nplates,
335  ( SpiceInt(*)[3] )(iplate));
337 
338  // Get the verticies of the plates
339  NaifTriangle plate(3, 3);
340  SpiceInt n;
341  for (int i = 0 ; i < 3 ; i++) {
342  dskv02_c(m_dsk->m_handle, &m_dsk->m_dladsc, iplate[i], 1, &n,
343  ( SpiceDouble(*)[3] )(plate[i]));
344  }
346 
347  return (plate);
348  }
349 
350 
351 
370 
371  // Sanity check
372  FileName dskFile(dskfile);
373  if ( !dskFile.fileExists() ) {
374  QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
375  throw IException(IException::User, mess, _FILEINFO_);
376  }
377 
378  // Open the NAIF Digital Shape Kernel (DSK)
379  QScopedPointer<NaifDskDescriptor> dsk(new NaifDskDescriptor());
380  dsk->m_dskfile = dskfile;
382  dasopr_c( dskFile.expanded().toLatin1().data(), &dsk->m_handle );
384 
385  // Search to the first DLA segment
386  SpiceBoolean found;
387  dlabfs_c( dsk->m_handle, &dsk->m_dladsc, &found );
389  if ( !found ) {
390  QString mess = "No segments found in DSK file " + dskfile ;
391  throw IException(IException::User, mess, _FILEINFO_);
392  }
393 
395  dskgd_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_dskdsc );
396 
397  // Get size/counts
398  dskz02_c( dsk->m_handle, &dsk->m_dladsc, &dsk->m_vertices,
399  &dsk->m_plates );
401 
402  // return pointer
403  return ( dsk.take() );
404  }
405 
406 
407 
409  bool NaifDskPlateModel::verify(const bool &test, const QString &errmsg,
410  const NaifDskPlateModel::ErrAction &action)
411  const {
412  if ( ( Throw == action ) && ( !test ) ) {
414  }
415 
416  // Looks good
417  return ( test );
418  }
419 
420 
421 
424  verify( validate(v), "Vertex/point invalid - not a 3 vector" );
428 
429  }
430 
431 
432  NaifDskPlateModel::NaifDskDescriptor::NaifDskDescriptor() : m_dskfile(), m_handle(-1),
433  m_dladsc(), m_dskdsc(), m_plates(0),
434  m_vertices(0), m_mutex() {
435  }
436 
437 
438  NaifDskPlateModel::NaifDskDescriptor::~NaifDskDescriptor() {
439  if ( -1 != m_handle ) {
441  dascls_c ( m_handle );
443  }
444  }
445 
446 
447 } // namespace Isis
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:86
The distance is being specified in kilometers.
Definition: Displacement.h:54
File name manipulation and expansion.
Definition: FileName.h:111
NaifDskDescriptor * openDSK(const QString &dskfile)
Opens a valid NAIF DSK plate model file.
Throw an exception if an error occurs.
int size() const
Returns the number of plates in the DSK file - mostly for conformity.
NaifTriangle plate(SpiceInt plateid) const
Retrieve the triangular plate identified by its ID.
QString filename() const
Returns the nane of the NAIF DSK file.
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:59
SurfacePoint * point(const Latitude &lat, const Longitude &lon) const
Get surface intersection for a lat/lon grid point.
SurfacePoint * makePoint(const NaifVertex &v) const
Construct and return a SurfacePoint pointer.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
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:64
SpiceInt plateIdOfIntercept(const NaifVertex &vertex, const NaifVector &raydir, NaifVertex &xpoint) const
Primary API to determine ray intercept from observer/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:65
SpiceInt numberPlates() const
Returns the number of plates in the model.
bool verify(const bool &test, const QString &errmsg, const ErrAction &action=Throw) const
Convenience method for generalized error reporting.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
Container for a intercept condition.
Definition: Intercept.h:51
double positiveEast(Angle::Units units=Angle::Radians) const
Get the longitude in the PositiveEast coordinate system.
Definition: Longitude.cpp:159
double planetocentric(Angle::Units units=Angle::Radians) const
Get the latitude in the planetocentric (universal) coordinate system.
Definition: Latitude.cpp:295
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
bool validate(const NaifVertex &v)
Verifies that the given NaifVector or NaifVertex is 3 dimensional.
Definition: NaifDskApi.cpp:54
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.
bool isValid() const
Checks validity of the object.
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:99
bool isPlateIdValid(const SpiceInt plateid) const
Determines if the plate ID is valid.
Intercept * intercept(const NaifVertex &vertex, const NaifVector &raydir) const
Determine a target body intercept point from an observer and look direction.
SpiceInt numberVertices() const
Returns the number of vertices in the plate model.
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:76
TNT::Array2D< SpiceDouble > NaifTriangle
3-D triangle[3][3]
Definition: NaifDskApi.h:66
Unless noted otherwise, the portions of Isis written by the USGS are public domain.

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:24:21