USGS

Isis 3.0 Object Programmers' Reference

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().toAscii().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 );
388  NaifStatus::CheckErrors();
389  if ( !found ) {
390  QString mess = "No segments found in DSK file " + dskfile ;
391  throw IException(IException::User, mess, _FILEINFO_);
392  }
393 
394  NaifStatus::CheckErrors();
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 );
400  NaifStatus::CheckErrors();
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