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
39using namespace std;
40
41namespace Isis {
42
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
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
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition Angle.h:63
Displacement is a signed length, usually in meters.
@ Kilometers
The distance is being specified in kilometers.
File name manipulation and expansion.
Definition FileName.h:100
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Container for a intercept condition.
Definition Intercept.h:36
This class is designed to encapsulate the concept of a Latitude.
Definition Latitude.h:51
This class is designed to encapsulate the concept of a Longitude.
Definition Longitude.h:40
SpiceInt m_handle
The DAS file handle of the DSK file.
bool isPlateIdValid(const SpiceInt plateid) const
Determines if the plate ID is valid.
ErrAction
Enumeration to indicate whether to throw an exception if an error occurs.
@ Throw
Throw an exception if an error occurs.
SpiceInt numberPlates() const
Returns the number of plates in the model.
SharedNaifDskDescriptor m_dsk
Shared pointer to the NaifDskDescriptor for this plate.
QString filename() const
Returns the nane of the NAIF DSK file.
Intercept * intercept(const NaifVertex &vertex, const NaifVector &raydir) const
Determine a target body intercept point from an observer and look direction.
int size() const
Returns the number of plates in the DSK file - mostly for conformity.
bool verify(const bool &test, const QString &errmsg, const ErrAction &action=Throw) const
Convenience method for generalized error reporting.
NaifTriangle plate(SpiceInt plateid) const
Retrieve the triangular plate identified by its ID.
NaifDskPlateModel()
Default empty constructor.
SurfacePoint * makePoint(const NaifVertex &v) const
Construct and return a SurfacePoint pointer
SpiceInt plateIdOfIntercept(const NaifVertex &vertex, const NaifVector &raydir, NaifVertex &xpoint) const
Primary API to determine ray intercept from observer/look direction.
bool isValid() const
Checks validity of the object.
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.
NaifDskDescriptor * openDSK(const QString &dskfile)
Opens a valid NAIF DSK plate model file.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
This class defines a body-fixed surface point.
Specification for an abstract triangular plate.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
TNT::Array1D< SpiceDouble > NaifVector
Namespace to contain type definitions of NAIF DSK fundamentals.
Definition NaifDskApi.h:46
TNT::Array2D< SpiceDouble > NaifTriangle
3-D triangle[3][3]
Definition NaifDskApi.h:48
TNT::Array1D< SpiceDouble > NaifVertex
1-D Buffer[3]
Definition NaifDskApi.h:47
bool validate(const NaifVertex &v)
Verifies that the given NaifVector or NaifVertex is 3 dimensional.
Namespace for the standard library.