Isis 3 Programmer Reference
Camera.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "Camera.h"
8 
9 
10 #include <algorithm>
11 #include <cfloat>
12 #include <cmath>
13 #include <iomanip>
14 #include <stdint.h>
15 
16 #include <QDebug>
17 #include <QList>
18 #include <QPair>
19 #include <QString>
20 #include <QTime>
21 #include <QVector>
22 
23 #include "Angle.h"
24 #include "Constants.h"
25 #include "CameraDetectorMap.h"
26 #include "CameraFocalPlaneMap.h"
27 #include "CameraDistortionMap.h"
28 #include "CameraGroundMap.h"
29 #include "CameraSkyMap.h"
30 #include "DemShape.h"
31 #include "IException.h"
32 #include "IString.h"
33 #include "iTime.h"
34 #include "Latitude.h"
35 #include "Longitude.h"
36 #include "NaifStatus.h"
37 #include "Projection.h"
38 #include "ProjectionFactory.h"
39 #include "RingPlaneProjection.h"
40 #include "ShapeModel.h"
41 #include "SpecialPixel.h"
42 #include "SurfacePoint.h"
43 #include "Target.h"
44 #include "TProjection.h"
45 
46 using namespace std;
47 
48 namespace Isis {
49 
54  Camera::Camera(Cube &cube) : Sensor(cube) {
55 
56  m_instrumentId = cube.label()->findGroup("Instrument",
57  PvlObject::FindOptions::Traverse).findKeyword("InstrumentId")[0];
58 
59  m_instrumentNameLong = "Unknown";
60  m_instrumentNameShort = "Unknown";
61  m_spacecraftNameLong = "Unknown";
62  m_spacecraftNameShort = "Unknown";
63  // Get the image size which can be different than the alpha cube size
64  p_lines = cube.lineCount();
65  p_samples = cube.sampleCount();
66  p_bands = cube.bandCount();
67 
69 
70  // Get the AlphaCube information
71  p_alphaCube = new AlphaCube(cube);
72 
73  // Get the projection group if it exists
74  Pvl &lab = *cube.label();
75  if (lab.findObject("IsisCube").hasGroup("Mapping")) {
77  }
78  else {
79  p_projection = NULL;
80  }
81  p_ignoreProjection = false;
82 
83  // Initialize stuff
84  p_focalLength = 0.0;
85  p_pixelPitch = 1.0;
86  p_referenceBand = 0;
87  p_childBand = 1;
88 
89  p_distortionMap = NULL;
90  p_focalPlaneMap = NULL;
91  p_detectorMap = NULL;
92  p_groundMap = NULL;
93  p_skyMap = NULL;
94 
95  // See if we have a reference band
96  PvlGroup &inst = lab.findObject("IsisCube").findGroup("Instrument");
97  if (inst.hasKeyword("ReferenceBand")) {
98  p_referenceBand = inst["ReferenceBand"];
99  }
100 
101  p_groundRangeComputed = false;
102  p_raDecRangeComputed = false;
103  p_ringRangeComputed = false;
104  p_pointComputed = false;
105  }
106 
109  if (p_projection) {
110  delete p_projection;
111  p_projection = NULL;
112  }
113 
114  if (p_alphaCube) {
115  delete p_alphaCube;
116  p_alphaCube = NULL;
117  }
118 
119  if (p_distortionMap) {
120  delete p_distortionMap;
121  p_distortionMap = NULL;
122  }
123 
124  if (p_focalPlaneMap) {
125  delete p_focalPlaneMap;
126  p_focalPlaneMap = NULL;
127  }
128 
129  if (p_detectorMap) {
130  delete p_detectorMap;
131  p_detectorMap = NULL;
132  }
133 
134  if (p_groundMap) {
135  delete p_groundMap;
136  p_groundMap = NULL;
137  }
138 
139  if (p_skyMap) {
140  delete p_skyMap;
141  p_skyMap = NULL;
142  }
143  }
144 
145 
154  bool Camera::SetImage(const double sample, const double line) {
155  p_childSample = sample;
156  p_childLine = line;
157  p_pointComputed = true;
158 
159  // get shape
160  // TODO: we need to validate this pointer (somewhere)
161  ShapeModel *shape = target()->shape();
162  shape->clearSurfacePoint(); // Set initial condition for ShapeModel
163 
164  // Case of no map projection
165  if (p_projection == NULL || p_ignoreProjection) {
166  // Convert to parent coordinate (remove crop, pad, shrink, enlarge)
167  double parentSample = p_alphaCube->AlphaSample(sample);
168  double parentLine = p_alphaCube->AlphaLine(line);
169  bool success = false;
170  success = p_detectorMap->SetParent(parentSample, parentLine);
171  // Convert from parent to detector
172  if (success) {
173  double detectorSample = p_detectorMap->DetectorSample();
174  double detectorLine = p_detectorMap->DetectorLine();
175  success = p_focalPlaneMap->SetDetector(detectorSample, detectorLine);
176  // Now Convert from detector to distorted focal plane
177  if (success) {
178  double focalPlaneX = p_focalPlaneMap->FocalPlaneX();
179  double focalPlaneY = p_focalPlaneMap->FocalPlaneY();
180  success = p_distortionMap->SetFocalPlane(focalPlaneX, focalPlaneY);
181  // Remove optical distortion
182  if (success) {
183  // Map to the ground
187  return p_groundMap->SetFocalPlane(x, y, z);
188  }
189  }
190  }
191  }
192 
193  // The projection is a sky map
194  else if (p_projection->IsSky()) {
195  return SetImageSkyMapProjection(sample, line, shape);
196  }
197 
198  // We have map projected camera model
199  else {
200  return SetImageMapProjection(sample, line, shape);
201  }
202 
203  // failure
204  shape->clearSurfacePoint();
205  return false;
206  }
207 
208 
228  bool Camera::SetImage(const double sample, const double line, const double deltaT) {
229  p_childSample = sample;
230  p_childLine = line;
231  p_pointComputed = true;
232 
233  // get shape
234  // TODO: we need to validate this pointer (somewhere)
235  ShapeModel *shape = target()->shape();
236  shape->clearSurfacePoint(); // Set initial condition for ShapeModel
237 
238  // Case of no map projection
239  if (p_projection == NULL || p_ignoreProjection) {
240  // Convert to parent coordinate (remove crop, pad, shrink, enlarge)
241  double parentSample = p_alphaCube->AlphaSample(sample);
242  double parentLine = p_alphaCube->AlphaLine(line);
243  bool success = false;
244  success = p_detectorMap->SetParent(parentSample, parentLine, deltaT);
245  // Convert from parent to detector
246  if (success) {
247  double detectorSample = p_detectorMap->DetectorSample();
248  double detectorLine = p_detectorMap->DetectorLine();
249  success = p_focalPlaneMap->SetDetector(detectorSample, detectorLine);
250  // Now Convert from detector to distorted focal plane
251  if (success) {
252  double focalPlaneX = p_focalPlaneMap->FocalPlaneX();
253  double focalPlaneY = p_focalPlaneMap->FocalPlaneY();
254  success = p_distortionMap->SetFocalPlane(focalPlaneX, focalPlaneY);
255  // Remove optical distortion
256  if (success) {
257  // Map to the ground
261  return p_groundMap->SetFocalPlane(x, y, z);
262  }
263  }
264  }
265  }
266 
267  // The projection is a sky map
268  else if (p_projection->IsSky()) {
269  return SetImageSkyMapProjection(sample, line, shape);
270  }
271 
272  // We have map projected camera model
273  else {
274  return SetImageMapProjection(sample, line, shape);
275  }
276 
277  // failure
278  shape->clearSurfacePoint();
279  return false;
280  }
281 
282 
294  bool Camera::SetImageMapProjection(const double sample, const double line, ShapeModel *shape) {
295  Latitude lat;
296  Longitude lon;
297  Distance rad;
298  if (shape->name() != "Plane") { // this is the normal behavior
299  if (p_projection->SetWorld(sample, line)) {
300  TProjection *tproj = (TProjection *) p_projection;
301  lat = Latitude(tproj->UniversalLatitude(), Angle::Degrees);
303  rad = Distance(LocalRadius(lat, lon));
304  if (!rad.isValid()) {
305  shape->setHasIntersection(false);
306  return false;
307  }
308  SurfacePoint surfPt(lat, lon, rad);
309  if (SetGround(surfPt)) {
310  p_childSample = sample;
311  p_childLine = line;
312 
313  shape->setHasIntersection(true);
314  return true;
315  }
316  }
317  }
318  else { // shape is ring plane
319  if (p_projection->SetWorld(sample, line)) {
321  lat = Latitude(0.0, Angle::Degrees);
324 
325  if (!rad.isValid()) {
326  shape->setHasIntersection(false);
327  return false;
328  }
329  SurfacePoint surfPt(lat, lon, rad);
330  if (SetGround(surfPt)) {
331  p_childSample = sample;
332  p_childLine = line;
333 
334  shape->setHasIntersection(true);
335  return true;
336  }
337  }
338  }
339  shape->clearSurfacePoint();
340  return false;
341  }
342 
343 
355  bool Camera::SetImageSkyMapProjection(const double sample, const double line, ShapeModel *shape) {
356  TProjection *tproj = (TProjection *) p_projection;
357  if (tproj->SetWorld(sample, line)) {
359  tproj->UniversalLatitude())) {
360  p_childSample = sample;
361  p_childLine = line;
362 
363  return HasSurfaceIntersection();
364  }
365  }
366  shape->clearSurfacePoint();
367  return false;
368  }
369 
370 
380  bool Camera::SetUniversalGround(const double latitude, const double longitude) {
381  // Convert lat/lon or rad/az (i.e. ring rad / ring lon) to undistorted focal plane x/y
383  Longitude(longitude, Angle::Degrees))) {
384  return RawFocalPlanetoImage();
385  }
386 
388  return false;
389  }
390 
391 
401  bool Camera::SetGround(Latitude latitude, Longitude longitude) {
402  ShapeModel *shape = target()->shape();
403  Distance localRadius;
404 
405  if (shape->name() != "Plane") { // this is the normal behavior
406  localRadius = LocalRadius(latitude, longitude);
407  }
408  else {
409  localRadius = Distance(latitude.degrees(),Distance::Kilometers);
410  latitude = Latitude(0.,Angle::Degrees);
411  }
412 
413  if (!localRadius.isValid()) {
415  return false;
416  }
417 
418  return SetGround(SurfacePoint(latitude, longitude, localRadius));
419  }
420 
421 
422 
431  bool Camera::SetGround(const SurfacePoint & surfacePt) {
432  ShapeModel *shape = target()->shape();
433  if (!surfacePt.Valid()) {
434  shape->clearSurfacePoint();
435  return false;
436  }
437 
438  // Convert lat/lon to undistorted focal plane x/y
439  if (p_groundMap->SetGround(surfacePt)) {
440  return RawFocalPlanetoImage();
441  }
442 
443  shape->clearSurfacePoint();
444  return false;
445  }
446 
447 
456  double ux = p_groundMap->FocalPlaneX();
457  double uy = p_groundMap->FocalPlaneY();
458 
459  // get shape
460  // TODO: we need to validate this pointer (somewhere)
461  ShapeModel *shape = target()->shape();
462 
463  //cout << "undistorted focal plane: " << ux << " " << uy << endl; //debug
464  //cout.precision(15);
465  //cout << "Backward Time: " << Time().Et() << endl;
466  // Convert undistorted x/y to distorted x/y
467  bool success = p_distortionMap->SetUndistortedFocalPlane(ux, uy);
468  if (success) {
469  double focalPlaneX = p_distortionMap->FocalPlaneX();
470  double focalPlaneY = p_distortionMap->FocalPlaneY();
471  //cout << "focal plane: " << focalPlaneX << " " << focalPlaneY << endl; //debug
472  // Convert distorted x/y to detector position
473  success = p_focalPlaneMap->SetFocalPlane(focalPlaneX, focalPlaneY);
474  if (success) {
475  double detectorSample = p_focalPlaneMap->DetectorSample();
476  double detectorLine = p_focalPlaneMap->DetectorLine();
477  //cout << "detector: " << detectorSample << " " << detectorLine << endl;
478  // Convert detector to parent position
479  success = p_detectorMap->SetDetector(detectorSample, detectorLine);
480  if (success) {
481  double parentSample = p_detectorMap->ParentSample();
482  double parentLine = p_detectorMap->ParentLine();
483  //cout << "cube: " << parentSample << " " << parentLine << endl; //debug
484  if (p_projection == NULL || p_ignoreProjection) {
485  p_childSample = p_alphaCube->BetaSample(parentSample);
486  p_childLine = p_alphaCube->BetaLine(parentLine);
487  p_pointComputed = true;
488  shape->setHasIntersection(true);
489  return true;
490  }
491  else if (p_projection->IsSky()) {
492  if (p_projection->SetGround(Declination(), RightAscension())) {
495  p_pointComputed = true;
496  shape->setHasIntersection(true);
497  return true;
498  }
499  }
504  p_pointComputed = true;
505  shape->setHasIntersection(true);
506  return true;
507  }
508  }
509  else { // ring plane
510  // UniversalLongitude should return azimuth (ring longitude) in this case
511  // TODO:
512  // when we make the change to real azimuths this value may need to be adjusted or
513  // code changed in the shapemodel or surfacepoint class.
517  p_pointComputed = true;
518  shape->setHasIntersection(true);
519  return true;
520  }
521  }
522  }
523  }
524  }
525 
526  shape->clearSurfacePoint();
527  return false;
528  }
529 
530 
531 
542  bool Camera::SetUniversalGround(const double latitude, const double longitude,
543  const double radius) {
544  // Convert lat/lon to undistorted focal plane x/y
546  Longitude(longitude, Angle::Degrees),
547  Distance(radius, Distance::Meters)))) {
548  return RawFocalPlanetoImage(); // sets p_hasIntersection
549  }
550 
552  return false;
553  }
554 
555 
556 
583 
584 
586 
587  double thetaRad;
588  thetaRad = EmissionAngle()*DEG2RAD;
589 
590  if (thetaRad < HALFPI) {
591  return DetectorResolution()/cos(thetaRad);
592 
593  }
594  return Isis::Null;
595 
596  }
597 
598  return Isis::Null;
599 
600  }
601 
602 
609  if (HasSurfaceIntersection()) {
610  double sB[3];
611  instrumentPosition(sB);
612  double pB[3];
613  Coordinate(pB);
614  double a = sB[0] - pB[0];
615  double b = sB[1] - pB[1];
616  double c = sB[2] - pB[2];
617  double dist = sqrt(a * a + b * b + c * c) * 1000.0;
618  return dist / (p_focalLength / p_pixelPitch);
619  }
620  return Isis::Null;
621  }
622 
623 
631  }
632 
641  }
642 
643 
651  }
652 
653 
663  }
664 
665 
671  double lineRes = LineResolution();
672  double sampRes = SampleResolution();
673  if (lineRes < 0.0) return Isis::Null;
674  if (sampRes < 0.0) return Isis::Null;
675  return (lineRes + sampRes) / 2.0;
676  }
677 
678 
686  double lineRes = ObliqueLineResolution();
687  double sampRes = ObliqueSampleResolution();
688  if (lineRes < 0.0) return Isis::Null;
689  if (sampRes < 0.0) return Isis::Null;
690  return (lineRes + sampRes) / 2.0;
691  }
692 
693 
701  return p_maxres;
702  }
703 
704 
712  return p_minres;
713  }
714 
715 
723  return p_minobliqueres;
724  }
725 
726 
734  return p_maxobliqueres;
735  }
736 
737 
742  // Software adjustment is needed if we get here -- call RingRangeResolution instead
743  if (target()->shape()->name() == "Plane") {
744  IString msg = "Images with plane targets should use Camera method RingRangeResolution ";
745  msg += "instead of GroundRangeResolution";
746  throw IException(IException::Programmer, msg, _FILEINFO_);
747  }
748 
749  // Have we already done this
750  if (p_groundRangeComputed) return;
751  p_groundRangeComputed = true;
752 
753  bool computed = p_pointComputed;
754  double originalSample = Sample();
755  double originalLine = Line();
756  int originalBand = Band();
757 
758  // Initializations
759  p_minlat = DBL_MAX;
760  p_minlon = DBL_MAX;
761  p_minlon180 = DBL_MAX;
762  p_maxlat = -DBL_MAX;
763  p_maxlon = -DBL_MAX;
764  p_maxlon180 = -DBL_MAX;
765  p_minres = DBL_MAX;
766  p_maxres = -DBL_MAX;
767  p_minobliqueres = DBL_MAX;
768  p_maxobliqueres = -DBL_MAX;
769 
770  // See if we have band dependence and loop for the appropriate number of bands
771  int eband = p_bands;
772  if (IsBandIndependent()) eband = 1;
773  for (int band = 1; band <= eband; band++) {
774  SetBand(band);
775 
776  // Loop for each line testing the left and right sides of the image
777  for (int line = 1; line <= p_lines + 1; line++) {
778  // Look for the first good lat/lon on the left edge of the image
779  // If it is the first or last line then test the whole line
780  int samp;
781  for (samp = 1; samp <= p_samples + 1; samp++) {
782 
783  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
784  double lat = UniversalLatitude();
785  double lon = UniversalLongitude();
786  if (lat < p_minlat) p_minlat = lat;
787  if (lat > p_maxlat) p_maxlat = lat;
788  if (lon < p_minlon) p_minlon = lon;
789  if (lon > p_maxlon) p_maxlon = lon;
790 
791  if (lon > 180.0) lon -= 360.0;
792  if (lon < p_minlon180) p_minlon180 = lon;
793  if (lon > p_maxlon180) p_maxlon180 = lon;
794 
795  double res = PixelResolution();
796  if (res > 0.0) {
797  if (res < p_minres) p_minres = res;
798  if (res > p_maxres) p_maxres = res;
799  }
800  // Determine min/max oblique resolution
801  double obliqueres = ObliquePixelResolution();
802  if (obliqueres > 0.0) {
803  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
804  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
805 
806  }
807  if ((line != 1) && (line != p_lines + 1)) break;
808  }
809  } // end loop through samples
810 
811  //We've already checked the first and last lines.
812  if (line == 1) continue;
813  if (line == p_lines + 1) continue;
814 
815  // Look for the first good lat/lon on the right edge of the image
816  if (samp < p_samples + 1) {
817  for (samp = p_samples + 1; samp >= 1; samp--) {
818  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
819  double lat = UniversalLatitude();
820  double lon = UniversalLongitude();
821  if (lat < p_minlat) p_minlat = lat;
822  if (lat > p_maxlat) p_maxlat = lat;
823  if (lon < p_minlon) p_minlon = lon;
824  if (lon > p_maxlon) p_maxlon = lon;
825 
826  if (lon > 180.0) lon -= 360.0;
827  if (lon < p_minlon180) p_minlon180 = lon;
828  if (lon > p_maxlon180) p_maxlon180 = lon;
829 
830  double res = PixelResolution();
831  if (res > 0.0) {
832  if (res < p_minres) p_minres = res;
833  if (res > p_maxres) p_maxres = res;
834  }
835 
836  // Determine min/max oblique resolution
837  double obliqueres = ObliquePixelResolution();
838  if (obliqueres > 0.0) {
839  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
840  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
841 
842  }
843  break;
844  }
845  }
846  }
847  } // end loop through lines
848 
849  // Test at the sub-spacecraft point to see if we have a
850  // better resolution
851  double lat, lon;
852 
853  subSpacecraftPoint(lat, lon);
854  Latitude latitude(lat, Angle::Degrees);
855  Longitude longitude(lon, Angle::Degrees);
856  // get the local radius for the subspacecraft point
857  Distance radius(LocalRadius(latitude, longitude));
858  SurfacePoint testPoint;
859 
860  if (radius.isValid()) {
861 
862  testPoint = SurfacePoint(latitude, longitude, radius);
863 
864  if (SetGround(testPoint)) {
865  if (Sample() >= 0.5 && Line() >= 0.5 &&
866  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
867  double res = PixelResolution();
868  if (res > 0.0) {
869  if (res < p_minres) p_minres = res;
870  if (res > p_maxres) p_maxres = res;
871  }
872 
873  double obliqueres = ObliquePixelResolution();
874  if (obliqueres > 0.0) {
875  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
876  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
877 
878  }
879  }
880  }
881  } // end valid local (subspacecraft) radius
882 
883  // Special test for ground range to see if either pole is in the image
884  latitude = Latitude(90, Angle::Degrees);
885  longitude = Longitude(0.0, Angle::Degrees);
886  // get radius for north pole
887  radius = LocalRadius(latitude, longitude);
888 
889  if (radius.isValid()) {
890 
891  testPoint = SurfacePoint(latitude, longitude, radius);
892 
893  if (SetGround(testPoint)) {
894  if (Sample() >= 0.5 && Line() >= 0.5 &&
895  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
896  p_maxlat = 90.0;
897  p_minlon = 0.0;
898  p_maxlon = 360.0;
899  p_minlon180 = -180.0;
900  p_maxlon180 = 180.0;
901  }
902  }
903  } // end valid north polar radius
904 
905  latitude = Latitude(-90, Angle::Degrees);
906  // get radius for south pole
907  radius = LocalRadius(latitude, longitude);
908 
909  if (radius.isValid()) {
910 
911  testPoint = SurfacePoint(latitude, longitude, radius);
912  if (SetGround(testPoint)) {
913  if (Sample() >= 0.5 && Line() >= 0.5 &&
914  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
915  p_minlat = -90.0;
916  p_minlon = 0.0;
917  p_maxlon = 360.0;
918  p_minlon180 = -180.0;
919  p_maxlon180 = 180.0;
920  }
921  }
922  } // end valid south polar radius
923 
924  // Another special test for ground range as we could have the
925  // 0-360 seam running right through the image so
926  // test it as well (the increment may not be fine enough !!!)
929  lat += Angle((p_maxlat - p_minlat) / 10.0, Angle::Degrees)) {
930  if (SetGround(lat, Longitude(0.0, Angle::Degrees))) {
931  if (Sample() >= 0.5 && Line() >= 0.5 &&
932  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
933  p_minlon = 0.0;
934  p_maxlon = 360.0;
935  break;
936  }
937  } // end if set ground (lat, 0)
938 
939  // Another special test for ground range as we could have the
940  // -180-180 seam running right through the image so
941  // test it as well (the increment may not be fine enough !!!)
942  if (SetGround(lat, Longitude(180.0, Angle::Degrees))) {
943  if (Sample() >= 0.5 && Line() >= 0.5 &&
944  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
945  p_minlon180 = -180.0;
946  p_maxlon180 = 180.0;
947  break;
948  }
949  } // end if set ground (lat, 180)
950  } // end for loop (latitudes from min to max)
951  } // end for loop through bands
952 
953  SetBand(originalBand);
954 
955  if(computed) {
956  SetImage(originalSample, originalLine);
957  }
958  else {
959  p_pointComputed = false;
960  }
961 
962  if (p_minlon == DBL_MAX || p_minlat == DBL_MAX || p_maxlon == -DBL_MAX || p_maxlat == -DBL_MAX) {
963  string message = "Camera missed planet or SPICE data off.";
964  throw IException(IException::Unknown, message, _FILEINFO_);
965  }
966 
967 
968  // Checks for invalid lat/lon ranges
969 // if(p_minlon == DBL_MAX || p_minlat == DBL_MAX || p_maxlon == -DBL_MAX
970 // || p_maxlat == -DBL_MAX)
971 // {
972 // string message = "Camera missed planet or SPICE data off.";
973 // throw IException(IException::Unknown, message, _FILEINFO_);
974 // }
975  }
976 
977 
983  // TODO Add test to make sure we have a ring plane image **
984 
985  // Have we already done this
986  if (p_ringRangeComputed) return;
987 
988  p_ringRangeComputed = true;
989 
990  bool computed = p_pointComputed;
991  double originalSample = Sample();
992  double originalLine = Line();
993  int originalBand = Band();
994 
995  // Initializations
996  p_minRingRadius = DBL_MAX;
997  p_minRingLongitude = DBL_MAX;
998  p_minRingLongitude180 = DBL_MAX;
999  p_maxRingRadius = -DBL_MAX;
1000  p_maxRingLongitude = -DBL_MAX;
1001  p_maxRingLongitude180 = -DBL_MAX;
1002  p_minres = DBL_MAX;
1003  p_maxres = -DBL_MAX;
1004 
1005  // See if we have band dependence and loop for the appropriate number of bands
1006  int eband = p_bands;
1007  if (IsBandIndependent())
1008  eband = 1;
1009 
1010  for (int band = 1; band <= eband; band++) {
1011  SetBand(band);
1012 
1013  // Loop for each line testing the left and right sides of the image
1014  for (int line = 1; line <= p_lines + 1; line++) {
1015 
1016  // Look for the first good radius/azimuth on the left edge of the image
1017  // If it is the first or last line then test the whole line
1018  int samp;
1019  for (samp = 1; samp <= p_samples + 1; samp++) {
1020 
1021  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
1022  double radius = LocalRadius().meters();
1023  double azimuth = UniversalLongitude();
1024  if (radius < p_minRingRadius) p_minRingRadius = radius;
1025  if (radius > p_maxRingRadius) p_maxRingRadius = radius;
1026  if (azimuth < p_minRingLongitude) p_minRingLongitude = azimuth;
1027  if (azimuth > p_maxRingLongitude) p_maxRingLongitude = azimuth;
1028 
1029  if (azimuth > 180.0) azimuth -= 360.0;
1030  if (azimuth < p_minRingLongitude180) p_minRingLongitude180 = azimuth;
1031  if (azimuth > p_maxRingLongitude180) p_maxRingLongitude180 = azimuth;
1032 
1033  double res = PixelResolution();
1034  if (res > 0.0) {
1035  if (res < p_minres) p_minres = res;
1036  if (res > p_maxres) p_maxres = res;
1037  }
1038  if ((line != 1) && (line != p_lines + 1)) break;
1039  }
1040  }
1041  //We've already checked the first and last lines.
1042  if (line == 1) continue;
1043  if (line == p_lines + 1) continue;
1044 
1045  // Look for the first good rad/azimuth on the right edge of the image
1046  if (samp < p_samples + 1) {
1047  for(samp = p_samples + 1; samp >= 1; samp--) {
1048  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
1049  double radius = LocalRadius().meters();
1050  double azimuth = UniversalLongitude();
1051  if (radius < p_minRingRadius) p_minRingRadius = radius;
1052  if (radius > p_maxRingRadius) p_maxRingRadius = radius;
1053  if (azimuth < p_minRingLongitude) p_minRingLongitude = azimuth;
1054  if (azimuth > p_maxRingLongitude) p_maxRingLongitude = azimuth;
1055 
1056  if (azimuth > 180.0) azimuth -= 360.0;
1057  if (azimuth < p_minRingLongitude180) p_minRingLongitude180 = azimuth;
1058  if (azimuth > p_maxRingLongitude180) p_maxRingLongitude180 = azimuth;
1059 
1060  double res = PixelResolution();
1061  if (res > 0.0) {
1062  if (res < p_minres) p_minres = res;
1063  if (res > p_maxres) p_maxres = res;
1064  }
1065  break;
1066  }
1067  }
1068  }
1069  }
1070 
1071  // Test at the sub-spacecraft point to see if we have a
1072  // better resolution
1073  // TODO: is there something to this analogous for ring images?
1074 // double rad, lon;
1075 
1076 // subSpacecraftPoint(lat, lon);
1077 // Latitude latitude(lat, Angle::Degrees);
1078 // Longitude longitude(lon, Angle::Degrees);
1079 // Distance radius(LocalRadius(latitude, longitude));
1080 // SurfacePoint testPoint;
1081 
1082 // if (radius.isValid()) {
1083 
1084 // testPoint = SurfacePoint(latitude, longitude, radius);
1085 
1086 // if(SetGround(testPoint)) {
1087 // if(Sample() >= 0.5 && Line() >= 0.5 &&
1088 // Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1089 // double res = PixelResolution();
1090 // if(res > 0.0) {
1091 // if(res < p_minres) p_minres = res;
1092 // if(res > p_maxres) p_maxres = res;
1093 // }
1094 // }
1095 // }
1096 // }
1097 
1098  // Another special test for ring range as we could have the
1099  // 0-360 seam running right through the image so
1100  // test it as well (the increment may not be fine enough !!!)
1103  radius += Distance((p_maxRingRadius - p_minRingRadius) / 10.0, Distance::Meters)) {
1105  if (Sample() >= 0.5 && Line() >= 0.5 &&
1106  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1107  p_minRingLongitude = 0.0;
1108  p_maxRingLongitude = 360.0;
1109  break;
1110  }
1111  }
1112 
1113  // for (Latitude lat = Latitude(p_minlat, Angle::Degrees);
1114  // lat <= Latitude(p_maxlat, Angle::Degrees);
1115  // lat += Angle((p_maxlat - p_minlat) / 10.0, Angle::Degrees)) {
1116  // if (SetGround(lat, Longitude(0.0, Angle::Degrees))) {
1117  // if (Sample() >= 0.5 && Line() >= 0.5 &&
1118  // Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1119  // p_minlon = 0.0;
1120  // p_maxlon = 360.0;
1121  // break;
1122  // }
1123  // }
1124 
1125  // Another special test for ring range as we could have the
1126  // -180-180 seam running right through the image so
1127  // test it as well (the increment may not be fine enough !!!)
1129  if (Sample() >= 0.5 && Line() >= 0.5 &&
1130  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1131  p_minRingLongitude180 = -180.0;
1132  p_maxRingLongitude180 = 180.0;
1133  break;
1134  }
1135  }
1136  }
1137  } // end loop over bands
1138 
1139  SetBand(originalBand);
1140 
1141  if (computed) {
1142  SetImage(originalSample, originalLine);
1143  }
1144  else {
1145  p_pointComputed = false;
1146  }
1147 
1148  // Checks for invalid radius/lon ranges
1149  if (p_minRingRadius == DBL_MAX || p_minRingRadius == DBL_MAX
1150  || p_minRingLongitude == DBL_MAX || p_maxRingLongitude == -DBL_MAX) {
1151  string message = "RingPlane ShapeModel - Camera missed plane or SPICE data off.";
1152  throw IException(IException::Unknown, message, _FILEINFO_);
1153  }
1154  }
1155 
1156 
1166  double minlat, minlon, maxlat, maxlon;
1167  return GroundRange(minlat, maxlat, minlon, maxlon, pvl);
1168  }
1169 
1182  bool Camera::GroundRange(double &minlat, double &maxlat,
1183  double &minlon, double &maxlon,
1184  Pvl &pvl) {
1185  // Compute the ground range and resolution
1187 
1188  // Get the default radii
1189  Distance localRadii[3];
1190  radii(localRadii);
1191  Distance &a = localRadii[0];
1192  Distance &b = localRadii[2];
1193 
1194  // See if the PVL overrides the radii
1195  PvlGroup map = pvl.findGroup("Mapping", Pvl::Traverse);
1196 
1197  if(map.hasKeyword("EquatorialRadius"))
1198  a = Distance(toDouble(map["EquatorialRadius"][0]), Distance::Meters);
1199 
1200  if(map.hasKeyword("PolarRadius"))
1201  b = Distance(toDouble(map["PolarRadius"][0]), Distance::Meters);
1202 
1203  // Convert to planetographic if necessary
1204  minlat = p_minlat;
1205  maxlat = p_maxlat;
1206  if(map.hasKeyword("LatitudeType")) {
1207  QString latType = (QString) map["LatitudeType"];
1208  if (latType.toUpper() == "PLANETOGRAPHIC") {
1209  if (abs(minlat) < 90.0) { // So tan doesn't fail
1210  minlat *= PI / 180.0;
1211  minlat = atan(tan(minlat) * (a / b) * (a / b));
1212  minlat *= 180.0 / PI;
1213  }
1214 
1215  if(abs(maxlat) < 90.0) { // So tan doesn't fail
1216  maxlat *= PI / 180.0;
1217  maxlat = atan(tan(maxlat) * (a / b) * (a / b));
1218  maxlat *= 180.0 / PI;
1219  }
1220  }
1221  }
1222 
1223  // Assume 0 to 360 domain but change it if necessary
1224  minlon = p_minlon;
1225  maxlon = p_maxlon;
1226  bool domain360 = true;
1227  if(map.hasKeyword("LongitudeDomain")) {
1228  QString lonDomain = (QString) map["LongitudeDomain"];
1229  if(lonDomain.toUpper() == "180") {
1230  minlon = p_minlon180;
1231  maxlon = p_maxlon180;
1232  domain360 = false;
1233  }
1234  }
1235 
1236  // Convert to the proper longitude direction
1237  if(map.hasKeyword("LongitudeDirection")) {
1238  QString lonDirection = (QString) map["LongitudeDirection"];
1239  if(lonDirection.toUpper() == "POSITIVEWEST") {
1240  double swap = minlon;
1241  minlon = -maxlon;
1242  maxlon = -swap;
1243  }
1244  }
1245 
1246  // Convert to the proper longitude domain
1247  if(domain360) {
1248  while(minlon < 0.0) {
1249  minlon += 360.0;
1250  maxlon += 360.0;
1251  }
1252  while(minlon > 360.0) {
1253  minlon -= 360.0;
1254  maxlon -= 360.0;
1255  }
1256  }
1257  else {
1258  while(minlon < -180.0) {
1259  minlon += 360.0;
1260  maxlon += 360.0;
1261  }
1262  while(minlon > 180.0) {
1263  minlon -= 360.0;
1264  maxlon -= 360.0;
1265  }
1266  }
1267 
1268  // Now return if it crosses the longitude domain boundary
1269  if((maxlon - minlon) > 359.0) return true;
1270  return false;
1271  }
1272 
1286  bool Camera::ringRange(double &minRingRadius, double &maxRingRadius,
1287  double &minRingLongitude, double &maxRingLongitude, Pvl &pvl) {
1288  // Compute the ring range and resolution
1290 
1291  // Get the mapping group
1292  PvlGroup map = pvl.findGroup("Mapping", Pvl::Traverse);
1293 
1294  // Get the ring radius range
1295  minRingRadius = p_minRingRadius;
1296  maxRingRadius = p_maxRingRadius;
1297 
1298  // Assume 0 to 360 domain but change it if necessary
1299  minRingLongitude = p_minRingLongitude;
1300  maxRingLongitude = p_maxRingLongitude;
1301  bool domain360 = true;
1302  if (map.hasKeyword("RingLongitudeDomain")) {
1303  QString ringLongitudeDomain = (QString) map["RingLongitudeDomain"];
1304  if (ringLongitudeDomain == "180") {
1305  minRingLongitude = p_minRingLongitude180;
1306  maxRingLongitude = p_maxRingLongitude180;
1307  domain360 = false;
1308  }
1309  }
1310 
1311  // Convert to the proper azimuth direction
1312  if (map.hasKeyword("RingLongitudeDirection")) {
1313  QString ringLongitudeDirection = (QString) map["RingLongitudeDirection"];
1314  if (ringLongitudeDirection.toUpper() == "Clockwise") {
1315  double swap = minRingLongitude;
1316  minRingLongitude = -maxRingLongitude;
1317  maxRingLongitude = -swap;
1318  }
1319  }
1320 
1321  // Convert to the proper azimuth domain
1322  if (domain360) {
1323  while (minRingLongitude < 0.0) {
1324  minRingLongitude += 360.0;
1325  maxRingLongitude += 360.0;
1326  }
1327  while (minRingLongitude > 360.0) {
1328  minRingLongitude -= 360.0;
1329  maxRingLongitude -= 360.0;
1330  }
1331  }
1332  else {
1333  while (minRingLongitude < -180.0) {
1334  minRingLongitude += 360.0;
1335  maxRingLongitude += 360.0;
1336  }
1337  while (minRingLongitude > 180.0) {
1338  minRingLongitude -= 360.0;
1339  maxRingLongitude -= 360.0;
1340  }
1341  }
1342 
1343  // Now return if it crosses the azimuth domain boundary
1344  if ((maxRingLongitude - minRingLongitude) > 359.0) {
1345  return true;
1346  }
1347  return false;
1348  }
1349 
1350 
1357  PvlGroup map("Mapping");
1358  map += PvlKeyword("TargetName", target()->name());
1359 
1360  std::vector<Distance> radii = target()->radii();
1361  map += PvlKeyword("EquatorialRadius", toString(radii[0].meters()), "meters");
1362  map += PvlKeyword("PolarRadius", toString(radii[2].meters()), "meters");
1363 
1364  map += PvlKeyword("LatitudeType", "Planetocentric");
1365  map += PvlKeyword("LongitudeDirection", "PositiveEast");
1366  map += PvlKeyword("LongitudeDomain", "360");
1367 
1369  map += PvlKeyword("MinimumLatitude", toString(p_minlat));
1370  map += PvlKeyword("MaximumLatitude", toString(p_maxlat));
1371  map += PvlKeyword("MinimumLongitude", toString(p_minlon));
1372  map += PvlKeyword("MaximumLongitude", toString(p_maxlon));
1373  map += PvlKeyword("PixelResolution", toString(p_minres));
1374 
1375  map += PvlKeyword("ProjectionName", "Sinusoidal");
1376  pvl.addGroup(map);
1377  }
1378 
1379 
1386  if (target()->shape()->name() != "Plane") {
1387  // If we get here and we don't have a plane, throw an error
1388  IString msg = "A ring plane projection has been requested on an image whose shape is not a ring plane. ";
1389  msg += "Rerun spiceinit with shape=RINGPLANE. ";
1390  throw IException(IException::User, msg, _FILEINFO_);
1391  }
1392 
1393  PvlGroup map("Mapping");
1394  map += PvlKeyword("TargetName", target()->name());
1395 
1396  map += PvlKeyword("RingLongitudeDirection", "CounterClockwise");
1397  map += PvlKeyword("RingLongitudeDomain", "360");
1398 
1400  map += PvlKeyword("MinimumRingRadius", toString(p_minRingRadius));
1401  map += PvlKeyword("MaximumRingRadius", toString(p_maxRingRadius));
1402  map += PvlKeyword("MinimumRingLongitude", toString(p_minRingLongitude));
1403  map += PvlKeyword("MaximumRingLongitude", toString(p_maxRingLongitude));
1404  map += PvlKeyword("PixelResolution", toString(p_minres));
1405 
1406  map += PvlKeyword("ProjectionName", "Planar");
1407  pvl.addGroup(map);
1408  }
1409 
1412  int code = naifIkCode();
1413  QString key = "INS" + toString(code) + "_FOCAL_LENGTH";
1415  }
1416 
1419  int code = naifIkCode();
1420  QString key = "INS" + toString(code) + "_PIXEL_PITCH";
1422  }
1423 
1424 
1425 
1435  bool Camera::SetRightAscensionDeclination(const double ra, const double dec) {
1436  if (p_skyMap->SetSky(ra, dec)) {
1437  double ux = p_skyMap->FocalPlaneX();
1438  double uy = p_skyMap->FocalPlaneY();
1440  double dx = p_distortionMap->FocalPlaneX();
1441  double dy = p_distortionMap->FocalPlaneY();
1442  if (p_focalPlaneMap->SetFocalPlane(dx, dy)) {
1443  double detectorSamp = p_focalPlaneMap->DetectorSample();
1444  double detectorLine = p_focalPlaneMap->DetectorLine();
1445  if (p_detectorMap->SetDetector(detectorSamp, detectorLine)) {
1446  double parentSample = p_detectorMap->ParentSample();
1447  double parentLine = p_detectorMap->ParentLine();
1448 
1449  if (p_projection == NULL || p_ignoreProjection) {
1450  p_childSample = p_alphaCube->BetaSample(parentSample);
1451  p_childLine = p_alphaCube->BetaLine(parentLine);
1452  p_pointComputed = true;
1453  return true;
1454  }
1455  else if (p_projection->IsSky()) {
1456  if (p_projection->SetGround(dec, ra)) {
1459  p_pointComputed = true;
1460  return true;
1461  }
1462  }
1463  else if (target()->shape()->hasIntersection()) {
1465  UniversalLongitude())) {
1468  p_pointComputed = true;
1469  return true;
1470  }
1471  }
1472  }
1473  }
1474  }
1475  }
1476 
1477  return false;
1478  }
1479 
1480 
1488  void Camera::GetLocalNormal(double normal[3]) {
1489 
1490  ShapeModel *shapeModel = target()->shape();
1491  if ( !shapeModel->hasIntersection()) {
1492  // if the shape is not intersected, then clearly there is no normal
1493  normal[0] = normal[1] = normal[2] = 0.0;
1494  return;
1495  }
1496 
1497  // The DEM shape model (and it's child classes) will use 4 surrounding neighbor
1498  // points to find the local normal. The SetImage() calls used to find the
1499  // neighbors is potentially expensive, so we will not calculate the neighbors
1500  // for shape models whose calculateLocalNormal() method won't use them.
1501  bool computed = p_pointComputed;
1502  if (!shapeModel->isDEM()) {
1503  // Non-DEM case: Ellipsoid, NAIF DSK, or Plane --
1504  // Pass in a vector where all of the "neighbors" are the origin (shape model center).
1505  // We do this so that if the implementation of the calculateLocalNormal() method in
1506  // any of the non-DEM shape model classes is modified to use this vector, then an error
1507  // should be thrown instead of a segmentation fault.
1508  QVector<double *> unusedNeighborPoints(4);
1509  double origin[3] = {0, 0, 0};
1510  unusedNeighborPoints.fill(origin);
1511  shapeModel->calculateLocalNormal(unusedNeighborPoints);
1512  }
1513  else { // attempt to find local normal for DEM shapes using 4 surrounding points on the image
1514  QVector<double *> cornerNeighborPoints(4);
1515 
1516  // As documented in the doxygen above, the goal of this method is to
1517  // calculate a normal vector to the surface using the 4 corner surrounding points.
1518  double samp = Sample();
1519  double line = Line();
1520 
1521  // order of points in vector is top, bottom, left, right
1522  QList< QPair< double, double > > surroundingPoints;
1523  surroundingPoints.append(qMakePair(samp, std::nexttoward(line - 0.5, line)));
1524  surroundingPoints.append(qMakePair(samp, std::nexttoward(line + 0.5, line)));
1525  surroundingPoints.append(qMakePair(std::nexttoward(samp - 0.5, samp), line));
1526  surroundingPoints.append(qMakePair(std::nexttoward(samp + 0.5, samp), line));
1527 
1528  // save input state to be restored on return
1529  double originalSample = samp;
1530  double originalLine = line;
1531 
1532  // now we have all four points in the image, so find the same points on the surface
1533  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1534  cornerNeighborPoints[i] = new double[3];
1535  }
1536 
1537  Latitude lat;
1538  Longitude lon;
1539  Distance radius;
1540 
1541  // if this is a dsk, we only need to use the existing intercept point (plate) normal then return
1542  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1543  // If a surrounding point fails, set it to the original point
1544  if (!(SetImage(surroundingPoints[i].first, surroundingPoints[i].second))) {
1545  surroundingPoints[i].first = samp;
1546  surroundingPoints[i].second = line;
1547 
1548  // If the original point fails too, we can't get a normal. Clean up and return.
1549  if (!(SetImage(surroundingPoints[i].first, surroundingPoints[i].second))) {
1550 
1551  normal[0] = normal[1] = normal[2] = 0.0;
1552 
1553  // restore input state
1554  if (computed) {
1555  SetImage(originalSample, originalLine);
1556  }
1557  else {
1558  p_pointComputed = false;
1559  }
1560 
1561  // free memory
1562  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1563  delete [] cornerNeighborPoints[i];
1564  }
1565 
1566  return;
1567  }
1568  }
1569 
1570  SurfacePoint surfacePoint = GetSurfacePoint();
1571  lat = surfacePoint.GetLatitude();
1572  lon = surfacePoint.GetLongitude();
1573  radius = LocalRadius(lat, lon);
1574 
1575  latrec_c(radius.kilometers(), lon.radians(), lat.radians(), cornerNeighborPoints[i]);
1576  }
1577 
1578  // if the first 2 surrounding points match or the last 2 surrounding points match,
1579  // we can't get a normal. Clean up and return.
1580  if ((surroundingPoints[0].first == surroundingPoints[1].first &&
1581  surroundingPoints[0].second == surroundingPoints[1].second) ||
1582  (surroundingPoints[2].first == surroundingPoints[3].first &&
1583  surroundingPoints[2].second == surroundingPoints[3].second)) {
1584 
1585  normal[0] = normal[1] = normal[2] = 0.0;
1586 
1587  // restore input state
1588  if (!computed) {
1589  SetImage(originalSample, originalLine);
1590  }
1591  else {
1592  p_pointComputed = false;
1593  }
1594 
1595  // free memory
1596  for (int i = 0; i < cornerNeighborPoints.size(); i++)
1597  delete [] cornerNeighborPoints[i];
1598 
1599  return;
1600  }
1601 
1602  // Restore input state to original point before calculating normal
1603  SetImage(originalSample, originalLine);
1604  shapeModel->calculateLocalNormal(cornerNeighborPoints);
1605 
1606  // free memory
1607  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1608  delete [] cornerNeighborPoints[i];
1609  }
1610 
1611  }
1612 
1613  // restore input state if calculation failed and clean up.
1614  if (!shapeModel->hasNormal()) {
1615  p_pointComputed = false;
1616  return;
1617  }
1618 
1619  // restore failed computed state
1620  if (!computed) {
1621  p_pointComputed = false;
1622  }
1623 
1624  // Set the method normal values
1625  std::vector<double> localNormal(3);
1626  localNormal = shapeModel->normal();
1627  memcpy(normal, (double *) &localNormal[0], sizeof(double) * 3);
1628  }
1629 
1630 
1642  void Camera::LocalPhotometricAngles(Angle & phase, Angle & incidence,
1643  Angle & emission, bool &success) {
1644 
1645  // get local normal vector
1646  double normal[3];
1647  GetLocalNormal(normal);
1648  success = true;
1649 
1650  // Check to make sure normal is valid
1651  SpiceDouble mag;
1652  unorm_c(normal,normal,&mag);
1653  if (mag == 0.) {
1654  success = false;
1655  return;
1656  }
1657 
1658  // get a normalized surface spacecraft vector
1659  SpiceDouble surfSpaceVect[3], unitizedSurfSpaceVect[3], dist;
1660  std::vector<double> sB(3, Isis::Null);
1662 
1663  SpiceDouble pB[3];
1664  SurfacePoint surfacePoint = GetSurfacePoint();
1665  pB[0] = surfacePoint.GetX().kilometers();
1666  pB[1] = surfacePoint.GetY().kilometers();
1667  pB[2] = surfacePoint.GetZ().kilometers();
1668 
1669  vsub_c((SpiceDouble *) &sB[0], pB, surfSpaceVect);
1670  unorm_c(surfSpaceVect, unitizedSurfSpaceVect, &dist);
1671 
1672  // get a normalized surface sun vector
1673  SpiceDouble surfaceSunVect[3];
1674  vsub_c(m_uB, pB, surfaceSunVect);
1675  SpiceDouble unitizedSurfSunVect[3];
1676  unorm_c(surfaceSunVect, unitizedSurfSunVect, &dist);
1677 
1678  // use normalized surface spacecraft and surface sun vectors to calculate
1679  // the phase angle (in radians)
1680  phase = Angle(vsep_c(unitizedSurfSpaceVect, unitizedSurfSunVect),
1681  Angle::Radians);
1682 
1683  // use normalized surface spacecraft and local normal vectors to calculate
1684  // the emission angle (in radians)
1685  emission = Angle(vsep_c(unitizedSurfSpaceVect, normal),
1686  Angle::Radians);
1687 
1688  // use normalized surface sun and normal vectors to calculate the incidence
1689  // angle (in radians)
1690  incidence = Angle(vsep_c(unitizedSurfSunVect, normal),
1691  Angle::Radians);
1692 
1693 
1694  }
1695 
1696 
1707  bool Camera::RaDecRange(double &minra, double &maxra,
1708  double &mindec, double &maxdec) {
1709 
1710 
1711  bool computed = p_pointComputed;
1712  double originalSample = Sample();
1713  double originalLine = Line();
1714  int originalBand = Band();
1715 
1716  // Have we already done this
1717  if (!p_raDecRangeComputed) {
1718  p_raDecRangeComputed = true;
1719 
1720  // Initializations
1721  p_mindec = DBL_MAX;
1722  p_minra = DBL_MAX;
1723  p_minra180 = DBL_MAX;
1724  p_maxdec = -DBL_MAX;
1725  p_maxra = -DBL_MAX;
1726  p_maxra180 = -DBL_MAX;
1727 
1728  // See if we have band dependence and loop for the appropriate number of bands
1729  int eband = p_bands;
1730  if (IsBandIndependent()) eband = 1;
1731  for (int band = 1; band <= eband; band++) {
1732  this->SetBand(band);
1733 
1734  for (int line = 1; line <= p_lines; line++) {
1735  // Test left, top, and bottom sides
1736  int samp;
1737  for (samp = 1; samp <= p_samples; samp++) {
1738  SetImage((double)samp, (double)line);
1739  double ra = RightAscension();
1740  double dec = Declination();
1741  if (ra < p_minra) p_minra = ra;
1742  if (ra > p_maxra) p_maxra = ra;
1743  if (dec < p_mindec) p_mindec = dec;
1744  if (dec > p_maxdec) p_maxdec = dec;
1745 
1746  if (ra > 180.0) ra -= 360.0;
1747  if (ra < p_minra180) p_minra180 = ra;
1748  if (ra > p_maxra180) p_maxra180 = ra;
1749 
1750  if ((line != 1) && (line != p_lines)) break;
1751  }
1752 
1753  // Test right side
1754  if (samp < p_samples) {
1755  for (samp = p_samples; samp >= 1; samp--) {
1756  SetImage((double)samp, (double)line);
1757  double ra = RightAscension();
1758  double dec = Declination();
1759  if (ra < p_minra) p_minra = ra;
1760  if (ra > p_maxra) p_maxra = ra;
1761  if (dec < p_mindec) p_mindec = dec;
1762  if (dec > p_maxdec) p_maxdec = dec;
1763 
1764  if (ra > 180.0) ra -= 360.0;
1765  if (ra < p_minra180) p_minra180 = ra;
1766  if (ra > p_maxra180) p_maxra180 = ra;
1767 
1768  break;
1769  }
1770  }
1771  }
1772 
1773  // Special test for ground range to see if either pole is in the image
1774  if (SetRightAscensionDeclination(0.0, 90.0)) {
1775  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1776  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1777  p_maxdec = 90.0;
1778  p_minra = 0.0;
1779  p_maxra = 360.0;
1780  p_minra180 = -180.0;
1781  p_maxra180 = 180.0;
1782  }
1783  }
1784 
1785  if (SetRightAscensionDeclination(0.0, -90.0)) {
1786  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1787  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1788  p_mindec = -90.0;
1789  p_minra = 0.0;
1790  p_maxra = 360.0;
1791  p_minra180 = -180.0;
1792  p_maxra180 = 180.0;
1793  }
1794  }
1795 
1796  // Another special test for ground range as we could have the
1797  // 0-360 seam running right through the image so
1798  // test it as well (the increment may not be fine enough !!!)
1799  for (double dec = p_mindec; dec <= p_maxdec; dec += (p_maxdec - p_mindec) / 10.0) {
1800  if (SetRightAscensionDeclination(0.0, dec)) {
1801  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1802  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1803  p_minra = 0.0;
1804  p_maxra = 360.0;
1805  break;
1806  }
1807  }
1808  }
1809 
1810  // Another special test for ground range as we could have the
1811  // 0-360 seam running right through the image so
1812  // test it as well (the increment may not be fine enough !!!)
1813  for (double dec = p_mindec; dec <= p_maxdec; dec += (p_maxdec - p_mindec) / 10.0) {
1814  if (SetRightAscensionDeclination(180.0, dec)) {
1815  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1816  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1817  p_minra180 = -180.0;
1818  p_maxra180 = 180.0;
1819  break;
1820  }
1821  }
1822  }
1823  }
1824  }
1825 
1826  minra = p_minra;
1827  maxra = p_maxra;
1828  mindec = p_mindec;
1829  maxdec = p_maxdec;
1830 
1831  SetBand(originalBand);
1832 
1833  if (computed) {
1834  SetImage(originalSample, originalLine);
1835  }
1836  else {
1837  p_pointComputed = false;
1838  }
1839 
1840  return true;
1841  }
1842 
1843 
1850 
1851  bool computed = p_pointComputed;
1852  double originalSample = Sample();
1853  double originalLine = Line();
1854  int originalBand = Band();
1855 
1856  SetImage(1.0, 1.0);
1857  double ra1 = RightAscension();
1858  double dec1 = Declination();
1859 
1860  SetImage(1.0, (double)p_lines);
1861  double ra2 = RightAscension();
1862  double dec2 = Declination();
1863 
1864  double dist = (ra1 - ra2) * (ra1 - ra2) + (dec1 - dec2) * (dec1 - dec2);
1865  dist = sqrt(dist);
1866  double lineRes = dist / (p_lines - 1);
1867 
1868  SetImage((double)p_samples, 1.0);
1869  ra2 = RightAscension();
1870  dec2 = Declination();
1871 
1872  dist = (ra1 - ra2) * (ra1 - ra2) + (dec1 - dec2) * (dec1 - dec2);
1873  dist = sqrt(dist);
1874  double sampRes = dist / (p_samples - 1);
1875 
1876  SetBand(originalBand);
1877 
1878  if (computed) {
1879  SetImage(originalSample, originalLine);
1880  }
1881  else {
1882  p_pointComputed = false;
1883  }
1884 
1885  return (sampRes < lineRes) ? sampRes : lineRes;
1886  }
1887 
1894  if (target()->shape()->name() == "Plane") {
1895  QString msg = "North Azimuth is not available for plane target shapes.";
1896  throw IException(IException::Programmer, msg, _FILEINFO_);
1897  }
1898  // Get the latitude of your current location using the shape model
1899  // specified in the image Kernels
1900  double lat = UniversalLatitude();
1901  // We are in northern hemisphere
1902  if (lat >= 0.0) {
1903  return ComputeAzimuth(90.0, 0.0);
1904  }
1905  // We are in southern hemisphere
1906  else {
1907  double azimuth = ComputeAzimuth(-90.0, 0.0) + 180.0;
1908  if (azimuth > 360.0) azimuth = azimuth - 360.0;
1909  return azimuth;
1910  }
1911  }
1912 
1921  double lat, lon;
1922  subSolarPoint(lat, lon);
1923  return ComputeAzimuth(lat, lon);
1924  }
1925 
1926 
1935  double lat, lon;
1936  subSpacecraftPoint(lat, lon);
1937  return ComputeAzimuth(lat, lon);
1938  }
1939 
1940 
2040  double Camera::ComputeAzimuth(const double lat, const double lon) {
2041  // Make sure we are on the planet, if not, north azimuth is meaningless
2042  if (!HasSurfaceIntersection()) return Isis::Null;
2043 
2044  // Need to save the "state" of the camera so we can restore it when the
2045  // method is done
2046  bool computed = p_pointComputed;
2047 
2049 
2050  // Get the azimuth's origin point (the current position) and its radius
2051  SpiceDouble azimuthOrigin[3];
2052  Coordinate(azimuthOrigin);
2053  Distance originRadius = LocalRadius();
2054  if (!originRadius.isValid()) {
2055  return Isis::Null;
2056  }
2057 
2058  // Convert the point of interest to rectangular coordinates (x,y,z) in the
2059  // body-fixed coordinate system and use the azimuth's origin radius to avoid the
2060  // situation where the DEM does not cover the entire planet
2061  SpiceDouble pointOfInterestFromBodyCenter[3];
2062  latrec_c(originRadius.kilometers(), lon * PI / 180.0,
2063  lat * PI / 180.0, pointOfInterestFromBodyCenter);
2064 
2065  // Get the difference vector with its tail at the azimuth origin and its
2066  // head at the point of interest by subtracting vectors the vectors that
2067  // originate at the body center
2068  //
2069  // pointOfInterest = pointOfInterestFromBodyCenter - azimuthOriginFromBodyCenter
2070  //
2071  SpiceDouble pointOfInterest[3];
2072  vsub_c(pointOfInterestFromBodyCenter, azimuthOrigin, pointOfInterest);
2073 
2074  // Get the component of the difference vector pointOfInterestFromAzimuthOrigin that is
2075  // perpendicular to the origin point (i.e. project perpendicularly onto the reference plane).
2076  // This will result in a point of interest vector that is in the plane tangent to the surface at
2077  // the origin point
2078  SpiceDouble pointOfInterestProj[3];
2079  vperp_c(pointOfInterest, azimuthOrigin, pointOfInterestProj);
2080 
2081  // Unitize the tangent vector to a 1 km length vector
2082  SpiceDouble pointOfInterestProjUnit[3];
2083  vhat_c(pointOfInterestProj, pointOfInterestProjUnit);
2084 
2085  // Scale the vector to within a pixel of the azimuth's origin point.
2086  // Get pixel scale in km/pixel and divide by 2 to insure that we stay within
2087  // a pixel of the origin point
2088  double scale = (PixelResolution() / 1000.0) / 2.0;
2089  SpiceDouble pointOfInterestProjUnitScaled[3];
2090  vscl_c(scale, pointOfInterestProjUnit, pointOfInterestProjUnitScaled);
2091 
2092  // Compute the adjusted point of interest vector from the body center. This point
2093  // will be within a pixel of the origin and in the same direction as the requested
2094  // raw point of interest vector
2095  SpiceDouble adjustedPointOfInterestFromBodyCenter[3];
2096  vadd_c(azimuthOrigin, pointOfInterestProjUnitScaled, adjustedPointOfInterestFromBodyCenter);
2097 
2098  // Get the origin image coordinate
2099  double azimuthOriginSample = Sample();
2100  double azimuthOriginLine = Line();
2101 
2102  // Convert the point to a lat/lon and find out its image coordinate
2103  double adjustedPointOfInterestRad, adjustedPointOfInterestLon, adjustedPointOfInterestLat;
2104  reclat_c(adjustedPointOfInterestFromBodyCenter,
2105  &adjustedPointOfInterestRad,
2106  &adjustedPointOfInterestLon,
2107  &adjustedPointOfInterestLat);
2108  adjustedPointOfInterestLat = adjustedPointOfInterestLat * 180.0 / PI;
2109  adjustedPointOfInterestLon = adjustedPointOfInterestLon * 180.0 / PI;
2110  if (adjustedPointOfInterestLon < 0) adjustedPointOfInterestLon += 360.0;
2111 
2112  // Use the radius of the azimuth's origin point
2113  // (rather than that of the adjusted point of interest location)
2114  // to avoid the effects of topography on the calculation
2115  bool success = SetUniversalGround(adjustedPointOfInterestLat,
2116  adjustedPointOfInterestLon,
2117  originRadius.meters());
2118  if (!success) {
2119  // if the adjusted lat/lon values for the point of origin fail to be set, we can not compute
2120  // an azimuth. reset to the original sample/line and return null.
2121  SetImage(azimuthOriginSample, azimuthOriginLine);
2122  return Isis::Null;
2123  }
2124 
2125  double adjustedPointOfInterestSample = Sample();
2126  double adjustedPointOfInterestLine = Line();
2127 
2128  // TODO: Write PushState and PopState method to ensure the
2129  // internals of the class are set based on SetImage or SetGround
2130 
2131  // We now have the information needed to calculate an arctangent
2132  //
2133  //
2134  // point of interest
2135  // |\ |
2136  // | \ |
2137  // | \ | tan(A) = (delta line) / (delta sample)
2138  // delta line | \ | A = arctan( (delta line) / (delta sample) )
2139  // | \ |
2140  // | \ |
2141  // | \ |
2142  // ___________|_____A_\|_______________
2143  // delta sample |origin point
2144  // |
2145  // |
2146  // |
2147  // |
2148  // |
2149  //
2150  // in this example, the azimuth is the angle indicated by the A plus 180 degrees, since we begin
2151  // the angle rotation at the positive x-axis
2152  // This quadrant issue (i.e.need to add 180 degrees) is handled by the atan2 program
2153  //
2154  double deltaSample = adjustedPointOfInterestSample - azimuthOriginSample;
2155  double deltaLine = adjustedPointOfInterestLine - azimuthOriginLine;
2156 
2157  // Compute the angle; the azimuth is the arctangent of the line difference divided by the
2158  // sample difference; the atan2 function is used because it determines which quadrant we
2159  // are in based on the sign of the 2 arguments; the arctangent is measured in a positive
2160  // clockwise direction because the lines in the image increase downward; the arctangent
2161  // uses the 3 o'clock axis (positive sample direction) as its reference line (line of
2162  // zero degrees); a good place to read about the atan2 function is at
2163  // http://en.wikipedia.org/wiki/Atan2
2164  double azimuth = 0.0;
2165  if (deltaSample != 0.0 || deltaLine != 0.0) {
2166  azimuth = atan2(deltaLine, deltaSample);
2167  azimuth *= 180.0 / PI;
2168  }
2169 
2170  // Azimuth is limited to the range of 0 to 360
2171  if (azimuth < 0.0) azimuth += 360.0;
2172  if (azimuth > 360.0) azimuth -= 360.0;
2173 
2175 
2176  // computed is true if the sample/line or lat/lon were reset in this method
2177  // to find the location of the point of interest
2178  // If so, reset "state" of camera to the original sample/line
2179  if (computed) {
2180  SetImage(azimuthOriginSample, azimuthOriginLine);
2181  }
2182  else {
2183  p_pointComputed = false;
2184  }
2185 
2186  return azimuth;
2187  }
2188 
2189 
2197 
2198  // Get the xyz coordinates for the spacecraft and point we are interested in
2199  double coord[3], spCoord[3];
2200  Coordinate(coord);
2201  instrumentPosition(spCoord);
2202 
2203  // Get the angle between the 2 points and convert to degrees
2204  double a = vsep_c(coord, spCoord) * 180.0 / PI;
2205  double b = 180.0 - EmissionAngle();
2206 
2207  // The three angles in a triangle must add up to 180 degrees
2208  double c = 180.0 - (a + b);
2209 
2211 
2212  return c;
2213  }
2214 
2215 
2237  double Camera::GroundAzimuth(double glat, double glon,
2238  double slat, double slon) {
2239  double a;
2240  double b;
2241  if (glat >= 0.0) {
2242  a = (90.0 - slat) * PI / 180.0;
2243  b = (90.0 - glat) * PI / 180.0;
2244  }
2245  else {
2246  a = (90.0 + slat) * PI / 180.0;
2247  b = (90.0 + glat) * PI / 180.0;
2248  }
2249 
2250  double cslon = slon;
2251  double cglon = glon;
2252  if (cslon > cglon) {
2253  if ((cslon-cglon) > 180.0) {
2254  while ((cslon-cglon) > 180.0) cslon = cslon - 360.0;
2255  }
2256  }
2257  if (cglon > cslon) {
2258  if ((cglon-cslon) > 180.0) {
2259  while ((cglon-cslon) > 180.0) cglon = cglon - 360.0;
2260  }
2261  }
2262 
2263  // Which quadrant are we in?
2264  int quad;
2265  if (slat > glat) {
2266  if (cslon > cglon) {
2267  quad = 1;
2268  }
2269  else if (cslon < cglon) {
2270  quad = 2;
2271  }
2272  else {
2273  quad = 1;
2274  }
2275  }
2276  else if (slat < glat) {
2277  if (cslon > cglon) {
2278  quad = 4;
2279  }
2280  else if (cslon < cglon) {
2281  quad = 3;
2282  }
2283  else {
2284  quad = 4;
2285  }
2286  }
2287  else {
2288  if (cslon > cglon) {
2289  quad = 1;
2290  }
2291  else if (cslon < cglon) {
2292  quad = 2;
2293  }
2294  else {
2295  return 0.0;
2296  }
2297  }
2298 
2299  double C = (cglon - cslon) * PI / 180.0;
2300  if (C < 0) C = -C;
2301  double c = acos(cos(a)*cos(b) + sin(a)*sin(b)*cos(C));
2302  double azimuth = 0.0;
2303  if (sin(b) == 0.0 || sin(c) == 0.0) {
2304  return azimuth;
2305  }
2306  double intermediate = (cos(a) - cos(b)*cos(c))/(sin(b)*sin(c));
2307  if (intermediate < -1.0) {
2308  intermediate = -1.0;
2309  }
2310  else if (intermediate > 1.0) {
2311  intermediate = 1.0;
2312  }
2313  double A = acos(intermediate) * 180.0 / PI;
2314  //double B = acos((cos(b) - cos(c)*cos(a))/(sin(c)*sin(a))) * 180.0 / PI;
2315  if (glat >= 0.0) {
2316  if (quad == 1 || quad == 4) {
2317  azimuth = A;
2318  }
2319  else if (quad == 2 || quad == 3) {
2320  azimuth = 360.0 - A;
2321  }
2322  }
2323  else {
2324  if (quad == 1 || quad == 4) {
2325  azimuth = 180.0 - A;
2326  }
2327  else if (quad == 2 || quad == 3) {
2328  azimuth = 180.0 + A;
2329  }
2330  }
2331 
2332  return azimuth;
2333  }
2334 
2335 
2342  void Camera::SetDistortionMap(CameraDistortionMap *map, bool deleteExisting) {
2343  if (deleteExisting && p_distortionMap) {
2344  delete p_distortionMap;
2345  }
2346 
2347  p_distortionMap = map;
2348  }
2349 
2350 
2358  if (p_focalPlaneMap) {
2359  delete p_focalPlaneMap;
2360  }
2361 
2362  p_focalPlaneMap = map;
2363  }
2364 
2365 
2373  if (p_detectorMap) {
2374  delete p_detectorMap;
2375  }
2376 
2377  p_detectorMap = map;
2378  }
2379 
2380 
2388  if (p_groundMap) {
2389  delete p_groundMap;
2390  }
2391 
2392  p_groundMap = map;
2393  }
2394 
2395 
2402  if (p_skyMap) {
2403  delete p_skyMap;
2404  }
2405 
2406  p_skyMap = map;
2407  }
2408 
2409 
2421  // We want to stay in unprojected space for this process
2422  bool projIgnored = p_ignoreProjection;
2423  p_ignoreProjection = true;
2424 
2425  // get the cache variables
2426  pair<double,double> ephemerisTimes = StartEndEphemerisTimes();
2427  int cacheSize = CacheSize(ephemerisTimes.first, ephemerisTimes.second);
2428 
2429  // Set a position in the image so that the PixelResolution can be calculated
2431  double tol = PixelResolution() / 100.; //meters/pix/100.
2432 
2433  if (tol < 0.0) {
2434  // Alternative calculation of ground resolution of a pixel/100
2435  double altitudeMeters;
2436  if (target()->isSky()) { // Use the unit sphere as the target
2437  altitudeMeters = 1.0;
2438  }
2439  else {
2440  altitudeMeters = SpacecraftAltitude() * 1000.;
2441  }
2442  tol = PixelPitch() * altitudeMeters / FocalLength() / 100.;
2443  }
2444 
2445  p_ignoreProjection = projIgnored;
2446 
2447  Spice::createCache(ephemerisTimes.first, ephemerisTimes.second,
2448  cacheSize, tol);
2449 
2450  setTime(ephemerisTimes.first);
2451 
2452  // Reset to band 1
2453  SetBand(1);
2454 
2455  return;
2456  }
2457 
2458 
2479  pair<double, double> Camera::StartEndEphemerisTimes() {
2480  pair<double,double> ephemerisTimes;
2481  double startTime = -DBL_MAX;
2482  double endTime = -DBL_MAX;
2483 
2484  for (int band = 1; band <= Bands(); band++) {
2485  SetBand(band);
2486  SetImage(0.5, 0.5);
2487  double etStart = time().Et();
2488  SetImage(p_alphaCube->BetaSamples() + 0.5,
2489  p_alphaCube->BetaLines() + 0.5); // need to do something if SetImage returns false???
2490  double etEnd = time().Et();
2491  if (band == 1) {
2492  startTime = min(etStart, etEnd);
2493  endTime = max(etStart, etEnd);
2494  }
2495  startTime = min(startTime, min(etStart, etEnd));
2496  endTime = max(endTime, max(etStart, etEnd));
2497  }
2498  if (startTime == -DBL_MAX || endTime == -DBL_MAX) {
2499  string msg = "Unable to find time range for the spice kernels";
2500  throw IException(IException::Programmer, msg, _FILEINFO_);
2501  }
2502  ephemerisTimes.first = startTime;
2503  ephemerisTimes.second = endTime;
2504  return ephemerisTimes;
2505  }
2506 
2507 
2527  int Camera::CacheSize(double startTime, double endTime) {
2528  int cacheSize;
2529  // BetaLines() + 1 so we get at least 2 points for interpolation
2530  cacheSize = p_alphaCube->BetaLines() + 1;
2531  if (startTime == endTime) {
2532  cacheSize = 1;
2533  }
2534  return cacheSize;
2535  }
2536 
2537 
2554  void Camera::SetGeometricTilingHint(int startSize, int endSize) {
2555  // verify the start size is a multiple of 2 greater than 2
2556  int powerOf2 = 2;
2557 
2558  // No hint if 2's are passed in
2559  if (startSize == 2 && endSize == 2) {
2562  return;
2563  }
2564 
2565  if (endSize > startSize) {
2566  IString message = "Camera::SetGeometricTilingHint End size must be smaller than the start size";
2567  throw IException(IException::Programmer, message, _FILEINFO_);
2568  }
2569 
2570  if (startSize < 4) {
2571  IString message = "Camera::SetGeometricTilingHint Start size must be at least 4";
2572  throw IException(IException::Programmer, message, _FILEINFO_);
2573  }
2574 
2575  bool foundEnd = false;
2576  while (powerOf2 > 0 && startSize != powerOf2) {
2577  if (powerOf2 == endSize) foundEnd = true;
2578  powerOf2 *= 2;
2579  }
2580 
2581  // Didnt find a solution, the integer became negative first, must not be
2582  // a power of 2
2583  if (powerOf2 < 0) {
2584  IString message = "Camera::SetGeometricTilingHint Start size must be a power of 2";
2585  throw IException(IException::Programmer, message, _FILEINFO_);
2586  }
2587 
2588  if (!foundEnd) {
2589  IString message = "Camera::SetGeometricTilingHint End size must be a power of 2 less than the start size, but greater than 2";
2590  throw IException(IException::Programmer, message, _FILEINFO_);
2591  }
2592 
2593  p_geometricTilingStartSize = startSize;
2594  p_geometricTilingEndSize = endSize;
2595  }
2596 
2597 
2605  void Camera::GetGeometricTilingHint(int &startSize, int &endSize) {
2606  startSize = p_geometricTilingStartSize;
2607  endSize = p_geometricTilingEndSize;
2608  }
2609 
2610 
2620  if (Sample() < 0.5 || Line() < 0.5) {
2621  return false;
2622  }
2623 
2624  if (Sample() > Samples() + 0.5 || Line() > Lines() + 0.5) {
2625  return false;
2626  }
2627 
2628  return true;
2629  }
2630 
2631 
2639  return p_projection != 0;
2640  }
2641 
2642 
2650  return true;
2651  }
2652 
2653 
2660  return p_referenceBand;
2661  }
2662 
2663 
2671  return p_referenceBand != 0;
2672  }
2673 
2674 
2680  void Camera::SetBand(const int band) {
2681  p_childBand = band;
2682  }
2683 
2684 
2690  double Camera::Sample() const {
2691  return p_childSample;
2692  }
2693 
2694 
2700  int Camera::Band() const {
2701  return p_childBand;
2702  }
2703 
2704 
2710  double Camera::Line() const {
2711  return p_childLine;
2712  }
2713 
2714 
2721  return PixelResolution();
2722  }
2723 
2724 
2725 
2726 
2732  double Camera::FocalLength() const {
2733  return p_focalLength;
2734  }
2735 
2736 
2742  double Camera::PixelPitch() const {
2743  return p_pixelPitch;
2744  }
2745 
2746 
2756 
2757  QList<QPointF> offsets;
2758  offsets.append(QPointF(-PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2759  -PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2760  offsets.append(QPointF(PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2761  -PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2762  offsets.append(QPointF(PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2763  PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2764  offsets.append(QPointF(-PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2765  PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2766 
2767  return offsets;
2768  }
2769 
2770 
2776  int Camera::Samples() const {
2777  return p_samples;
2778  }
2779 
2780 
2786  int Camera::Lines() const {
2787  return p_lines;
2788  }
2789 
2790 
2796  int Camera::Bands() const {
2797  return p_bands;
2798  }
2799 
2800 
2806  int Camera::ParentLines() const {
2807  return p_alphaCube->AlphaLines();
2808  }
2809 
2810 
2817  return p_alphaCube->AlphaSamples();
2818  }
2819 
2820 
2827  return p_distortionMap;
2828  }
2829 
2830 
2837  return p_focalPlaneMap;
2838  }
2839 
2840 
2847  return p_detectorMap;
2848  }
2849 
2850 
2857  return p_groundMap;
2858  }
2859 
2860 
2867  return p_skyMap;
2868  }
2869 
2870 
2877  return m_instrumentId;
2878  }
2879 
2880 
2886  QString Camera::instrumentNameLong() const {
2887  return m_instrumentNameLong;
2888  }
2889 
2890 
2897  return m_instrumentNameShort;
2898  }
2899 
2900 
2906  QString Camera::spacecraftNameLong() const {
2907  return m_spacecraftNameLong;
2908  }
2909 
2910 
2917  return m_spacecraftNameShort;
2918  }
2919 
2925  void Camera::IgnoreProjection(bool ignore) {
2926  p_ignoreProjection = ignore;
2927  }
2963  int Camera::SpkTargetId() const {
2964  return (naifSpkCode());
2965  }
2966 
3005  int Camera::SpkCenterId() const {
3006  return (naifBodyCode());
3007  }
3008 
3014  void Camera::SetFocalLength(double v) {
3015  p_focalLength = v;
3016  }
3017 
3023  void Camera::SetPixelPitch(double v) {
3024  p_pixelPitch = v;
3025  }
3026 
3038  double orgLine = Line();
3039  double orgSample = Sample();
3040  double orgDec = Declination();
3041  double orgRa = RightAscension();
3042 
3043  SetRightAscensionDeclination(orgRa, orgDec + (2 * RaDecResolution()));
3044  double y = Line() - orgLine;
3045  double x = Sample() - orgSample;
3046  double celestialNorthClockAngle = atan2(-y, x) * 180.0 / Isis::PI;
3047  celestialNorthClockAngle = 90.0 - celestialNorthClockAngle;
3048 
3049  if (celestialNorthClockAngle < 0.0) {
3050  celestialNorthClockAngle += 360.0;
3051  }
3052 
3053  SetImage(orgSample, orgLine);
3054  return celestialNorthClockAngle;
3055  }
3056 
3057 
3063  double Camera::exposureDuration() const {
3065  }
3066 
3067 
3077  double Camera::exposureDuration(const double sample, const double line, const int band) const {
3078 
3079  //If band defaults to -1, use the camera's stored band.
3080  if (band < 0) {
3081  return p_detectorMap->exposureDuration(sample, line, p_childBand);
3082  }
3083  return p_detectorMap->exposureDuration(sample, line, band);
3084  }
3085 
3086 // end namespace isis
3087 }
Isis::Distance::kilometers
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:106
Isis::Spice::radii
void radii(Distance r[3]) const
Returns the radii of the body in km.
Definition: Spice.cpp:930
Isis::Camera::SetBand
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition: Camera.cpp:2680
Isis::Camera::CacheSize
int CacheSize(double startTime, double endTime)
This method calculates the spice cache size.
Definition: Camera.cpp:2527
Isis::Angle::Degrees
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:56
Isis::Camera::~Camera
virtual ~Camera()
Destroys the Camera Object.
Definition: Camera.cpp:108
Isis::Camera::IgnoreProjection
void IgnoreProjection(bool ignore)
Set whether or not the camera should ignore the Projection.
Definition: Camera.cpp:2925
Isis::Camera::SetRightAscensionDeclination
bool SetRightAscensionDeclination(const double ra, const double dec)
Sets the right ascension declination.
Definition: Camera.cpp:1435
Isis::HALFPI
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:41
Isis::Camera::p_projection
Projection * p_projection
A pointer to the Projection.
Definition: Camera.h:541
Isis::Camera::exposureDuration
virtual double exposureDuration() const
Return the exposure duration for the pixel that the camera is set to.
Definition: Camera.cpp:3063
Isis::Camera::p_minRingRadius
double p_minRingRadius
The minimum ring radius.
Definition: Camera.h:553
Isis::CameraGroundMap::FocalPlaneX
double FocalPlaneX() const
Definition: CameraGroundMap.h:122
Isis::Camera::p_mindec
double p_mindec
The minimum declination.
Definition: Camera.h:544
Isis::Spice::time
iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions.
Definition: Spice.cpp:884
Isis::Camera::p_minlon
double p_minlon
The minimum longitude.
Definition: Camera.h:523
Isis::Camera::SetGeometricTilingHint
void SetGeometricTilingHint(int startSize=128, int endSize=8)
This method sets the best geometric tiling size for projecting from this camera model.
Definition: Camera.cpp:2554
Isis::Camera::SetImageSkyMapProjection
bool SetImageSkyMapProjection(const double sample, const double line, ShapeModel *shape)
Sets the sample/line values of the image to get the lat/lon values for a Skymap Projected image.
Definition: Camera.cpp:355
Isis::CameraSkyMap::SetSky
virtual bool SetSky(const double ra, const double dec)
Compute undistorted focal plane coordinate from ra/dec.
Definition: CameraSkyMap.cpp:65
Isis::Camera::p_skyMap
CameraSkyMap * p_skyMap
A pointer to the SkyMap.
Definition: Camera.h:568
Isis::Camera::p_maxdec
double p_maxdec
The maximum declination.
Definition: Camera.h:545
Isis::Target::shape
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:655
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::Spice::subSolarPoint
virtual void subSolarPoint(double &lat, double &lon)
Returns the sub-solar latitude/longitude in universal coordinates (0-360 positive east,...
Definition: Spice.cpp:1329
Isis::Camera::Band
int Band() const
Returns the current band.
Definition: Camera.cpp:2700
Isis::ShapeModel::clearSurfacePoint
virtual void clearSurfacePoint()
Clears or resets the current surface point.
Definition: ShapeModel.cpp:386
Isis::CameraFocalPlaneMap::FocalPlaneY
double FocalPlaneY() const
Definition: CameraFocalPlaneMap.cpp:247
Isis::Spice::subSpacecraftPoint
virtual void subSpacecraftPoint(double &lat, double &lon)
Returns the sub-spacecraft latitude/longitude in universal coordinates (0-360 positive east,...
Definition: Spice.cpp:1278
Isis::RingPlaneProjection::UniversalRingLongitude
double UniversalRingLongitude()
This returns a universal ring longitude (clockwise in 0 to 360 domain).
Definition: RingPlaneProjection.cpp:589
Isis::Spice::instrumentPosition
virtual SpicePosition * instrumentPosition() const
Accessor method for the instrument position.
Definition: Spice.cpp:1600
Isis::CameraDetectorMap
Convert between parent image coordinates and detector coordinates.
Definition: CameraDetectorMap.h:47
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::Sensor::SpacecraftAltitude
double SpacecraftAltitude()
Returns the distance from the spacecraft to the subspacecraft point in km.
Definition: Sensor.cpp:701
Isis::Camera::ParentLines
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2806
Isis::Spice::naifBodyCode
SpiceInt naifBodyCode() const
This returns the NAIF body code of the target indicated in the labels.
Definition: Spice.cpp:941
Isis::Camera::ObliquePixelResolution
virtual double ObliquePixelResolution()
Returns the oblique pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:685
Isis::Camera::SkyMap
CameraSkyMap * SkyMap()
Returns a pointer to the CameraSkyMap object.
Definition: Camera.cpp:2866
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::Camera::SpkTargetId
virtual int SpkTargetId() const
Provides target code for instruments SPK NAIF kernel.
Definition: Camera.cpp:2963
QList
This is free and unencumbered software released into the public domain.
Definition: BoxcarCachingAlgorithm.h:13
Isis::Camera::p_childLine
double p_childLine
Line value for child.
Definition: Camera.h:502
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::Camera::SetSkyMap
void SetSkyMap(CameraSkyMap *map)
Sets the Sky Map.
Definition: Camera.cpp:2401
Isis::Spice::naifIkCode
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:968
Isis::TProjection::UniversalLatitude
virtual double UniversalLatitude()
This returns a universal latitude (planetocentric).
Definition: TProjection.cpp:908
Isis::Sensor::HasSurfaceIntersection
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition: Sensor.cpp:186
Isis::Camera::SetImage
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:154
Isis::Camera::p_maxra180
double p_maxra180
The maximum right ascension in the 180 domain.
Definition: Camera.h:549
Isis::Camera::p_lines
int p_lines
The number of lines in the image.
Definition: Camera.h:536
Isis::Camera::p_minRingLongitude180
double p_minRingLongitude180
The minimum ring longitude in the 180 domain.
Definition: Camera.h:557
Isis::Camera::IntersectsLongitudeDomain
bool IntersectsLongitudeDomain(Pvl &pvl)
Checks whether the ground range intersects the longitude domain or not.
Definition: Camera.cpp:1165
Isis::DEG2RAD
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition: Constants.h:43
Isis::Camera::SetDetectorMap
void SetDetectorMap(CameraDetectorMap *map)
Sets the Detector Map.
Definition: Camera.cpp:2372
Isis::CameraDistortionMap::UndistortedFocalPlaneX
double UndistortedFocalPlaneX() const
Gets the x-value in the undistorted focal plane coordinate system.
Definition: CameraDistortionMap.cpp:237
Isis::CameraDetectorMap::DetectorSample
double DetectorSample() const
Return detector sample.
Definition: CameraDetectorMap.cpp:153
Isis::Camera::SetGroundMap
void SetGroundMap(CameraGroundMap *map)
Sets the Ground Map.
Definition: Camera.cpp:2387
Isis::Camera::Sample
virtual double Sample() const
Returns the current sample number.
Definition: Camera.cpp:2690
Isis::IException::Unknown
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:118
Isis::ShapeModel::setHasIntersection
void setHasIntersection(bool b)
Sets the flag to indicate whether this ShapeModel has an intersection.
Definition: ShapeModel.cpp:554
Isis::Camera::p_maxlon180
double p_maxlon180
The maximum longitude in the 180 domain.
Definition: Camera.h:530
Isis::Camera::m_instrumentNameLong
QString m_instrumentNameLong
Full instrument name.
Definition: Camera.h:496
Isis::CameraDetectorMap::SampleScaleFactor
virtual double SampleScaleFactor() const
Return scaling factor for computing sample resolution.
Definition: CameraDetectorMap.cpp:173
Isis::CameraDistortionMap::SetUndistortedFocalPlane
virtual bool SetUndistortedFocalPlane(double ux, double uy)
Compute distorted focal plane x/y.
Definition: CameraDistortionMap.cpp:130
Isis::CameraDetectorMap::SetParent
virtual bool SetParent(const double sample, const double line)
Compute detector position from a parent image coordinate.
Definition: CameraDetectorMap.cpp:63
Isis::Camera::ObliqueDetectorResolution
virtual double ObliqueDetectorResolution()
This method returns the Oblique Detector Resolution if the Look Vector intersects the target and if t...
Definition: Camera.cpp:582
Isis::AlphaCube::AlphaLine
double AlphaLine(double betaLine)
Returns an alpha line given a beta line.
Definition: AlphaCube.h:109
Isis::Camera::p_maxRingLongitude
double p_maxRingLongitude
The maximum ring longitude (azimuth)
Definition: Camera.h:556
Isis::Sensor::Declination
virtual double Declination()
Returns the declination angle (sky latitude).
Definition: Sensor.cpp:574
Isis::Camera::p_referenceBand
int p_referenceBand
The reference band.
Definition: Camera.h:539
Isis::CameraDistortionMap::FocalPlaneX
double FocalPlaneX() const
Gets the x-value in the focal plane coordinate system.
Definition: CameraDistortionMap.cpp:215
Isis::Camera::ObliqueSampleResolution
virtual double ObliqueSampleResolution()
Returns the oblique sample resolution at the current position in m.
Definition: Camera.cpp:639
Isis::Camera::resolution
virtual double resolution()
Returns the resolution of the camera.
Definition: Camera.cpp:2720
Isis::Camera::GroundRangeResolution
void GroundRangeResolution()
Computes the ground range and min/max resolution.
Definition: Camera.cpp:741
Isis::TProjection::Longitude
virtual double Longitude() const
This returns a longitude with correct longitude direction and domain as specified in the label object...
Definition: TProjection.cpp:823
Isis::CameraFocalPlaneMap::DetectorLine
double DetectorLine() const
Definition: CameraFocalPlaneMap.cpp:263
Isis::ShapeModel::name
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:543
Isis::Projection::projectionType
ProjectionType projectionType() const
Returns an enum value for the projection type.
Definition: Projection.cpp:198
Isis::Camera::instrumentNameLong
QString instrumentNameLong() const
This method returns the full instrument name.
Definition: Camera.cpp:2886
Isis::CameraDistortionMap::FocalPlaneY
double FocalPlaneY() const
Gets the y-value in the focal plane coordinate system.
Definition: CameraDistortionMap.cpp:226
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Camera::RaDecRange
bool RaDecRange(double &minra, double &maxra, double &mindec, double &maxdec)
Computes the RaDec range.
Definition: Camera.cpp:1707
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::Camera::DistortionMap
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition: Camera.cpp:2826
Isis::Camera::p_minlat
double p_minlat
The minimum latitude.
Definition: Camera.h:521
Isis::AlphaCube::AlphaSample
double AlphaSample(double betaSample)
Returns an alpha sample given a beta sample.
Definition: AlphaCube.h:121
Isis::SurfacePoint::GetLatitude
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Definition: SurfacePoint.cpp:1665
Isis::CameraDistortionMap::UndistortedFocalPlaneZ
double UndistortedFocalPlaneZ() const
Gets the z-value in the undistorted focal plane coordinate system.
Definition: CameraDistortionMap.cpp:260
Isis::Camera::p_maxobliqueres
double p_maxobliqueres
The maximum oblique resolution.
Definition: Camera.h:528
Isis::Spice::createCache
virtual void createCache(iTime startTime, iTime endTime, const int size, double tol)
This method creates an internal cache of spacecraft and sun positions over a specified time range.
Definition: Spice.cpp:649
Isis::Camera::HasReferenceBand
bool HasReferenceBand() const
Checks to see if the Camera object has a reference band.
Definition: Camera.cpp:2670
Isis::Projection::SetUniversalGround
virtual bool SetUniversalGround(const double coord1, const double coord2)
This method is used to set the lat/lon or radius/azimuth (i.e.
Definition: Projection.cpp:417
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::Camera::SetGround
virtual bool SetGround(Latitude latitude, Longitude longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:401
Isis::Sensor::GetSurfacePoint
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition: Sensor.cpp:255
Isis::Camera::p_bands
int p_bands
The number of bands in the image.
Definition: Camera.h:537
Isis::Camera::basicRingMapping
void basicRingMapping(Pvl &map)
Writes the basic mapping group for ring plane to the specified Pvl.
Definition: Camera.cpp:1385
Isis::CameraFocalPlaneMap::DetectorSample
double DetectorSample() const
Definition: CameraFocalPlaneMap.cpp:255
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::Sensor::RightAscension
virtual double RightAscension()
Returns the right ascension angle (sky longitude).
Definition: Sensor.cpp:561
Isis::Camera::RawFocalPlanetoImage
bool RawFocalPlanetoImage()
Computes the image coordinate for the current universal ground point.
Definition: Camera.cpp:455
Isis::Distance
Distance measurement, usually in meters.
Definition: Distance.h:34
Isis::AlphaCube::BetaLine
double BetaLine(double alphaLine)
Returns a beta line given an alpha line.
Definition: AlphaCube.h:133
Isis::Longitude
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:40
Isis::Camera::m_instrumentId
QString m_instrumentId
The InstrumentId as it appears on the cube.
Definition: Camera.h:494
Isis::CameraGroundMap
Convert between undistorted focal plane and ground coordinates.
Definition: CameraGroundMap.h:73
Isis::Spice::target
virtual Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1368
Isis::CameraSkyMap::FocalPlaneY
double FocalPlaneY() const
Definition: CameraSkyMap.h:53
Isis::Camera::p_maxres
double p_maxres
The maximum resolution.
Definition: Camera.h:526
Isis::Camera::StartEndEphemerisTimes
std::pair< double, double > StartEndEphemerisTimes()
Calculates the start and end ephemeris times.
Definition: Camera.cpp:2479
Isis::Target::radii
std::vector< Distance > radii() const
Returns the radii of the body in km.
Definition: Target.cpp:532
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::CameraSkyMap::FocalPlaneX
double FocalPlaneX() const
Definition: CameraSkyMap.h:46
Isis::Distance::Kilometers
@ Kilometers
The distance is being specified in kilometers.
Definition: Distance.h:45
Isis::Camera::p_focalLength
double p_focalLength
The focal length, in units of millimeters.
Definition: Camera.h:518
Isis::Camera::SpacecraftAzimuth
double SpacecraftAzimuth()
Return the Spacecraft Azimuth.
Definition: Camera.cpp:1934
Isis::CameraDetectorMap::exposureDuration
virtual double exposureDuration(const double sample, const double line, const int band) const
This virtual method is for returning the exposure duration of a given pixel.
Definition: CameraDetectorMap.cpp:212
Isis::Camera::p_minRingLongitude
double p_minRingLongitude
The minimum ring longitude (azimuth)
Definition: Camera.h:555
Isis::Camera::ParentSamples
int ParentSamples() const
Returns the number of samples in the parent alphacube.
Definition: Camera.cpp:2816
Isis::Sensor::setTime
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition: Sensor.cpp:97
Isis::Camera::OffNadirAngle
double OffNadirAngle()
Return the off nadir angle in degrees.
Definition: Camera.cpp:2195
Isis::Projection::WorldY
virtual double WorldY() const
This returns the world Y coordinate provided SetGround, SetCoordinate, SetUniversalGround,...
Definition: Projection.cpp:544
Isis::Camera::ringRangeResolution
void ringRangeResolution()
Analogous to above GroundRangeResolution method.
Definition: Camera.cpp:982
Isis::Camera::p_ignoreProjection
bool p_ignoreProjection
Whether or no to ignore the Projection.
Definition: Camera.h:542
Isis::Distance::Meters
@ Meters
The distance is being specified in meters.
Definition: Distance.h:43
Isis::iTime::Et
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:126
Isis::Camera::InCube
bool InCube()
This returns true if the current Sample() or Line() value is outside of the cube (meaning the point m...
Definition: Camera.cpp:2619
Isis::RingPlaneProjection
Base class for Map Projections of plane shapes.
Definition: RingPlaneProjection.h:147
Isis::ShapeModel::isDEM
virtual bool isDEM() const =0
Indicates whether this shape model is from a DEM.
Isis::Camera::SetPixelPitch
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1418
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Sensor::UniversalLongitude
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:233
Isis::Cube::lineCount
int lineCount() const
Definition: Cube.cpp:1734
Isis::Camera::p_detectorMap
CameraDetectorMap * p_detectorMap
A pointer to the DetectorMap.
Definition: Camera.h:566
Isis::Camera::p_focalPlaneMap
CameraFocalPlaneMap * p_focalPlaneMap
A pointer to the FocalPlaneMap.
Definition: Camera.h:565
Isis::Camera::GroundAzimuth
static double GroundAzimuth(double glat, double glon, double slat, double slon)
Computes and returns the ground azimuth between the ground point and another point of interest,...
Definition: Camera.cpp:2237
Isis::Camera::ComputeAzimuth
double ComputeAzimuth(const double lat, const double lon)
Computes the image azimuth value from your current position (origin) to a point of interest specified...
Definition: Camera.cpp:2040
Isis::CameraFocalPlaneMap::SetFocalPlane
virtual bool SetFocalPlane(const double dx, const double dy)
Compute detector position (sample,line) from focal plane coordinates.
Definition: CameraFocalPlaneMap.cpp:143
Isis::Spice::m_uB
SpiceDouble m_uB[3]
This contains the sun position (u) in the bodyfixed reference frame (B).
Definition: Spice.h:369
Isis::Camera::LowestObliqueImageResolution
double LowestObliqueImageResolution()
Returns the lowest/worst oblique resolution in the entire image.
Definition: Camera.cpp:721
Isis::AlphaCube::BetaLines
int BetaLines() const
Returns the number of lines in the beta cube.
Definition: AlphaCube.h:87
Isis::Camera::HighestImageResolution
double HighestImageResolution()
Returns the highest/best resolution in the entire image.
Definition: Camera.cpp:710
Isis::TProjection
Base class for Map TProjections.
Definition: TProjection.h:166
Isis::Camera::instrumentId
QString instrumentId()
This method returns the InstrumentId as it appears in the cube.
Definition: Camera.cpp:2876
Isis::Camera::p_childBand
int p_childBand
Band value for child.
Definition: Camera.h:563
Isis::Camera::p_ringRangeComputed
bool p_ringRangeComputed
Flag showing if ring range was computed successfully.
Definition: Camera.h:560
Isis::Camera::LineResolution
virtual double LineResolution()
Returns the line resolution at the current position in meters.
Definition: Camera.cpp:649
Isis::Camera::p_distortionMap
CameraDistortionMap * p_distortionMap
A pointer to the DistortionMap.
Definition: Camera.h:564
Isis::Camera::p_childSample
double p_childSample
Sample value for child.
Definition: Camera.h:501
Isis::Camera::SetUniversalGround
virtual bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:380
Isis::Camera::p_pixelPitch
double p_pixelPitch
The pixel pitch, in millimeters per pixel.
Definition: Camera.h:519
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::Distance::isValid
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:192
Isis::Cube::sampleCount
int sampleCount() const
Definition: Cube.cpp:1807
Isis::Camera::PixelIfovOffsets
virtual QList< QPointF > PixelIfovOffsets()
Returns the pixel ifov offsets from center of pixel, which defaults to the (pixel pitch * summing mod...
Definition: Camera.cpp:2755
Isis::Projection::WorldX
virtual double WorldX() const
This returns the world X coordinate provided SetGround, SetCoordinate, SetUniversalGround,...
Definition: Projection.cpp:524
Isis::CameraDetectorMap::ParentSample
double ParentSample() const
Return parent sample.
Definition: CameraDetectorMap.cpp:133
Isis::Camera::CelestialNorthClockAngle
double CelestialNorthClockAngle()
Computes the celestial north clock angle at the current line/sample or ra/dec.
Definition: Camera.cpp:3037
Isis::Camera::p_minlon180
double p_minlon180
The minimum longitude in the 180 domain.
Definition: Camera.h:529
Isis::Camera::p_alphaCube
AlphaCube * p_alphaCube
A pointer to the AlphaCube.
Definition: Camera.h:503
Isis::CameraDistortionMap
Distort/undistort focal plane coordinates.
Definition: CameraDistortionMap.h:41
Isis::Camera::p_minres
double p_minres
The minimum resolution.
Definition: Camera.h:525
Isis::Camera::SetFocalPlaneMap
void SetFocalPlaneMap(CameraFocalPlaneMap *map)
Sets the Focal Plane Map.
Definition: Camera.cpp:2357
Isis::Camera::NorthAzimuth
double NorthAzimuth()
Returns the North Azimuth.
Definition: Camera.cpp:1893
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::AlphaCube
This class is used to rewrite the "alpha" keywords out of the AlphaCube group or Instrument group.
Definition: AlphaCube.h:46
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::AlphaCube::AlphaLines
int AlphaLines() const
Returns the number of lines in the alpha cube.
Definition: AlphaCube.h:67
Isis::Camera::m_spacecraftNameLong
QString m_spacecraftNameLong
Full spacecraft name.
Definition: Camera.h:498
Isis::CameraDetectorMap::SetDetector
virtual bool SetDetector(const double sample, const double line)
Compute parent position from a detector coordinate.
Definition: CameraDetectorMap.cpp:43
Isis::Cube::bandCount
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition: Cube.cpp:1410
Isis::Angle
Defines an angle and provides unit conversions.
Definition: Angle.h:45
Isis::Projection::SetWorld
virtual bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
Definition: Projection.cpp:497
Isis::Camera::p_samples
int p_samples
The number of samples in the image.
Definition: Camera.h:535
Isis::Camera::SetImageMapProjection
bool SetImageMapProjection(const double sample, const double line, ShapeModel *shape)
Sets the sample/line values of the image to get the lat/lon values for a Map Projected image.
Definition: Camera.cpp:294
Isis::CameraDetectorMap::LineScaleFactor
virtual double LineScaleFactor() const
Return scaling factor for computing line resolution.
Definition: CameraDetectorMap.cpp:183
Isis::CameraDetectorMap::DetectorLine
double DetectorLine() const
Return detector line.
Definition: CameraDetectorMap.cpp:163
Isis::Camera::p_maxRingRadius
double p_maxRingRadius
The maximum ring radius.
Definition: Camera.h:554
Isis::SurfacePoint::GetLongitude
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Definition: SurfacePoint.cpp:1685
Isis::Camera::p_maxlon
double p_maxlon
The maximum longitude.
Definition: Camera.h:524
Isis::AlphaCube::AlphaSamples
int AlphaSamples() const
Returns the number of samples in the alpha cube.
Definition: AlphaCube.h:77
Isis::AlphaCube::BetaSample
double BetaSample(double alphaSample)
Returns a beta sample given an alpha sample.
Definition: AlphaCube.h:145
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::Camera::Bands
int Bands() const
Returns the number of bands in the image.
Definition: Camera.cpp:2796
Isis::ProjectionFactory::CreateFromCube
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
Definition: ProjectionFactory.cpp:1069
Isis::Camera::p_raDecRangeComputed
bool p_raDecRangeComputed
Flag showing if the raDec range has been computed successfully.
Definition: Camera.h:551
Isis::Camera::p_maxRingLongitude180
double p_maxRingLongitude180
The maximum ring longitude in the 180 domain.
Definition: Camera.h:558
Isis::PvlObject::addGroup
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:186
Isis::Camera::IsBandIndependent
virtual bool IsBandIndependent()
Virtual method that checks if the band is independent.
Definition: Camera.cpp:2649
Isis::Displacement::kilometers
double kilometers() const
Get the displacement in kilometers.
Definition: Displacement.cpp:94
Isis::Camera::Samples
int Samples() const
Returns the number of samples in the image.
Definition: Camera.cpp:2776
Isis::Camera::p_pointComputed
bool p_pointComputed
Flag showing if Sample/Line has been computed.
Definition: Camera.h:505
Isis::Camera::BasicMapping
void BasicMapping(Pvl &map)
Writes the basic mapping group to the specified Pvl.
Definition: Camera.cpp:1356
Isis::Camera::p_groundRangeComputed
bool p_groundRangeComputed
Flag showing if ground range was computed successfully.
Definition: Camera.h:532
Isis::Camera::RaDecResolution
double RaDecResolution()
Returns the RaDec resolution.
Definition: Camera.cpp:1849
Isis::Sensor
Class for computing sensor ground coordinates.
Definition: Sensor.h:170
Isis::Camera::p_maxra
double p_maxra
The maxumum right ascension.
Definition: Camera.h:547
Isis::Camera::p_geometricTilingStartSize
int p_geometricTilingStartSize
The ideal geometric tile size to start with when projecting.
Definition: Camera.h:571
Isis::ShapeModel::hasNormal
bool hasNormal() const
Returns surface point normal status.
Definition: ShapeModel.cpp:378
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::Camera::FocalPlaneMap
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2836
Isis::AlphaCube::BetaSamples
int BetaSamples() const
Returns the number of samples in the beta cube.
Definition: AlphaCube.h:97
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
Isis::Camera::FocalLength
double FocalLength() const
Returns the focal length.
Definition: Camera.cpp:2732
std
Namespace for the standard library.
Isis::Camera::LoadCache
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2420
Isis::CameraFocalPlaneMap::FocalPlaneX
double FocalPlaneX() const
Definition: CameraFocalPlaneMap.cpp:239
Isis::ShapeModel
Define shapes and provide utilities for Isis targets.
Definition: ShapeModel.h:62
Isis::Camera::m_instrumentNameShort
QString m_instrumentNameShort
Shortened instrument name.
Definition: Camera.h:497
Isis::CameraFocalPlaneMap
Convert between distorted focal plane and detector coordinates.
Definition: CameraFocalPlaneMap.h:85
Isis::Camera::GroundMap
CameraGroundMap * GroundMap()
Returns a pointer to the CameraGroundMap object.
Definition: Camera.cpp:2856
Isis::Camera::DetectorMap
CameraDetectorMap * DetectorMap()
Returns a pointer to the CameraDetectorMap object.
Definition: Camera.cpp:2846
Isis::Camera::PixelPitch
double PixelPitch() const
Returns the pixel pitch.
Definition: Camera.cpp:2742
Isis::Camera::PixelResolution
virtual double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:670
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::CameraFocalPlaneMap::SetDetector
virtual bool SetDetector(const double sample, const double line)
Compute distorted focal plane coordinate from detector position (sampel,line)
Definition: CameraFocalPlaneMap.cpp:164
Isis::CameraSkyMap
Convert between undistorted focal plane and ra/dec coordinates.
Definition: CameraSkyMap.h:31
Isis::Camera::SpkCenterId
virtual int SpkCenterId() const
Provides the center of motion body for SPK NAIF kernel.
Definition: Camera.cpp:3005
Isis::CameraDistortionMap::SetFocalPlane
virtual bool SetFocalPlane(double dx, double dy)
Compute undistorted focal plane x/y.
Definition: CameraDistortionMap.cpp:83
Isis::TProjection::UniversalLongitude
virtual double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
Definition: TProjection.cpp:922
Isis::Camera::GroundRange
bool GroundRange(double &minlat, double &maxlat, double &minlon, double &maxlon, Pvl &pvl)
Computes the Ground Range.
Definition: Camera.cpp:1182
Isis::Distance::meters
double meters() const
Get the distance in meters.
Definition: Distance.cpp:85
Isis::Camera::p_minobliqueres
double p_minobliqueres
The minimum oblique resolution.
Definition: Camera.h:527
Isis::Spice::instrumentBodyFixedPosition
virtual void instrumentBodyFixedPosition(double p[3]) const
Returns the spacecraft position in body-fixed frame km units.
Definition: Spice.cpp:835
Isis::Camera::p_groundMap
CameraGroundMap * p_groundMap
A pointer to the GroundMap.
Definition: Camera.h:567
Isis::Angle::degrees
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:232
Isis::Camera::GetLocalNormal
void GetLocalNormal(double normal[3])
This method will find the local normal at the current (sample, line) and set it to the passed in arra...
Definition: Camera.cpp:1488
Isis::Projection::Triaxial
@ Triaxial
These projections are used to map triaxial and irregular-shaped bodies.
Definition: Projection.h:166
Isis::CameraGroundMap::SetFocalPlane
virtual bool SetFocalPlane(const double ux, const double uy, const double uz)
Compute ground position from focal plane coordinate.
Definition: CameraGroundMap.cpp:50
Isis::Camera::HighestObliqueImageResolution
double HighestObliqueImageResolution()
Returns the highest/best oblique resolution in the entire image.
Definition: Camera.cpp:732
Isis::Camera::Lines
int Lines() const
Returns the number of lines in the image.
Definition: Camera.cpp:2786
Isis::Camera::LocalPhotometricAngles
void LocalPhotometricAngles(Angle &phase, Angle &incidence, Angle &emission, bool &success)
Calculates LOCAL photometric angles using the DEM (not ellipsoid).
Definition: Camera.cpp:1642
Isis::ShapeModel::hasIntersection
bool hasIntersection()
Returns intersection status.
Definition: ShapeModel.cpp:368
Isis::Sensor::Coordinate
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition: Sensor.cpp:196
Isis::Projection::IsSky
bool IsSky() const
Returns true if projection is sky and false if it is land.
Definition: Projection.cpp:208
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::Sensor::EmissionAngle
virtual double EmissionAngle() const
Returns the emission angle in degrees.
Definition: Sensor.cpp:324
Isis::Camera::instrumentNameShort
QString instrumentNameShort() const
This method returns the shortened instrument name.
Definition: Camera.cpp:2896
Isis::Camera::SampleResolution
virtual double SampleResolution()
Returns the sample resolution at the current position in meters.
Definition: Camera.cpp:629
Isis::Camera::Line
virtual double Line() const
Returns the current line number.
Definition: Camera.cpp:2710
Isis::Camera::spacecraftNameLong
QString spacecraftNameLong() const
This method returns the full spacecraft name.
Definition: Camera.cpp:2906
Isis::Spice::getDouble
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:1039
QVector
This is free and unencumbered software released into the public domain.
Definition: Calculator.h:18
Isis::Spice::naifSpkCode
SpiceInt naifSpkCode() const
This returns the NAIF SPK code to use when reading from SPK kernels.
Definition: Spice.cpp:950
Isis::CameraDetectorMap::ParentLine
double ParentLine() const
Return parent line.
Definition: CameraDetectorMap.cpp:143
Isis::Camera::ObliqueLineResolution
virtual double ObliqueLineResolution()
Returns the oblique line resolution at the current position in meters.
Definition: Camera.cpp:661
Isis::Camera::ReferenceBand
int ReferenceBand() const
Returns the reference band.
Definition: Camera.cpp:2659
Isis::Camera::m_spacecraftNameShort
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:499
Isis::CameraGroundMap::FocalPlaneY
double FocalPlaneY() const
Definition: CameraGroundMap.h:129
Isis::CameraDistortionMap::UndistortedFocalPlaneY
double UndistortedFocalPlaneY() const
Gets the y-value in the undistorted focal plane coordinate system.
Definition: CameraDistortionMap.cpp:248
Isis::Camera::p_minra180
double p_minra180
The minimum right ascension in the 180 domain.
Definition: Camera.h:548
Isis::Camera::LowestImageResolution
double LowestImageResolution()
Returns the lowest/worst resolution in the entire image.
Definition: Camera.cpp:699
Isis::Camera::HasProjection
bool HasProjection()
Checks to see if the camera object has a projection.
Definition: Camera.cpp:2638
Isis::Camera::SunAzimuth
double SunAzimuth()
Returns the Sun Azimuth.
Definition: Camera.cpp:1920
Isis::Camera::spacecraftNameShort
QString spacecraftNameShort() const
This method returns the shortened spacecraft name.
Definition: Camera.cpp:2916
Isis::Camera::ringRange
bool ringRange(double &minRingRadius, double &maxRingRadius, double &minRingLongitude, double &maxRingLongitude, Pvl &pvl)
Analogous to the above Ground Range method.
Definition: Camera.cpp:1286
Isis::Camera::p_maxlat
double p_maxlat
The maximum latitude.
Definition: Camera.h:522
Isis::Camera::DetectorResolution
virtual double DetectorResolution()
Returns the detector resolution at the current position in meters.
Definition: Camera.cpp:608
Isis::Camera::GetGeometricTilingHint
void GetGeometricTilingHint(int &startSize, int &endSize)
This will get the geometric tiling hint; these values are typically used for ProcessRubberSheet::SetT...
Definition: Camera.cpp:2605
Isis::SurfacePoint
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:132
Isis::Camera::p_geometricTilingEndSize
int p_geometricTilingEndSize
The ideal geometric tile size to end with when projecting.
Definition: Camera.h:573
Isis::Camera::SetFocalLength
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition: Camera.cpp:1411
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::Sensor::LocalRadius
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:267
Isis::Camera::p_minra
double p_minra
The minimum right ascension.
Definition: Camera.h:546
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::ShapeModel::normal
std::vector< double > normal()
Returns the local surface normal at the current intersection point.
Definition: ShapeModel.cpp:401
Isis::RingPlaneProjection::UniversalRingRadius
double UniversalRingRadius()
This returns a universal radius, which is just the radius in meters.
Definition: RingPlaneProjection.cpp:575
Isis::Sensor::UniversalLatitude
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:210
Isis::CameraGroundMap::SetGround
virtual bool SetGround(const Latitude &lat, const Longitude &lon)
Compute undistorted focal plane coordinate from ground position.
Definition: CameraGroundMap.cpp:76
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226
Isis::Camera::SetDistortionMap
void SetDistortionMap(CameraDistortionMap *map, bool deleteExisting=true)
Sets the Distortion Map.
Definition: Camera.cpp:2342