Isis 3.0 Programmer Reference
Back | Home
Camera.cpp
Go to the documentation of this file.
1 
23 #include "Camera.h"
24 
25 
26 #include <algorithm>
27 #include <cfloat>
28 #include <cmath>
29 #include <iomanip>
30 #include <stdint.h>
31 
32 #include <QDebug>
33 #include <QList>
34 #include <QPair>
35 #include <QString>
36 #include <QTime>
37 #include <QVector>
38 
39 #include "Angle.h"
40 #include "Constants.h"
41 #include "CameraDetectorMap.h"
42 #include "CameraFocalPlaneMap.h"
43 #include "CameraDistortionMap.h"
44 #include "CameraGroundMap.h"
45 #include "CameraSkyMap.h"
46 #include "DemShape.h"
47 #include "IException.h"
48 #include "IString.h"
49 #include "iTime.h"
50 #include "Latitude.h"
51 #include "Longitude.h"
52 #include "NaifStatus.h"
53 #include "Projection.h"
54 #include "ProjectionFactory.h"
55 #include "RingPlaneProjection.h"
56 #include "ShapeModel.h"
57 #include "SpecialPixel.h"
58 #include "SurfacePoint.h"
59 #include "Target.h"
60 #include "TProjection.h"
61 
62 using namespace std;
63 
64 namespace Isis {
65 
70  Camera::Camera(Cube &cube) : Sensor(cube) {
71  m_instrumentNameLong = "Unknown";
72  m_instrumentNameShort = "Unknown";
73  m_spacecraftNameLong = "Unknown";
74  m_spacecraftNameShort = "Unknown";
75  // Get the image size which can be different than the alpha cube size
76  p_lines = cube.lineCount();
77  p_samples = cube.sampleCount();
78  p_bands = cube.bandCount();
79 
81 
82  // Get the AlphaCube information
83  p_alphaCube = new AlphaCube(cube);
84 
85  // Get the projection group if it exists
86  Pvl &lab = *cube.label();
87  if (lab.findObject("IsisCube").hasGroup("Mapping")) {
89  }
90  else {
91  p_projection = NULL;
92  }
93  p_ignoreProjection = false;
94 
95  // Initialize stuff
96  p_focalLength = 0.0;
97  p_pixelPitch = 1.0;
98  p_referenceBand = 0;
99  p_childBand = 1;
100 
101  p_distortionMap = NULL;
102  p_focalPlaneMap = NULL;
103  p_detectorMap = NULL;
104  p_groundMap = NULL;
105  p_skyMap = NULL;
106 
107  // See if we have a reference band
108  PvlGroup &inst = lab.findObject("IsisCube").findGroup("Instrument");
109  if (inst.hasKeyword("ReferenceBand")) {
110  p_referenceBand = inst["ReferenceBand"];
111  }
112 
113  p_groundRangeComputed = false;
114  p_raDecRangeComputed = false;
115  p_ringRangeComputed = false;
116  p_pointComputed = false;
117  }
118 
121  if (p_projection) {
122  delete p_projection;
123  p_projection = NULL;
124  }
125 
126  if (p_alphaCube) {
127  delete p_alphaCube;
128  p_alphaCube = NULL;
129  }
130 
131  if (p_distortionMap) {
132  delete p_distortionMap;
133  p_distortionMap = NULL;
134  }
135 
136  if (p_focalPlaneMap) {
137  delete p_focalPlaneMap;
138  p_focalPlaneMap = NULL;
139  }
140 
141  if (p_detectorMap) {
142  delete p_detectorMap;
143  p_detectorMap = NULL;
144  }
145 
146  if (p_groundMap) {
147  delete p_groundMap;
148  p_groundMap = NULL;
149  }
150 
151  if (p_skyMap) {
152  delete p_skyMap;
153  p_skyMap = NULL;
154  }
155  }
156 
157 
166  bool Camera::SetImage(const double sample, const double line) {
167  p_childSample = sample;
168  p_childLine = line;
169  p_pointComputed = true;
170 
171  // get shape
172  // TODO: we need to validate this pointer (somewhere)
173  ShapeModel *shape = target()->shape();
174  shape->clearSurfacePoint(); // Set initial condition for ShapeModel
175 
176  // Case of no map projection
177  if (p_projection == NULL || p_ignoreProjection) {
178  // Convert to parent coordinate (remove crop, pad, shrink, enlarge)
179  double parentSample = p_alphaCube->AlphaSample(sample);
180  double parentLine = p_alphaCube->AlphaLine(line);
181  bool success = false;
182  success = p_detectorMap->SetParent(parentSample, parentLine);
183  // Convert from parent to detector
184  if (success) {
185  double detectorSample = p_detectorMap->DetectorSample();
186  double detectorLine = p_detectorMap->DetectorLine();
187  success = p_focalPlaneMap->SetDetector(detectorSample, detectorLine);
188  // Now Convert from detector to distorted focal plane
189  if (success) {
190  double focalPlaneX = p_focalPlaneMap->FocalPlaneX();
191  double focalPlaneY = p_focalPlaneMap->FocalPlaneY();
192  success = p_distortionMap->SetFocalPlane(focalPlaneX, focalPlaneY);
193  // Remove optical distortion
194  if (success) {
195  // Map to the ground
199  return p_groundMap->SetFocalPlane(x, y, z);
200  }
201  }
202  }
203  }
204 
205  // The projection is a sky map
206  else if (p_projection->IsSky()) {
207  return SetImageSkyMapProjection(sample, line, shape);
208  }
209 
210  // We have map projected camera model
211  else {
212  return SetImageMapProjection(sample, line, shape);
213  }
214 
215  // failure
216  shape->clearSurfacePoint();
217  return false;
218  }
219 
220 
240  bool Camera::SetImage(const double sample, const double line, const double deltaT) {
241  p_childSample = sample;
242  p_childLine = line;
243  p_pointComputed = true;
244 
245  // get shape
246  // TODO: we need to validate this pointer (somewhere)
247  ShapeModel *shape = target()->shape();
248  shape->clearSurfacePoint(); // Set initial condition for ShapeModel
249 
250  // Case of no map projection
251  if (p_projection == NULL || p_ignoreProjection) {
252  // Convert to parent coordinate (remove crop, pad, shrink, enlarge)
253  double parentSample = p_alphaCube->AlphaSample(sample);
254  double parentLine = p_alphaCube->AlphaLine(line);
255  bool success = false;
256  success = p_detectorMap->SetParent(parentSample, parentLine, deltaT);
257  // Convert from parent to detector
258  if (success) {
259  double detectorSample = p_detectorMap->DetectorSample();
260  double detectorLine = p_detectorMap->DetectorLine();
261  success = p_focalPlaneMap->SetDetector(detectorSample, detectorLine);
262  // Now Convert from detector to distorted focal plane
263  if (success) {
264  double focalPlaneX = p_focalPlaneMap->FocalPlaneX();
265  double focalPlaneY = p_focalPlaneMap->FocalPlaneY();
266  success = p_distortionMap->SetFocalPlane(focalPlaneX, focalPlaneY);
267  // Remove optical distortion
268  if (success) {
269  // Map to the ground
273  return p_groundMap->SetFocalPlane(x, y, z);
274  }
275  }
276  }
277  }
278 
279  // The projection is a sky map
280  else if (p_projection->IsSky()) {
281  return SetImageSkyMapProjection(sample, line, shape);
282  }
283 
284  // We have map projected camera model
285  else {
286  return SetImageMapProjection(sample, line, shape);
287  }
288 
289  // failure
290  shape->clearSurfacePoint();
291  return false;
292  }
293 
294 
306  bool Camera::SetImageMapProjection(const double sample, const double line, ShapeModel *shape) {
307  Latitude lat;
308  Longitude lon;
309  Distance rad;
310  if (shape->name() != "Plane") { // this is the normal behavior
311  if (p_projection->SetWorld(sample, line)) {
312  TProjection *tproj = (TProjection *) p_projection;
313  lat = Latitude(tproj->UniversalLatitude(), Angle::Degrees);
315  rad = Distance(LocalRadius(lat, lon));
316  if (!rad.isValid()) {
317  shape->setHasIntersection(false);
318  return false;
319  }
320  SurfacePoint surfPt(lat, lon, rad);
321  if (SetGround(surfPt)) {
322  p_childSample = sample;
323  p_childLine = line;
324 
325  shape->setHasIntersection(true);
326  return true;
327  }
328  }
329  }
330  else { // shape is ring plane
331  if (p_projection->SetWorld(sample, line)) {
333  lat = Latitude(0.0, Angle::Degrees);
336 
337  if (!rad.isValid()) {
338  shape->setHasIntersection(false);
339  return false;
340  }
341  SurfacePoint surfPt(lat, lon, rad);
342  if (SetGround(surfPt)) {
343  p_childSample = sample;
344  p_childLine = line;
345 
346  shape->setHasIntersection(true);
347  return true;
348  }
349  }
350  }
351  shape->clearSurfacePoint();
352  return false;
353  }
354 
355 
367  bool Camera::SetImageSkyMapProjection(const double sample, const double line, ShapeModel *shape) {
368  TProjection *tproj = (TProjection *) p_projection;
369  if (tproj->SetWorld(sample, line)) {
371  tproj->UniversalLatitude())) {
372  p_childSample = sample;
373  p_childLine = line;
374 
375  return HasSurfaceIntersection();
376  }
377  }
378  shape->clearSurfacePoint();
379  return false;
380  }
381 
382 
392  bool Camera::SetUniversalGround(const double latitude, const double longitude) {
393  // Convert lat/lon or rad/az (i.e. ring rad / ring lon) to undistorted focal plane x/y
395  Longitude(longitude, Angle::Degrees))) {
396  return RawFocalPlanetoImage();
397  }
398 
400  return false;
401  }
402 
403 
413  bool Camera::SetGround(Latitude latitude, Longitude longitude) {
414  ShapeModel *shape = target()->shape();
415  Distance localRadius;
416 
417  if (shape->name() != "Plane") { // this is the normal behavior
418  localRadius = LocalRadius(latitude, longitude);
419  }
420  else {
421  localRadius = Distance(latitude.degrees(),Distance::Kilometers);
422  latitude = Latitude(0.,Angle::Degrees);
423  }
424 
425  if (!localRadius.isValid()) {
427  return false;
428  }
429 
430  return SetGround(SurfacePoint(latitude, longitude, localRadius));
431  }
432 
433 
434 
444  bool Camera::SetGround(const SurfacePoint & surfacePt) {
445  ShapeModel *shape = target()->shape();
446  if (!surfacePt.Valid()) {
447  shape->clearSurfacePoint();
448  return false;
449  }
450 
451  // Convert lat/lon to undistorted focal plane x/y
452  if (p_groundMap->SetGround(surfacePt)) {
453  return RawFocalPlanetoImage();
454  }
455 
456  shape->clearSurfacePoint();
457  return false;
458  }
459 
460 
469  double ux = p_groundMap->FocalPlaneX();
470  double uy = p_groundMap->FocalPlaneY();
471 
472  // get shape
473  // TODO: we need to validate this pointer (somewhere)
474  ShapeModel *shape = target()->shape();
475 
476  //cout << "undistorted focal plane: " << ux << " " << uy << endl; //debug
477  //cout.precision(15);
478  //cout << "Backward Time: " << Time().Et() << endl;
479  // Convert undistorted x/y to distorted x/y
480  bool success = p_distortionMap->SetUndistortedFocalPlane(ux, uy);
481  if (success) {
482  double focalPlaneX = p_distortionMap->FocalPlaneX();
483  double focalPlaneY = p_distortionMap->FocalPlaneY();
484  //cout << "focal plane: " << focalPlaneX << " " << focalPlaneY << endl; //debug
485  // Convert distorted x/y to detector position
486  success = p_focalPlaneMap->SetFocalPlane(focalPlaneX, focalPlaneY);
487  if (success) {
488  double detectorSample = p_focalPlaneMap->DetectorSample();
489  double detectorLine = p_focalPlaneMap->DetectorLine();
490  //cout << "detector: " << detectorSample << " " << detectorLine << endl;
491  // Convert detector to parent position
492  success = p_detectorMap->SetDetector(detectorSample, detectorLine);
493  if (success) {
494  double parentSample = p_detectorMap->ParentSample();
495  double parentLine = p_detectorMap->ParentLine();
496  //cout << "cube: " << parentSample << " " << parentLine << endl; //debug
497  if (p_projection == NULL || p_ignoreProjection) {
498  p_childSample = p_alphaCube->BetaSample(parentSample);
499  p_childLine = p_alphaCube->BetaLine(parentLine);
500  p_pointComputed = true;
501  shape->setHasIntersection(true);
502  return true;
503  }
504  else if (p_projection->IsSky()) {
505  if (p_projection->SetGround(Declination(), RightAscension())) {
508  p_pointComputed = true;
509  shape->setHasIntersection(true);
510  return true;
511  }
512  }
517  p_pointComputed = true;
518  shape->setHasIntersection(true);
519  return true;
520  }
521  }
522  else { // ring plane
523  // UniversalLongitude should return azimuth (ring longitude) in this case
524  // TODO:
525  // when we make the change to real azimuths this value may need to be adjusted or
526  // code changed in the shapemodel or surfacepoint class.
530  p_pointComputed = true;
531  shape->setHasIntersection(true);
532  return true;
533  }
534  }
535  }
536  }
537  }
538 
539  shape->clearSurfacePoint();
540  return false;
541  }
542 
543 
544 
555  bool Camera::SetUniversalGround(const double latitude, const double longitude,
556  const double radius) {
557  // Convert lat/lon to undistorted focal plane x/y
559  Longitude(longitude, Angle::Degrees),
560  Distance(radius, Distance::Meters)))) {
561  return RawFocalPlanetoImage(); // sets p_hasIntersection
562  }
563 
565  return false;
566  }
567 
568 
569 
642 
643 
645 
646 
647  double thetaRad;
648  double sB[3];
649  instrumentPosition(sB);
650  double pB[3];
651  Coordinate(pB);
652  double a = sB[0] - pB[0];
653  double b = sB[1] - pB[1];
654  double c = sB[2] - pB[2];
655  double rho = sqrt(a * a + b * b + c * c) * 1000.0;
656 
657  thetaRad = EmissionAngle()*DEG2RAD;
658 
659  if (thetaRad < HALFPI) {
660 
661  double nadirResolution = rho/(p_focalLength/p_pixelPitch);
662  return nadirResolution/sqrt(cos(thetaRad));
663 
664  }
665  return Isis::Null;
666 
667  }
668 
669  return Isis::Null;
670 
671  }
672 
673 
680  if (HasSurfaceIntersection()) {
681  double sB[3];
682  instrumentPosition(sB);
683  double pB[3];
684  Coordinate(pB);
685  double a = sB[0] - pB[0];
686  double b = sB[1] - pB[1];
687  double c = sB[2] - pB[2];
688  double dist = sqrt(a * a + b * b + c * c) * 1000.0;
689  return dist / (p_focalLength / p_pixelPitch);
690  }
691  return Isis::Null;
692  }
693 
694 
701 
703  }
704 
712 
714  }
715 
716 
724  }
725 
726 
735 
737  }
738 
739 
745  double lineRes = LineResolution();
746  double sampRes = SampleResolution();
747  if (lineRes < 0.0) return Isis::Null;
748  if (sampRes < 0.0) return Isis::Null;
749  return (lineRes + sampRes) / 2.0;
750  }
751 
752 
760  double lineRes = ObliqueLineResolution();
761  double sampRes = ObliqueSampleResolution();
762  if (lineRes < 0.0) return Isis::Null;
763  if (sampRes < 0.0) return Isis::Null;
764  return (lineRes + sampRes) / 2.0;
765  }
766 
767 
775  return p_maxres;
776  }
777 
778 
786  return p_minres;
787  }
788 
789 
797  return p_minobliqueres;
798  }
799 
800 
808  return p_maxobliqueres;
809  }
810 
811 
816  // Software adjustment is needed if we get here -- call RingRangeResolution instead
817  if (target()->shape()->name() == "Plane") {
818  IString msg = "Images with plane targets should use Camera method RingRangeResolution ";
819  msg += "instead of GroundRangeResolution";
821  }
822 
823  // Have we already done this
824  if (p_groundRangeComputed) return;
825  p_groundRangeComputed = true;
826 
827  bool computed = p_pointComputed;
828  double originalSample = Sample();
829  double originalLine = Line();
830  int originalBand = Band();
831 
832  // Initializations
833  p_minlat = DBL_MAX;
834  p_minlon = DBL_MAX;
835  p_minlon180 = DBL_MAX;
836  p_maxlat = -DBL_MAX;
837  p_maxlon = -DBL_MAX;
838  p_maxlon180 = -DBL_MAX;
839  p_minres = DBL_MAX;
840  p_maxres = -DBL_MAX;
841  p_minobliqueres = DBL_MAX;
842  p_maxobliqueres = -DBL_MAX;
843 
844  // See if we have band dependence and loop for the appropriate number of bands
845  int eband = p_bands;
846  if (IsBandIndependent()) eband = 1;
847  for (int band = 1; band <= eband; band++) {
848  SetBand(band);
849 
850  // Loop for each line testing the left and right sides of the image
851  for (int line = 1; line <= p_lines + 1; line++) {
852  // Look for the first good lat/lon on the left edge of the image
853  // If it is the first or last line then test the whole line
854  int samp;
855  for (samp = 1; samp <= p_samples + 1; samp++) {
856 
857  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
858  double lat = UniversalLatitude();
859  double lon = UniversalLongitude();
860  if (lat < p_minlat) p_minlat = lat;
861  if (lat > p_maxlat) p_maxlat = lat;
862  if (lon < p_minlon) p_minlon = lon;
863  if (lon > p_maxlon) p_maxlon = lon;
864 
865  if (lon > 180.0) lon -= 360.0;
866  if (lon < p_minlon180) p_minlon180 = lon;
867  if (lon > p_maxlon180) p_maxlon180 = lon;
868 
869  double res = PixelResolution();
870  if (res > 0.0) {
871  if (res < p_minres) p_minres = res;
872  if (res > p_maxres) p_maxres = res;
873  }
874  // Determine min/max oblique resolution
875  double obliqueres = ObliquePixelResolution();
876  if (obliqueres > 0.0) {
877  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
878  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
879 
880  }
881  if ((line != 1) && (line != p_lines + 1)) break;
882  }
883  } // end loop through samples
884 
885  //We've already checked the first and last lines.
886  if (line == 1) continue;
887  if (line == p_lines + 1) continue;
888 
889  // Look for the first good lat/lon on the right edge of the image
890  if (samp < p_samples + 1) {
891  for (samp = p_samples + 1; samp >= 1; samp--) {
892  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
893  double lat = UniversalLatitude();
894  double lon = UniversalLongitude();
895  if (lat < p_minlat) p_minlat = lat;
896  if (lat > p_maxlat) p_maxlat = lat;
897  if (lon < p_minlon) p_minlon = lon;
898  if (lon > p_maxlon) p_maxlon = lon;
899 
900  if (lon > 180.0) lon -= 360.0;
901  if (lon < p_minlon180) p_minlon180 = lon;
902  if (lon > p_maxlon180) p_maxlon180 = lon;
903 
904  double res = PixelResolution();
905  if (res > 0.0) {
906  if (res < p_minres) p_minres = res;
907  if (res > p_maxres) p_maxres = res;
908  }
909 
910  // Determine min/max oblique resolution
911  double obliqueres = ObliquePixelResolution();
912  if (obliqueres > 0.0) {
913  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
914  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
915 
916  }
917  break;
918  }
919  }
920  }
921  } // end loop through lines
922 
923  // Test at the sub-spacecraft point to see if we have a
924  // better resolution
925  double lat, lon;
926 
927  subSpacecraftPoint(lat, lon);
928  Latitude latitude(lat, Angle::Degrees);
929  Longitude longitude(lon, Angle::Degrees);
930  // get the local radius for the subspacecraft point
931  Distance radius(LocalRadius(latitude, longitude));
932  SurfacePoint testPoint;
933 
934  if (radius.isValid()) {
935 
936  testPoint = SurfacePoint(latitude, longitude, radius);
937 
938  if (SetGround(testPoint)) {
939  if (Sample() >= 0.5 && Line() >= 0.5 &&
940  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
941  double res = PixelResolution();
942  if (res > 0.0) {
943  if (res < p_minres) p_minres = res;
944  if (res > p_maxres) p_maxres = res;
945  }
946 
947  double obliqueres = ObliquePixelResolution();
948  if (obliqueres > 0.0) {
949  if (obliqueres < p_minobliqueres) p_minobliqueres = obliqueres;
950  if (obliqueres > p_maxobliqueres) p_maxobliqueres = obliqueres;
951 
952  }
953  }
954  }
955  } // end valid local (subspacecraft) radius
956 
957  // Special test for ground range to see if either pole is in the image
958  latitude = Latitude(90, Angle::Degrees);
959  longitude = Longitude(0.0, Angle::Degrees);
960  // get radius for north pole
961  radius = LocalRadius(latitude, longitude);
962 
963  if (radius.isValid()) {
964 
965  testPoint = SurfacePoint(latitude, longitude, radius);
966 
967  if (SetGround(testPoint)) {
968  if (Sample() >= 0.5 && Line() >= 0.5 &&
969  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
970  p_maxlat = 90.0;
971  p_minlon = 0.0;
972  p_maxlon = 360.0;
973  p_minlon180 = -180.0;
974  p_maxlon180 = 180.0;
975  }
976  }
977  } // end valid north polar radius
978 
979  latitude = Latitude(-90, Angle::Degrees);
980  // get radius for south pole
981  radius = LocalRadius(latitude, longitude);
982 
983  if (radius.isValid()) {
984 
985  testPoint = SurfacePoint(latitude, longitude, radius);
986  if (SetGround(testPoint)) {
987  if (Sample() >= 0.5 && Line() >= 0.5 &&
988  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
989  p_minlat = -90.0;
990  p_minlon = 0.0;
991  p_maxlon = 360.0;
992  p_minlon180 = -180.0;
993  p_maxlon180 = 180.0;
994  }
995  }
996  } // end valid south polar radius
997 
998  // Another special test for ground range as we could have the
999  // 0-360 seam running right through the image so
1000  // test it as well (the increment may not be fine enough !!!)
1002  lat <= Latitude(p_maxlat, Angle::Degrees);
1003  lat += Angle((p_maxlat - p_minlat) / 10.0, Angle::Degrees)) {
1004  if (SetGround(lat, Longitude(0.0, Angle::Degrees))) {
1005  if (Sample() >= 0.5 && Line() >= 0.5 &&
1006  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1007  p_minlon = 0.0;
1008  p_maxlon = 360.0;
1009  break;
1010  }
1011  } // end if set ground (lat, 0)
1012 
1013  // Another special test for ground range as we could have the
1014  // -180-180 seam running right through the image so
1015  // test it as well (the increment may not be fine enough !!!)
1016  if (SetGround(lat, Longitude(180.0, Angle::Degrees))) {
1017  if (Sample() >= 0.5 && Line() >= 0.5 &&
1018  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1019  p_minlon180 = -180.0;
1020  p_maxlon180 = 180.0;
1021  break;
1022  }
1023  } // end if set ground (lat, 180)
1024  } // end for loop (latitudes from min to max)
1025  } // end for loop through bands
1026 
1027  SetBand(originalBand);
1028 
1029  if(computed) {
1030  SetImage(originalSample, originalLine);
1031  }
1032  else {
1033  p_pointComputed = false;
1034  }
1035 
1036  if (p_minlon == DBL_MAX || p_minlat == DBL_MAX || p_maxlon == -DBL_MAX || p_maxlat == -DBL_MAX) {
1037  string message = "Camera missed planet or SPICE data off.";
1038  throw IException(IException::Unknown, message, _FILEINFO_);
1039  }
1040 
1041 
1042  // Checks for invalid lat/lon ranges
1043 // if(p_minlon == DBL_MAX || p_minlat == DBL_MAX || p_maxlon == -DBL_MAX
1044 // || p_maxlat == -DBL_MAX)
1045 // {
1046 // string message = "Camera missed planet or SPICE data off.";
1047 // throw IException(IException::Unknown, message, _FILEINFO_);
1048 // }
1049  }
1050 
1051 
1057  // TODO Add test to make sure we have a ring plane image **
1058 
1059  // Have we already done this
1060  if (p_ringRangeComputed) return;
1061 
1062  p_ringRangeComputed = true;
1063 
1064  bool computed = p_pointComputed;
1065  double originalSample = Sample();
1066  double originalLine = Line();
1067  int originalBand = Band();
1068 
1069  // Initializations
1070  p_minRingRadius = DBL_MAX;
1071  p_minRingLongitude = DBL_MAX;
1072  p_minRingLongitude180 = DBL_MAX;
1073  p_maxRingRadius = -DBL_MAX;
1074  p_maxRingLongitude = -DBL_MAX;
1075  p_maxRingLongitude180 = -DBL_MAX;
1076  p_minres = DBL_MAX;
1077  p_maxres = -DBL_MAX;
1078 
1079  // See if we have band dependence and loop for the appropriate number of bands
1080  int eband = p_bands;
1081  if (IsBandIndependent())
1082  eband = 1;
1083 
1084  for (int band = 1; band <= eband; band++) {
1085  SetBand(band);
1086 
1087  // Loop for each line testing the left and right sides of the image
1088  for (int line = 1; line <= p_lines + 1; line++) {
1089 
1090  // Look for the first good radius/azimuth on the left edge of the image
1091  // If it is the first or last line then test the whole line
1092  int samp;
1093  for (samp = 1; samp <= p_samples + 1; samp++) {
1094 
1095  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
1096  double radius = LocalRadius().meters();
1097  double azimuth = UniversalLongitude();
1098  if (radius < p_minRingRadius) p_minRingRadius = radius;
1099  if (radius > p_maxRingRadius) p_maxRingRadius = radius;
1100  if (azimuth < p_minRingLongitude) p_minRingLongitude = azimuth;
1101  if (azimuth > p_maxRingLongitude) p_maxRingLongitude = azimuth;
1102 
1103  if (azimuth > 180.0) azimuth -= 360.0;
1104  if (azimuth < p_minRingLongitude180) p_minRingLongitude180 = azimuth;
1105  if (azimuth > p_maxRingLongitude180) p_maxRingLongitude180 = azimuth;
1106 
1107  double res = PixelResolution();
1108  if (res > 0.0) {
1109  if (res < p_minres) p_minres = res;
1110  if (res > p_maxres) p_maxres = res;
1111  }
1112  if ((line != 1) && (line != p_lines + 1)) break;
1113  }
1114  }
1115  //We've already checked the first and last lines.
1116  if (line == 1) continue;
1117  if (line == p_lines + 1) continue;
1118 
1119  // Look for the first good rad/azimuth on the right edge of the image
1120  if (samp < p_samples + 1) {
1121  for(samp = p_samples + 1; samp >= 1; samp--) {
1122  if (SetImage((double)samp - 0.5, (double)line - 0.5)) {
1123  double radius = LocalRadius().meters();
1124  double azimuth = UniversalLongitude();
1125  if (radius < p_minRingRadius) p_minRingRadius = radius;
1126  if (radius > p_maxRingRadius) p_maxRingRadius = radius;
1127  if (azimuth < p_minRingLongitude) p_minRingLongitude = azimuth;
1128  if (azimuth > p_maxRingLongitude) p_maxRingLongitude = azimuth;
1129 
1130  if (azimuth > 180.0) azimuth -= 360.0;
1131  if (azimuth < p_minRingLongitude180) p_minRingLongitude180 = azimuth;
1132  if (azimuth > p_maxRingLongitude180) p_maxRingLongitude180 = azimuth;
1133 
1134  double res = PixelResolution();
1135  if (res > 0.0) {
1136  if (res < p_minres) p_minres = res;
1137  if (res > p_maxres) p_maxres = res;
1138  }
1139  break;
1140  }
1141  }
1142  }
1143  }
1144 
1145  // Test at the sub-spacecraft point to see if we have a
1146  // better resolution
1147  // TODO: is there something to this analogous for ring images?
1148 // double rad, lon;
1149 
1150 // subSpacecraftPoint(lat, lon);
1151 // Latitude latitude(lat, Angle::Degrees);
1152 // Longitude longitude(lon, Angle::Degrees);
1153 // Distance radius(LocalRadius(latitude, longitude));
1154 // SurfacePoint testPoint;
1155 
1156 // if (radius.isValid()) {
1157 
1158 // testPoint = SurfacePoint(latitude, longitude, radius);
1159 
1160 // if(SetGround(testPoint)) {
1161 // if(Sample() >= 0.5 && Line() >= 0.5 &&
1162 // Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1163 // double res = PixelResolution();
1164 // if(res > 0.0) {
1165 // if(res < p_minres) p_minres = res;
1166 // if(res > p_maxres) p_maxres = res;
1167 // }
1168 // }
1169 // }
1170 // }
1171 
1172  // Another special test for ring range as we could have the
1173  // 0-360 seam running right through the image so
1174  // test it as well (the increment may not be fine enough !!!)
1177  radius += Distance((p_maxRingRadius - p_minRingRadius) / 10.0, Distance::Meters)) {
1179  if (Sample() >= 0.5 && Line() >= 0.5 &&
1180  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1181  p_minRingLongitude = 0.0;
1182  p_maxRingLongitude = 360.0;
1183  break;
1184  }
1185  }
1186 
1187  // for (Latitude lat = Latitude(p_minlat, Angle::Degrees);
1188  // lat <= Latitude(p_maxlat, Angle::Degrees);
1189  // lat += Angle((p_maxlat - p_minlat) / 10.0, Angle::Degrees)) {
1190  // if (SetGround(lat, Longitude(0.0, Angle::Degrees))) {
1191  // if (Sample() >= 0.5 && Line() >= 0.5 &&
1192  // Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1193  // p_minlon = 0.0;
1194  // p_maxlon = 360.0;
1195  // break;
1196  // }
1197  // }
1198 
1199  // Another special test for ring range as we could have the
1200  // -180-180 seam running right through the image so
1201  // test it as well (the increment may not be fine enough !!!)
1203  if (Sample() >= 0.5 && Line() >= 0.5 &&
1204  Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
1205  p_minRingLongitude180 = -180.0;
1206  p_maxRingLongitude180 = 180.0;
1207  break;
1208  }
1209  }
1210  }
1211  } // end loop over bands
1212 
1213  SetBand(originalBand);
1214 
1215  if (computed) {
1216  SetImage(originalSample, originalLine);
1217  }
1218  else {
1219  p_pointComputed = false;
1220  }
1221 
1222  // Checks for invalid radius/lon ranges
1223  if (p_minRingRadius == DBL_MAX || p_minRingRadius == DBL_MAX
1224  || p_minRingLongitude == DBL_MAX || p_maxRingLongitude == -DBL_MAX) {
1225  string message = "RingPlane ShapeModel - Camera missed plane or SPICE data off.";
1226  throw IException(IException::Unknown, message, _FILEINFO_);
1227  }
1228  }
1229 
1230 
1240  double minlat, minlon, maxlat, maxlon;
1241  return GroundRange(minlat, maxlat, minlon, maxlon, pvl);
1242  }
1243 
1256  bool Camera::GroundRange(double &minlat, double &maxlat,
1257  double &minlon, double &maxlon,
1258  Pvl &pvl) {
1259  // Compute the ground range and resolution
1261 
1262  // Get the default radii
1263  Distance localRadii[3];
1264  radii(localRadii);
1265  Distance &a = localRadii[0];
1266  Distance &b = localRadii[2];
1267 
1268  // See if the PVL overrides the radii
1269  PvlGroup map = pvl.findGroup("Mapping", Pvl::Traverse);
1270 
1271  if(map.hasKeyword("EquatorialRadius"))
1272  a = Distance(toDouble(map["EquatorialRadius"][0]), Distance::Meters);
1273 
1274  if(map.hasKeyword("PolarRadius"))
1275  b = Distance(toDouble(map["PolarRadius"][0]), Distance::Meters);
1276 
1277  // Convert to planetographic if necessary
1278  minlat = p_minlat;
1279  maxlat = p_maxlat;
1280  if(map.hasKeyword("LatitudeType")) {
1281  QString latType = (QString) map["LatitudeType"];
1282  if (latType.toUpper() == "PLANETOGRAPHIC") {
1283  if (abs(minlat) < 90.0) { // So tan doesn't fail
1284  minlat *= PI / 180.0;
1285  minlat = atan(tan(minlat) * (a / b) * (a / b));
1286  minlat *= 180.0 / PI;
1287  }
1288 
1289  if(abs(maxlat) < 90.0) { // So tan doesn't fail
1290  maxlat *= PI / 180.0;
1291  maxlat = atan(tan(maxlat) * (a / b) * (a / b));
1292  maxlat *= 180.0 / PI;
1293  }
1294  }
1295  }
1296 
1297  // Assume 0 to 360 domain but change it if necessary
1298  minlon = p_minlon;
1299  maxlon = p_maxlon;
1300  bool domain360 = true;
1301  if(map.hasKeyword("LongitudeDomain")) {
1302  QString lonDomain = (QString) map["LongitudeDomain"];
1303  if(lonDomain.toUpper() == "180") {
1304  minlon = p_minlon180;
1305  maxlon = p_maxlon180;
1306  domain360 = false;
1307  }
1308  }
1309 
1310  // Convert to the proper longitude direction
1311  if(map.hasKeyword("LongitudeDirection")) {
1312  QString lonDirection = (QString) map["LongitudeDirection"];
1313  if(lonDirection.toUpper() == "POSITIVEWEST") {
1314  double swap = minlon;
1315  minlon = -maxlon;
1316  maxlon = -swap;
1317  }
1318  }
1319 
1320  // Convert to the proper longitude domain
1321  if(domain360) {
1322  while(minlon < 0.0) {
1323  minlon += 360.0;
1324  maxlon += 360.0;
1325  }
1326  while(minlon > 360.0) {
1327  minlon -= 360.0;
1328  maxlon -= 360.0;
1329  }
1330  }
1331  else {
1332  while(minlon < -180.0) {
1333  minlon += 360.0;
1334  maxlon += 360.0;
1335  }
1336  while(minlon > 180.0) {
1337  minlon -= 360.0;
1338  maxlon -= 360.0;
1339  }
1340  }
1341 
1342  // Now return if it crosses the longitude domain boundary
1343  if((maxlon - minlon) > 359.0) return true;
1344  return false;
1345  }
1346 
1360  bool Camera::ringRange(double &minRingRadius, double &maxRingRadius,
1361  double &minRingLongitude, double &maxRingLongitude, Pvl &pvl) {
1362  // Compute the ring range and resolution
1364 
1365  // Get the mapping group
1366  PvlGroup map = pvl.findGroup("Mapping", Pvl::Traverse);
1367 
1368  // Get the ring radius range
1369  minRingRadius = p_minRingRadius;
1370  maxRingRadius = p_maxRingRadius;
1371 
1372  // Assume 0 to 360 domain but change it if necessary
1373  minRingLongitude = p_minRingLongitude;
1374  maxRingLongitude = p_maxRingLongitude;
1375  bool domain360 = true;
1376  if (map.hasKeyword("RingLongitudeDomain")) {
1377  QString ringLongitudeDomain = (QString) map["RingLongitudeDomain"];
1378  if (ringLongitudeDomain == "180") {
1379  minRingLongitude = p_minRingLongitude180;
1380  maxRingLongitude = p_maxRingLongitude180;
1381  domain360 = false;
1382  }
1383  }
1384 
1385  // Convert to the proper azimuth direction
1386  if (map.hasKeyword("RingLongitudeDirection")) {
1387  QString ringLongitudeDirection = (QString) map["RingLongitudeDirection"];
1388  if (ringLongitudeDirection.toUpper() == "Clockwise") {
1389  double swap = minRingLongitude;
1390  minRingLongitude = -maxRingLongitude;
1391  maxRingLongitude = -swap;
1392  }
1393  }
1394 
1395  // Convert to the proper azimuth domain
1396  if (domain360) {
1397  while (minRingLongitude < 0.0) {
1398  minRingLongitude += 360.0;
1399  maxRingLongitude += 360.0;
1400  }
1401  while (minRingLongitude > 360.0) {
1402  minRingLongitude -= 360.0;
1403  maxRingLongitude -= 360.0;
1404  }
1405  }
1406  else {
1407  while (minRingLongitude < -180.0) {
1408  minRingLongitude += 360.0;
1409  maxRingLongitude += 360.0;
1410  }
1411  while (minRingLongitude > 180.0) {
1412  minRingLongitude -= 360.0;
1413  maxRingLongitude -= 360.0;
1414  }
1415  }
1416 
1417  // Now return if it crosses the azimuth domain boundary
1418  if ((maxRingLongitude - minRingLongitude) > 359.0) {
1419  return true;
1420  }
1421  return false;
1422  }
1423 
1424 
1431  PvlGroup map("Mapping");
1432  map += PvlKeyword("TargetName", target()->name());
1433 
1434  std::vector<Distance> radii = target()->radii();
1435  map += PvlKeyword("EquatorialRadius", toString(radii[0].meters()), "meters");
1436  map += PvlKeyword("PolarRadius", toString(radii[2].meters()), "meters");
1437 
1438  map += PvlKeyword("LatitudeType", "Planetocentric");
1439  map += PvlKeyword("LongitudeDirection", "PositiveEast");
1440  map += PvlKeyword("LongitudeDomain", "360");
1441 
1443  map += PvlKeyword("MinimumLatitude", toString(p_minlat));
1444  map += PvlKeyword("MaximumLatitude", toString(p_maxlat));
1445  map += PvlKeyword("MinimumLongitude", toString(p_minlon));
1446  map += PvlKeyword("MaximumLongitude", toString(p_maxlon));
1447  map += PvlKeyword("PixelResolution", toString(p_minres));
1448 
1449  map += PvlKeyword("ProjectionName", "Sinusoidal");
1450  pvl.addGroup(map);
1451  }
1452 
1453 
1460  if (target()->shape()->name() != "Plane") {
1461  // If we get here and we don't have a plane, throw an error
1462  IString msg = "A ring plane projection has been requested on an image whose shape is not a ring plane. ";
1463  msg += "Rerun spiceinit with shape=RINGPLANE. ";
1464  throw IException(IException::User, msg, _FILEINFO_);
1465  }
1466 
1467  PvlGroup map("Mapping");
1468  map += PvlKeyword("TargetName", target()->name());
1469 
1470  map += PvlKeyword("RingLongitudeDirection", "CounterClockwise");
1471  map += PvlKeyword("RingLongitudeDomain", "360");
1472 
1474  map += PvlKeyword("MinimumRingRadius", toString(p_minRingRadius));
1475  map += PvlKeyword("MaximumRingRadius", toString(p_maxRingRadius));
1476  map += PvlKeyword("MinimumRingLongitude", toString(p_minRingLongitude));
1477  map += PvlKeyword("MaximumRingLongitude", toString(p_maxRingLongitude));
1478  map += PvlKeyword("PixelResolution", toString(p_minres));
1479 
1480  map += PvlKeyword("ProjectionName", "Planar");
1481  pvl.addGroup(map);
1482  }
1483 
1486  int code = naifIkCode();
1487  QString key = "INS" + toString(code) + "_FOCAL_LENGTH";
1489  }
1490 
1493  int code = naifIkCode();
1494  QString key = "INS" + toString(code) + "_PIXEL_PITCH";
1496  }
1497 
1498 
1499 
1509  bool Camera::SetRightAscensionDeclination(const double ra, const double dec) {
1510  if (p_skyMap->SetSky(ra, dec)) {
1511  double ux = p_skyMap->FocalPlaneX();
1512  double uy = p_skyMap->FocalPlaneY();
1514  double dx = p_distortionMap->FocalPlaneX();
1515  double dy = p_distortionMap->FocalPlaneY();
1516  if (p_focalPlaneMap->SetFocalPlane(dx, dy)) {
1517  double detectorSamp = p_focalPlaneMap->DetectorSample();
1518  double detectorLine = p_focalPlaneMap->DetectorLine();
1519  if (p_detectorMap->SetDetector(detectorSamp, detectorLine)) {
1520  double parentSample = p_detectorMap->ParentSample();
1521  double parentLine = p_detectorMap->ParentLine();
1522 
1523  if (p_projection == NULL || p_ignoreProjection) {
1524  p_childSample = p_alphaCube->BetaSample(parentSample);
1525  p_childLine = p_alphaCube->BetaLine(parentLine);
1526  p_pointComputed = true;
1527  return true;
1528  }
1529  else if (p_projection->IsSky()) {
1530  if (p_projection->SetGround(dec, ra)) {
1533  p_pointComputed = true;
1534  return true;
1535  }
1536  }
1537  else if (target()->shape()->hasIntersection()) {
1539  UniversalLongitude())) {
1542  p_pointComputed = true;
1543  return true;
1544  }
1545  }
1546  }
1547  }
1548  }
1549  }
1550 
1551  return false;
1552  }
1553 
1554 
1562  void Camera::GetLocalNormal(double normal[3]) {
1563 
1564  ShapeModel *shapeModel = target()->shape();
1565  if ( !shapeModel->hasIntersection()) {
1566  // if the shape is not intersected, then clearly there is no normal
1567  normal[0] = normal[1] = normal[2] = 0.0;
1568  return;
1569  }
1570 
1571  // The DEM shape model (and it's child classes) will use 4 surrounding neighbor
1572  // points to find the local normal. The SetImage() calls used to find the
1573  // neighbors is potentially expensive, so we will not calculate the neighbors
1574  // for shape models whose calculateLocalNormal() method won't use them.
1575  bool computed = p_pointComputed;
1576  if (!shapeModel->isDEM()) {
1577  // Non-DEM case: Ellipsoid, NAIF DSK, or Plane --
1578  // Pass in a vector where all of the "neighbors" are the origin (shape model center).
1579  // We do this so that if the implementation of the calculateLocalNormal() method in
1580  // any of the non-DEM shape model classes is modified to use this vector, then an error
1581  // should be thrown instead of a segmentation fault.
1582  QVector<double *> unusedNeighborPoints(4);
1583  double origin[3] = {0, 0, 0};
1584  unusedNeighborPoints.fill(origin);
1585  shapeModel->calculateLocalNormal(unusedNeighborPoints);
1586  }
1587  else { // attempt to find local normal for DEM shapes using 4 surrounding points on the image
1588  QVector<double *> cornerNeighborPoints(4);
1589 
1590  // As documented in the doxygen above, the goal of this method is to
1591  // calculate a normal vector to the surface using the 4 corner surrounding points.
1592  double samp = Sample();
1593  double line = Line();
1594 
1595  // order of points in vector is top, bottom, left, right
1596  QList< QPair< double, double > > surroundingPoints;
1597  surroundingPoints.append(qMakePair(samp, line - 0.5));
1598  surroundingPoints.append(qMakePair(samp, line + 0.5 - DBL_MIN));
1599  surroundingPoints.append(qMakePair(samp - 0.5, line));
1600  surroundingPoints.append(qMakePair(samp + 0.5 - DBL_MIN, line));
1601 
1602  // save input state to be restored on return
1603  double originalSample = samp;
1604  double originalLine = line;
1605 
1606  // now we have all four points in the image, so find the same points on the surface
1607  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1608  cornerNeighborPoints[i] = new double[3];
1609  }
1610 
1611  Latitude lat;
1612  Longitude lon;
1613  Distance radius;
1614 
1615  // if this is a dsk, we only need to use the existing intercept point (plate) normal then return
1616  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1617  // If a surrounding point fails, set it to the original point
1618  if (!(SetImage(surroundingPoints[i].first, surroundingPoints[i].second))) {
1619  surroundingPoints[i].first = samp;
1620  surroundingPoints[i].second = line;
1621 
1622  // If the original point fails too, we can't get a normal. Clean up and return.
1623  if (!(SetImage(surroundingPoints[i].first, surroundingPoints[i].second))) {
1624 
1625  normal[0] = normal[1] = normal[2] = 0.0;
1626 
1627  // restore input state
1628  if (computed) {
1629  SetImage(originalSample, originalLine);
1630  }
1631  else {
1632  p_pointComputed = false;
1633  }
1634 
1635  // free memory
1636  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1637  delete [] cornerNeighborPoints[i];
1638  }
1639 
1640  return;
1641  }
1642  }
1643 
1644  SurfacePoint surfacePoint = GetSurfacePoint();
1645  lat = surfacePoint.GetLatitude();
1646  lon = surfacePoint.GetLongitude();
1647  radius = LocalRadius(lat, lon);
1648 
1649  latrec_c(radius.kilometers(), lon.radians(), lat.radians(), cornerNeighborPoints[i]);
1650  }
1651 
1652  // if the first 2 surrounding points match or the last 2 surrounding points match,
1653  // we can't get a normal. Clean up and return.
1654  if ((surroundingPoints[0].first == surroundingPoints[1].first &&
1655  surroundingPoints[0].second == surroundingPoints[1].second) ||
1656  (surroundingPoints[2].first == surroundingPoints[3].first &&
1657  surroundingPoints[2].second == surroundingPoints[3].second)) {
1658 
1659  normal[0] = normal[1] = normal[2] = 0.0;
1660 
1661  // restore input state
1662  if (!computed) {
1663  SetImage(originalSample, originalLine);
1664  }
1665  else {
1666  p_pointComputed = false;
1667  }
1668 
1669  // free memory
1670  for (int i = 0; i < cornerNeighborPoints.size(); i++)
1671  delete [] cornerNeighborPoints[i];
1672 
1673  return;
1674  }
1675 
1676  // Restore input state to original point before calculating normal
1677  SetImage(originalSample, originalLine);
1678  shapeModel->calculateLocalNormal(cornerNeighborPoints);
1679 
1680  // free memory
1681  for (int i = 0; i < cornerNeighborPoints.size(); i++) {
1682  delete [] cornerNeighborPoints[i];
1683  }
1684 
1685  }
1686 
1687  // restore input state if calculation failed and clean up.
1688  if (!shapeModel->hasNormal()) {
1689  p_pointComputed = false;
1690  return;
1691  }
1692 
1693  // restore failed computed state
1694  if (!computed) {
1695  p_pointComputed = false;
1696  }
1697 
1698  // Set the method normal values
1699  std::vector<double> localNormal(3);
1700  localNormal = shapeModel->normal();
1701  memcpy(normal, (double *) &localNormal[0], sizeof(double) * 3);
1702  }
1703 
1704 
1717  void Camera::LocalPhotometricAngles(Angle & phase, Angle & incidence,
1718  Angle & emission, bool &success) {
1719 
1720  // get local normal vector
1721  double normal[3];
1722  GetLocalNormal(normal);
1723  success = true;
1724 
1725  // Check to make sure normal is valid
1726  SpiceDouble mag;
1727  unorm_c(normal,normal,&mag);
1728  if (mag == 0.) {
1729  success = false;
1730  return;
1731  }
1732 
1733  // get a normalized surface spacecraft vector
1734  SpiceDouble surfSpaceVect[3], unitizedSurfSpaceVect[3], dist;
1735  std::vector<double> sB = bodyRotation()->ReferenceVector(
1737 
1738  SpiceDouble pB[3];
1739  SurfacePoint surfacePoint = GetSurfacePoint();
1740  pB[0] = surfacePoint.GetX().kilometers();
1741  pB[1] = surfacePoint.GetY().kilometers();
1742  pB[2] = surfacePoint.GetZ().kilometers();
1743 
1744  vsub_c((SpiceDouble *) &sB[0], pB, surfSpaceVect);
1745  unorm_c(surfSpaceVect, unitizedSurfSpaceVect, &dist);
1746 
1747  // get a normalized surface sun vector
1748  SpiceDouble surfaceSunVect[3];
1749  vsub_c(m_uB, pB, surfaceSunVect);
1750  SpiceDouble unitizedSurfSunVect[3];
1751  unorm_c(surfaceSunVect, unitizedSurfSunVect, &dist);
1752 
1753  // use normalized surface spacecraft and surface sun vectors to calculate
1754  // the phase angle (in radians)
1755  phase = Angle(vsep_c(unitizedSurfSpaceVect, unitizedSurfSunVect),
1756  Angle::Radians);
1757 
1758  // use normalized surface spacecraft and local normal vectors to calculate
1759  // the emission angle (in radians)
1760  emission = Angle(vsep_c(unitizedSurfSpaceVect, normal),
1761  Angle::Radians);
1762 
1763  // use normalized surface sun and normal vectors to calculate the incidence
1764  // angle (in radians)
1765  incidence = Angle(vsep_c(unitizedSurfSunVect, normal),
1766  Angle::Radians);
1767 
1768 
1769  }
1770 
1771 
1782  bool Camera::RaDecRange(double &minra, double &maxra,
1783  double &mindec, double &maxdec) {
1784 
1785 
1786  bool computed = p_pointComputed;
1787  double originalSample = Sample();
1788  double originalLine = Line();
1789  int originalBand = Band();
1790 
1791  // Have we already done this
1792  if (!p_raDecRangeComputed) {
1793  p_raDecRangeComputed = true;
1794 
1795  // Initializations
1796  p_mindec = DBL_MAX;
1797  p_minra = DBL_MAX;
1798  p_minra180 = DBL_MAX;
1799  p_maxdec = -DBL_MAX;
1800  p_maxra = -DBL_MAX;
1801  p_maxra180 = -DBL_MAX;
1802 
1803  // See if we have band dependence and loop for the appropriate number of bands
1804  int eband = p_bands;
1805  if (IsBandIndependent()) eband = 1;
1806  for (int band = 1; band <= eband; band++) {
1807  this->SetBand(band);
1808 
1809  for (int line = 1; line <= p_lines; line++) {
1810  // Test left, top, and bottom sides
1811  int samp;
1812  for (samp = 1; samp <= p_samples; samp++) {
1813  SetImage((double)samp, (double)line);
1814  double ra = RightAscension();
1815  double dec = Declination();
1816  if (ra < p_minra) p_minra = ra;
1817  if (ra > p_maxra) p_maxra = ra;
1818  if (dec < p_mindec) p_mindec = dec;
1819  if (dec > p_maxdec) p_maxdec = dec;
1820 
1821  if (ra > 180.0) ra -= 360.0;
1822  if (ra < p_minra180) p_minra180 = ra;
1823  if (ra > p_maxra180) p_maxra180 = ra;
1824 
1825  if ((line != 1) && (line != p_lines)) break;
1826  }
1827 
1828  // Test right side
1829  if (samp < p_samples) {
1830  for (samp = p_samples; samp >= 1; samp--) {
1831  SetImage((double)samp, (double)line);
1832  double ra = RightAscension();
1833  double dec = Declination();
1834  if (ra < p_minra) p_minra = ra;
1835  if (ra > p_maxra) p_maxra = ra;
1836  if (dec < p_mindec) p_mindec = dec;
1837  if (dec > p_maxdec) p_maxdec = dec;
1838 
1839  if (ra > 180.0) ra -= 360.0;
1840  if (ra < p_minra180) p_minra180 = ra;
1841  if (ra > p_maxra180) p_maxra180 = ra;
1842 
1843  break;
1844  }
1845  }
1846  }
1847 
1848  // Special test for ground range to see if either pole is in the image
1849  if (SetRightAscensionDeclination(0.0, 90.0)) {
1850  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1851  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1852  p_maxdec = 90.0;
1853  p_minra = 0.0;
1854  p_maxra = 360.0;
1855  p_minra180 = -180.0;
1856  p_maxra180 = 180.0;
1857  }
1858  }
1859 
1860  if (SetRightAscensionDeclination(0.0, -90.0)) {
1861  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1862  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1863  p_mindec = -90.0;
1864  p_minra = 0.0;
1865  p_maxra = 360.0;
1866  p_minra180 = -180.0;
1867  p_maxra180 = 180.0;
1868  }
1869  }
1870 
1871  // Another special test for ground range as we could have the
1872  // 0-360 seam running right through the image so
1873  // test it as well (the increment may not be fine enough !!!)
1874  for (double dec = p_mindec; dec <= p_maxdec; dec += (p_maxdec - p_mindec) / 10.0) {
1875  if (SetRightAscensionDeclination(0.0, dec)) {
1876  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1877  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1878  p_minra = 0.0;
1879  p_maxra = 360.0;
1880  break;
1881  }
1882  }
1883  }
1884 
1885  // Another special test for ground range as we could have the
1886  // 0-360 seam running right through the image so
1887  // test it as well (the increment may not be fine enough !!!)
1888  for (double dec = p_mindec; dec <= p_maxdec; dec += (p_maxdec - p_mindec) / 10.0) {
1889  if (SetRightAscensionDeclination(180.0, dec)) {
1890  if ((Line() >= 0.5) && (Line() <= p_lines) &&
1891  (Sample() >= 0.5) && (Sample() <= p_samples)) {
1892  p_minra180 = -180.0;
1893  p_maxra180 = 180.0;
1894  break;
1895  }
1896  }
1897  }
1898  }
1899  }
1900 
1901  minra = p_minra;
1902  maxra = p_maxra;
1903  mindec = p_mindec;
1904  maxdec = p_maxdec;
1905 
1906  SetBand(originalBand);
1907 
1908  if (computed) {
1909  SetImage(originalSample, originalLine);
1910  }
1911  else {
1912  p_pointComputed = false;
1913  }
1914 
1915  return true;
1916  }
1917 
1918 
1925 
1926  bool computed = p_pointComputed;
1927  double originalSample = Sample();
1928  double originalLine = Line();
1929  int originalBand = Band();
1930 
1931  SetImage(1.0, 1.0);
1932  double ra1 = RightAscension();
1933  double dec1 = Declination();
1934 
1935  SetImage(1.0, (double)p_lines);
1936  double ra2 = RightAscension();
1937  double dec2 = Declination();
1938 
1939  double dist = (ra1 - ra2) * (ra1 - ra2) + (dec1 - dec2) * (dec1 - dec2);
1940  dist = sqrt(dist);
1941  double lineRes = dist / (p_lines - 1);
1942 
1943  SetImage((double)p_samples, 1.0);
1944  ra2 = RightAscension();
1945  dec2 = Declination();
1946 
1947  dist = (ra1 - ra2) * (ra1 - ra2) + (dec1 - dec2) * (dec1 - dec2);
1948  dist = sqrt(dist);
1949  double sampRes = dist / (p_samples - 1);
1950 
1951  SetBand(originalBand);
1952 
1953  if (computed) {
1954  SetImage(originalSample, originalLine);
1955  }
1956  else {
1957  p_pointComputed = false;
1958  }
1959 
1960  return (sampRes < lineRes) ? sampRes : lineRes;
1961  }
1962 
1969  if (target()->shape()->name() == "Plane") {
1970  QString msg = "North Azimuth is not available for plane target shapes.";
1972  }
1973  // Get the latitude of your current location using the shape model
1974  // specified in the image Kernels
1975  double lat = UniversalLatitude();
1976  // We are in northern hemisphere
1977  if (lat >= 0.0) {
1978  return ComputeAzimuth(90.0, 0.0);
1979  }
1980  // We are in southern hemisphere
1981  else {
1982  double azimuth = ComputeAzimuth(-90.0, 0.0) + 180.0;
1983  if (azimuth > 360.0) azimuth = azimuth - 360.0;
1984  return azimuth;
1985  }
1986  }
1987 
1996  double lat, lon;
1997  subSolarPoint(lat, lon);
1998  return ComputeAzimuth(lat, lon);
1999  }
2000 
2001 
2010  double lat, lon;
2011  subSpacecraftPoint(lat, lon);
2012  return ComputeAzimuth(lat, lon);
2013  }
2014 
2015 
2116  double Camera::ComputeAzimuth(const double lat, const double lon) {
2117  // Make sure we are on the planet, if not, north azimuth is meaningless
2118  if (!HasSurfaceIntersection()) return Isis::Null;
2119 
2120  // Need to save the "state" of the camera so we can restore it when the
2121  // method is done
2122  bool computed = p_pointComputed;
2123 
2125 
2126  // Get the azimuth's origin point (the current position) and its radius
2127  SpiceDouble azimuthOrigin[3];
2128  Coordinate(azimuthOrigin);
2129  Distance originRadius = LocalRadius();
2130  if (!originRadius.isValid()) {
2131  return Isis::Null;
2132  }
2133 
2134  // Convert the point of interest to rectangular coordinates (x,y,z) in the
2135  // body-fixed coordinate system and use the azimuth's origin radius to avoid the
2136  // situation where the DEM does not cover the entire planet
2137  SpiceDouble pointOfInterestFromBodyCenter[3];
2138  latrec_c(originRadius.kilometers(), lon * PI / 180.0,
2139  lat * PI / 180.0, pointOfInterestFromBodyCenter);
2140 
2141  // Get the difference vector with its tail at the azimuth origin and its
2142  // head at the point of interest by subtracting vectors the vectors that
2143  // originate at the body center
2144  //
2145  // pointOfInterest = pointOfInterestFromBodyCenter - azimuthOriginFromBodyCenter
2146  //
2147  SpiceDouble pointOfInterest[3];
2148  vsub_c(pointOfInterestFromBodyCenter, azimuthOrigin, pointOfInterest);
2149 
2150  // Get the component of the difference vector pointOfInterestFromAzimuthOrigin that is
2151  // perpendicular to the origin point (i.e. project perpendicularly onto the reference plane).
2152  // This will result in a point of interest vector that is in the plane tangent to the surface at
2153  // the origin point
2154  SpiceDouble pointOfInterestProj[3];
2155  vperp_c(pointOfInterest, azimuthOrigin, pointOfInterestProj);
2156 
2157  // Unitize the tangent vector to a 1 km length vector
2158  SpiceDouble pointOfInterestProjUnit[3];
2159  vhat_c(pointOfInterestProj, pointOfInterestProjUnit);
2160 
2161  // Scale the vector to within a pixel of the azimuth's origin point.
2162  // Get pixel scale in km/pixel and divide by 2 to insure that we stay within
2163  // a pixel of the origin point
2164  double scale = (PixelResolution() / 1000.0) / 2.0;
2165  SpiceDouble pointOfInterestProjUnitScaled[3];
2166  vscl_c(scale, pointOfInterestProjUnit, pointOfInterestProjUnitScaled);
2167 
2168  // Compute the adjusted point of interest vector from the body center. This point
2169  // will be within a pixel of the origin and in the same direction as the requested
2170  // raw point of interest vector
2171  SpiceDouble adjustedPointOfInterestFromBodyCenter[3];
2172  vadd_c(azimuthOrigin, pointOfInterestProjUnitScaled, adjustedPointOfInterestFromBodyCenter);
2173 
2174  // Get the origin image coordinate
2175  double azimuthOriginSample = Sample();
2176  double azimuthOriginLine = Line();
2177 
2178  // Convert the point to a lat/lon and find out its image coordinate
2179  double adjustedPointOfInterestRad, adjustedPointOfInterestLon, adjustedPointOfInterestLat;
2180  reclat_c(adjustedPointOfInterestFromBodyCenter,
2181  &adjustedPointOfInterestRad,
2182  &adjustedPointOfInterestLon,
2183  &adjustedPointOfInterestLat);
2184  adjustedPointOfInterestLat = adjustedPointOfInterestLat * 180.0 / PI;
2185  adjustedPointOfInterestLon = adjustedPointOfInterestLon * 180.0 / PI;
2186  if (adjustedPointOfInterestLon < 0) adjustedPointOfInterestLon += 360.0;
2187 
2188  // Use the radius of the azimuth's origin point
2189  // (rather than that of the adjusted point of interest location)
2190  // to avoid the effects of topography on the calculation
2191  bool success = SetUniversalGround(adjustedPointOfInterestLat,
2192  adjustedPointOfInterestLon,
2193  originRadius.meters());
2194  if (!success) {
2195  // if the adjusted lat/lon values for the point of origin fail to be set, we can not compute
2196  // an azimuth. reset to the original sample/line and return null.
2197  SetImage(azimuthOriginSample, azimuthOriginLine);
2198  return Isis::Null;
2199  }
2200 
2201  double adjustedPointOfInterestSample = Sample();
2202  double adjustedPointOfInterestLine = Line();
2203 
2204  // TODO: Write PushState and PopState method to ensure the
2205  // internals of the class are set based on SetImage or SetGround
2206 
2207  // We now have the information needed to calculate an arctangent
2208  //
2209  //
2210  // point of interest
2211  // |\ |
2212  // | \ |
2213  // | \ | tan(A) = (delta line) / (delta sample)
2214  // delta line | \ | A = arctan( (delta line) / (delta sample) )
2215  // | \ |
2216  // | \ |
2217  // | \ |
2218  // ___________|_____A_\|_______________
2219  // delta sample |origin point
2220  // |
2221  // |
2222  // |
2223  // |
2224  // |
2225  //
2226  // in this example, the azimuth is the angle indicated by the A plus 180 degrees, since we begin
2227  // the angle rotation at the positive x-axis
2228  // This quadrant issue (i.e.need to add 180 degrees) is handled by the atan2 program
2229  //
2230  double deltaSample = adjustedPointOfInterestSample - azimuthOriginSample;
2231  double deltaLine = adjustedPointOfInterestLine - azimuthOriginLine;
2232 
2233  // Compute the angle; the azimuth is the arctangent of the line difference divided by the
2234  // sample difference; the atan2 function is used because it determines which quadrant we
2235  // are in based on the sign of the 2 arguments; the arctangent is measured in a positive
2236  // clockwise direction because the lines in the image increase downward; the arctangent
2237  // uses the 3 o'clock axis (positive sample direction) as its reference line (line of
2238  // zero degrees); a good place to read about the atan2 function is at
2239  // http://en.wikipedia.org/wiki/Atan2
2240  double azimuth = 0.0;
2241  if (deltaSample != 0.0 || deltaLine != 0.0) {
2242  azimuth = atan2(deltaLine, deltaSample);
2243  azimuth *= 180.0 / PI;
2244  }
2245 
2246  // Azimuth is limited to the range of 0 to 360
2247  if (azimuth < 0.0) azimuth += 360.0;
2248  if (azimuth > 360.0) azimuth -= 360.0;
2249 
2251 
2252  // computed is true if the sample/line or lat/lon were reset in this method
2253  // to find the location of the point of interest
2254  // If so, reset "state" of camera to the original sample/line
2255  if (computed) {
2256  SetImage(azimuthOriginSample, azimuthOriginLine);
2257  }
2258  else {
2259  p_pointComputed = false;
2260  }
2261 
2262  return azimuth;
2263  }
2264 
2265 
2273 
2274  // Get the xyz coordinates for the spacecraft and point we are interested in
2275  double coord[3], spCoord[3];
2276  Coordinate(coord);
2277  instrumentPosition(spCoord);
2278 
2279  // Get the angle between the 2 points and convert to degrees
2280  double a = vsep_c(coord, spCoord) * 180.0 / PI;
2281  double b = 180.0 - EmissionAngle();
2282 
2283  // The three angles in a triangle must add up to 180 degrees
2284  double c = 180.0 - (a + b);
2285 
2287 
2288  return c;
2289  }
2290 
2291 
2313  double Camera::GroundAzimuth(double glat, double glon,
2314  double slat, double slon) {
2315  double a;
2316  double b;
2317  if (glat >= 0.0) {
2318  a = (90.0 - slat) * PI / 180.0;
2319  b = (90.0 - glat) * PI / 180.0;
2320  }
2321  else {
2322  a = (90.0 + slat) * PI / 180.0;
2323  b = (90.0 + glat) * PI / 180.0;
2324  }
2325 
2326  double cslon = slon;
2327  double cglon = glon;
2328  if (cslon > cglon) {
2329  if ((cslon-cglon) > 180.0) {
2330  while ((cslon-cglon) > 180.0) cslon = cslon - 360.0;
2331  }
2332  }
2333  if (cglon > cslon) {
2334  if ((cglon-cslon) > 180.0) {
2335  while ((cglon-cslon) > 180.0) cglon = cglon - 360.0;
2336  }
2337  }
2338 
2339  // Which quadrant are we in?
2340  int quad;
2341  if (slat > glat) {
2342  if (cslon > cglon) {
2343  quad = 1;
2344  }
2345  else if (cslon < cglon) {
2346  quad = 2;
2347  }
2348  else {
2349  quad = 1;
2350  }
2351  }
2352  else if (slat < glat) {
2353  if (cslon > cglon) {
2354  quad = 4;
2355  }
2356  else if (cslon < cglon) {
2357  quad = 3;
2358  }
2359  else {
2360  quad = 4;
2361  }
2362  }
2363  else {
2364  if (cslon > cglon) {
2365  quad = 1;
2366  }
2367  else if (cslon < cglon) {
2368  quad = 2;
2369  }
2370  else {
2371  return 0.0;
2372  }
2373  }
2374 
2375  double C = (cglon - cslon) * PI / 180.0;
2376  if (C < 0) C = -C;
2377  double c = acos(cos(a)*cos(b) + sin(a)*sin(b)*cos(C));
2378  double azimuth = 0.0;
2379  if (sin(b) == 0.0 || sin(c) == 0.0) {
2380  return azimuth;
2381  }
2382  double A = acos((cos(a) - cos(b)*cos(c))/(sin(b)*sin(c))) * 180.0 / PI;
2383  //double B = acos((cos(b) - cos(c)*cos(a))/(sin(c)*sin(a))) * 180.0 / PI;
2384  if (glat >= 0.0) {
2385  if (quad == 1 || quad == 4) {
2386  azimuth = A;
2387  }
2388  else if (quad == 2 || quad == 3) {
2389  azimuth = 360.0 - A;
2390  }
2391  }
2392  else {
2393  if (quad == 1 || quad == 4) {
2394  azimuth = 180.0 - A;
2395  }
2396  else if (quad == 2 || quad == 3) {
2397  azimuth = 180.0 + A;
2398  }
2399  }
2400 
2401  return azimuth;
2402  }
2403 
2404 
2412  if (p_distortionMap) {
2413  delete p_distortionMap;
2414  }
2415 
2416  p_distortionMap = map;
2417  }
2418 
2419 
2427  if (p_focalPlaneMap) {
2428  delete p_focalPlaneMap;
2429  }
2430 
2431  p_focalPlaneMap = map;
2432  }
2433 
2434 
2442  if (p_detectorMap) {
2443  delete p_detectorMap;
2444  }
2445 
2446  p_detectorMap = map;
2447  }
2448 
2449 
2457  if (p_groundMap) {
2458  delete p_groundMap;
2459  }
2460 
2461  p_groundMap = map;
2462  }
2463 
2464 
2471  if (p_skyMap) {
2472  delete p_skyMap;
2473  }
2474 
2475  p_skyMap = map;
2476  }
2477 
2478 
2490  // We want to stay in unprojected space for this process
2491  bool projIgnored = p_ignoreProjection;
2492  p_ignoreProjection = true;
2493 
2494  // get the cache variables
2495  pair<double,double> ephemerisTimes = StartEndEphemerisTimes();
2496  int cacheSize = CacheSize(ephemerisTimes.first, ephemerisTimes.second);
2497 
2498  // Set a position in the image so that the PixelResolution can be calculated
2500  double tol = PixelResolution() / 100.; //meters/pix/100.
2501 
2502  if (tol < 0.0) {
2503  // Alternative calculation of ground resolution of a pixel/100
2504  double altitudeMeters;
2505  if (target()->isSky()) { // Use the unit sphere as the target
2506  altitudeMeters = 1.0;
2507  }
2508  else {
2509  altitudeMeters = SpacecraftAltitude() * 1000.;
2510  }
2511  tol = PixelPitch() * altitudeMeters / FocalLength() / 100.;
2512  }
2513 
2514  p_ignoreProjection = projIgnored;
2515 
2516  Spice::createCache(ephemerisTimes.first, ephemerisTimes.second,
2517  cacheSize, tol);
2518 
2519  setTime(ephemerisTimes.first);
2520 
2521  // Reset to band 1
2522  SetBand(1);
2523 
2524  return;
2525  }
2526 
2527 
2546  pair<double, double> Camera::StartEndEphemerisTimes() {
2547  pair<double,double> ephemerisTimes;
2548  double startTime = -DBL_MAX;
2549  double endTime = -DBL_MAX;
2550 
2551  for (int band = 1; band <= Bands(); band++) {
2552  SetBand(band);
2553  SetImage(0.5, 0.5);
2554  double etStart = time().Et();
2555  SetImage(p_alphaCube->BetaSamples() + 0.5,
2556  p_alphaCube->BetaLines() + 0.5); // need to do something if SetImage returns false???
2557  double etEnd = time().Et();
2558  if (band == 1) {
2559  startTime = min(etStart, etEnd);
2560  endTime = max(etStart, etEnd);
2561  }
2562  startTime = min(startTime, min(etStart, etEnd));
2563  endTime = max(endTime, max(etStart, etEnd));
2564  }
2565  if (startTime == -DBL_MAX || endTime == -DBL_MAX) {
2566  string msg = "Unable to find time range for the spice kernels";
2568  }
2569  ephemerisTimes.first = startTime;
2570  ephemerisTimes.second = endTime;
2571  return ephemerisTimes;
2572  }
2573 
2574 
2589  int Camera::CacheSize(double startTime, double endTime) {
2590  int cacheSize;
2591  // BetaLines() + 1 so we get at least 2 points for interpolation
2592  cacheSize = p_alphaCube->BetaLines() + 1;
2593  if (startTime == endTime) {
2594  cacheSize = 1;
2595  }
2596  return cacheSize;
2597  }
2598 
2599 
2616  void Camera::SetGeometricTilingHint(int startSize, int endSize) {
2617  // verify the start size is a multiple of 2 greater than 2
2618  int powerOf2 = 2;
2619 
2620  // No hint if 2's are passed in
2621  if (startSize == 2 && endSize == 2) {
2624  return;
2625  }
2626 
2627  if (endSize > startSize) {
2628  IString message = "Camera::SetGeometricTilingHint End size must be smaller than the start size";
2629  throw IException(IException::Programmer, message, _FILEINFO_);
2630  }
2631 
2632  if (startSize < 4) {
2633  IString message = "Camera::SetGeometricTilingHint Start size must be at least 4";
2634  throw IException(IException::Programmer, message, _FILEINFO_);
2635  }
2636 
2637  bool foundEnd = false;
2638  while (powerOf2 > 0 && startSize != powerOf2) {
2639  if (powerOf2 == endSize) foundEnd = true;
2640  powerOf2 *= 2;
2641  }
2642 
2643  // Didnt find a solution, the integer became negative first, must not be
2644  // a power of 2
2645  if (powerOf2 < 0) {
2646  IString message = "Camera::SetGeometricTilingHint Start size must be a power of 2";
2647  throw IException(IException::Programmer, message, _FILEINFO_);
2648  }
2649 
2650  if (!foundEnd) {
2651  IString message = "Camera::SetGeometricTilingHint End size must be a power of 2 less than the start size, but greater than 2";
2652  throw IException(IException::Programmer, message, _FILEINFO_);
2653  }
2654 
2655  p_geometricTilingStartSize = startSize;
2656  p_geometricTilingEndSize = endSize;
2657  }
2658 
2659 
2667  void Camera::GetGeometricTilingHint(int &startSize, int &endSize) {
2668  startSize = p_geometricTilingStartSize;
2669  endSize = p_geometricTilingEndSize;
2670  }
2671 
2672 
2682  if (Sample() < 0.5 || Line() < 0.5) {
2683  return false;
2684  }
2685 
2686  if (Sample() > Samples() + 0.5 || Line() > Lines() + 0.5) {
2687  return false;
2688  }
2689 
2690  return true;
2691  }
2692 
2693 
2701  return p_projection != 0;
2702  }
2703 
2704 
2712  return true;
2713  }
2714 
2715 
2722  return p_referenceBand;
2723  }
2724 
2725 
2733  return p_referenceBand != 0;
2734  }
2735 
2736 
2742  void Camera::SetBand(const int band) {
2743  p_childBand = band;
2744  }
2745 
2746 
2752  double Camera::Sample() {
2753  return p_childSample;
2754  }
2755 
2756 
2763  return p_childBand;
2764  }
2765 
2766 
2772  double Camera::Line() {
2773  return p_childLine;
2774  }
2775 
2776 
2783  return PixelResolution();
2784  }
2785 
2786 
2787 
2788 
2794  double Camera::FocalLength() const {
2795  return p_focalLength;
2796  }
2797 
2798 
2804  double Camera::PixelPitch() const {
2805  return p_pixelPitch;
2806  }
2807 
2808 
2816 
2817  QList<QPointF> offsets;
2818  offsets.append(QPointF(-PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2819  -PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2820  offsets.append(QPointF(PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2821  -PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2822  offsets.append(QPointF(PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2823  PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2824  offsets.append(QPointF(-PixelPitch() * DetectorMap()->SampleScaleFactor() / 2.0,
2825  PixelPitch() * DetectorMap()->LineScaleFactor() / 2.0));
2826 
2827  return offsets;
2828  }
2829 
2830 
2836  int Camera::Samples() const {
2837  return p_samples;
2838  }
2839 
2840 
2846  int Camera::Lines() const {
2847  return p_lines;
2848  }
2849 
2850 
2856  int Camera::Bands() const {
2857  return p_bands;
2858  }
2859 
2860 
2866  int Camera::ParentLines() const {
2867  return p_alphaCube->AlphaLines();
2868  }
2869 
2870 
2877  return p_alphaCube->AlphaSamples();
2878  }
2879 
2880 
2887  return p_distortionMap;
2888  }
2889 
2890 
2897  return p_focalPlaneMap;
2898  }
2899 
2900 
2907  return p_detectorMap;
2908  }
2909 
2910 
2917  return p_groundMap;
2918  }
2919 
2920 
2927  return p_skyMap;
2928  }
2929 
2930 
2936  QString Camera::instrumentNameLong() const {
2937  return m_instrumentNameLong;
2938  }
2939 
2940 
2947  return m_instrumentNameShort;
2948  }
2949 
2950 
2956  QString Camera::spacecraftNameLong() const {
2957  return m_spacecraftNameLong;
2958  }
2959 
2960 
2967  return m_spacecraftNameShort;
2968  }
2969 
2975  void Camera::IgnoreProjection(bool ignore) {
2976  p_ignoreProjection = ignore;
2977  }
3013  int Camera::SpkTargetId() const {
3014  return (naifSpkCode());
3015  }
3016 
3055  int Camera::SpkCenterId() const {
3056  return (naifBodyCode());
3057  }
3058 
3064  void Camera::SetFocalLength(double v) {
3065  p_focalLength = v;
3066  }
3067 
3073  void Camera::SetPixelPitch(double v) {
3074  p_pixelPitch = v;
3075  }
3076 
3088  double orgLine = Line();
3089  double orgSample = Sample();
3090  double orgDec = Declination();
3091  double orgRa = RightAscension();
3092 
3093  SetRightAscensionDeclination(orgRa, orgDec + (2 * RaDecResolution()));
3094  double y = Line() - orgLine;
3095  double x = Sample() - orgSample;
3096  double celestialNorthClockAngle = atan2(-y, x) * 180.0 / Isis::PI;
3097  celestialNorthClockAngle = 90.0 - celestialNorthClockAngle;
3098 
3099  if (celestialNorthClockAngle < 0.0) {
3100  celestialNorthClockAngle += 360.0;
3101  }
3102 
3103  SetImage(orgSample, orgLine);
3104  return celestialNorthClockAngle;
3105  }
3106 
3107 
3113  double Camera::exposureDuration() const {
3115  }
3116 
3117 
3127  double Camera::exposureDuration(const double sample, const double line, const int band) const {
3128 
3129  //If band defaults to -1, use the camera's stored band.
3130  if (band < 0) {
3131  return p_detectorMap->exposureDuration(sample, line, p_childBand);
3132  }
3133  return p_detectorMap->exposureDuration(sample, line, band);
3134  }
3135 
3136 // end namespace isis
3137 }
3138 
3139 
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:86
void LocalPhotometricAngles(Angle &phase, Angle &incidence, Angle &emission, bool &success)
Calculates LOCAL photometric angles using the DEM (not ellipsoid).
Definition: Camera.cpp:1717
double WorldX() const
This returns the world X coordinate provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:510
double FocalPlaneX() const
Return undistorted focal plane x.
virtual bool SetFocalPlane(const double ux, const double uy, const double uz)
Compute ground position from focal plane coordinate.
double p_maxlat
The maximum latitude.
Definition: Camera.h:515
std::vector< double > normal()
Returns the local surface normal at the current intersection point.
Definition: ShapeModel.cpp:342
double FocalPlaneY() const
Return undistorted focal plane y.
Definition: CameraSkyMap.h:65
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition: Camera.cpp:1485
double RightAscension()
Returns the right ascension angle (sky longitude).
Definition: Sensor.cpp:553
CameraDetectorMap * DetectorMap()
Returns a pointer to the CameraDetectorMap object.
Definition: Camera.cpp:2906
virtual double SampleScaleFactor() const
Return scaling factor for computing sample resolution.
int CacheSize(double startTime, double endTime)
This method calculates the spice cache size.
Definition: Camera.cpp:2589
void SetSkyMap(CameraSkyMap *map)
Sets the Sky Map.
Definition: Camera.cpp:2470
double ParentSample() const
Return parent sample.
double ObliqueLineResolution()
Returns the oblique line resolution at the current position in meters.
Definition: Camera.cpp:734
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:109
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
virtual bool SetParent(const double sample, const double line)
Compute detector position from a parent image coordinate.
double p_mindec
The minimum declination.
Definition: Camera.h:538
int BetaLines() const
Returns the number of lines in the beta cube.
Definition: AlphaCube.h:82
double p_minlon
The minimum longitude.
Definition: Camera.h:516
double p_minobliqueres
The minimum oblique resolution.
Definition: Camera.h:520
QString spacecraftNameShort() const
This method returns the shortened spacecraft name.
Definition: Camera.cpp:2966
bool IsSky() const
Returns true if projection is sky and false if it is land.
Definition: Projection.cpp:223
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
int p_referenceBand
The reference band.
Definition: Camera.h:533
double p_minra180
The minimum right ascension in the 180 domain.
Definition: Camera.h:542
double SunAzimuth()
Returns the Sun Azimuth.
Definition: Camera.cpp:1995
std::vector< Distance > radii() const
Returns the radii of the body in km.
Definition: Target.cpp:499
bool ringRange(double &minRingRadius, double &maxRingRadius, double &minRingLongitude, double &maxRingLongitude, Pvl &pvl)
Analogous to the above Ground Range method.
Definition: Camera.cpp:1360
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:245
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:454
void SetDetectorMap(CameraDetectorMap *map)
Sets the Detector Map.
Definition: Camera.cpp:2441
CameraDistortionMap * DistortionMap()
Returns a pointer to the CameraDistortionMap object.
Definition: Camera.cpp:2886
double radians() const
Convert an angle to a double.
Definition: Angle.h:239
virtual int SpkTargetId() const
Provides target code for instruments SPK NAIF kernel.
Definition: Camera.cpp:3013
int AlphaLines() const
Returns the number of lines in the alpha cube.
Definition: AlphaCube.h:74
virtual bool SetFocalPlane(const double dx, const double dy)
Compute detector position (sample,line) from focal plane coordinates.
int p_lines
The number of lines in the image.
Definition: Camera.h:530
virtual double LineScaleFactor() const
Return scaling factor for computing line resolution.
void SetGroundMap(CameraGroundMap *map)
Sets the Ground Map.
Definition: Camera.cpp:2456
Base class for Map TProjections.
Definition: TProjection.h:178
QString m_instrumentNameLong
Full instrument name.
Definition: Camera.h:494
double p_maxRingLongitude
The maximum ring longitude (azimuth)
Definition: Camera.h:550
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
QString spacecraftNameLong() const
This method returns the full spacecraft name.
Definition: Camera.cpp:2956
double SpacecraftAzimuth()
Return the Spacecraft Azimuth.
Definition: Camera.cpp:2009
bool SetRightAscensionDeclination(const double ra, const double dec)
Sets the right ascension declination.
Definition: Camera.cpp:1509
bool HasProjection()
Checks to see if the camera object has a projection.
Definition: Camera.cpp:2700
bool hasIntersection()
Returns intersection status.
Definition: ShapeModel.cpp:309
double p_maxra180
The maximum right ascension in the 180 domain.
Definition: Camera.h:543
void basicRingMapping(Pvl &map)
Writes the basic mapping group for ring plane to the specified Pvl.
Definition: Camera.cpp:1459
double OffNadirAngle()
Return the off nadir angle in degrees.
Definition: Camera.cpp:2271
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1298
void radii(Distance r[3]) const
Returns the radii of the body in km.
Definition: Spice.cpp:850
double FocalPlaneX() const
Return undistorted focal plane x.
Definition: CameraSkyMap.h:60
virtual double resolution()
Returns the resolution of the camera.
Definition: Camera.cpp:2782
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:198
bool InCube()
This returns true if the current Sample() or Line() value is outside of the cube (meaning the point m...
Definition: Camera.cpp:2681
const double PI(3.14159265358979323846)
The mathematical constant PI.
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:225
int ReferenceBand() const
Returns the reference band.
Definition: Camera.cpp:2721
const double DEG2RAD(0.017453292519943295769237)
Multiplier for converting from degrees to radians.
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1492
double DetectorLine() const
Return detector line.
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.
double UndistortedFocalPlaneY() const
Return undistorted focal plane y.
SpiceInt naifBodyCode() const
This returns the NAIF body code of the target indicated in the labels.
Definition: Spice.cpp:861
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:59
double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
Class for computing sensor ground coordinates.
Definition: Sensor.h:179
double p_maxlon180
The maximum longitude in the 180 domain.
Definition: Camera.h:523
The distance is being specified in kilometers.
Definition: Distance.h:58
double p_focalLength
The focal length, in units of millimeters.
Definition: Camera.h:511
Search child objects.
Definition: PvlObject.h:170
SpicePosition * instrumentPosition() const
Accessor method for the instrument position.
Definition: Spice.cpp:1454
double ObliquePixelResolution()
Returns the oblique pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:759
double ParentLine() const
Return parent line.
virtual ~Camera()
Destroys the Camera Object.
Definition: Camera.cpp:120
double p_maxobliqueres
The maximum oblique resolution.
Definition: Camera.h:521
const double HALFPI(1.57079632679489661923)
The mathematical constant PI/2.
CameraDistortionMap * p_distortionMap
A pointer to the DistortionMap.
Definition: Camera.h:560
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
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:569
double ObliqueSampleResolution()
Returns the oblique sample resolution at the current position in m.
Definition: Camera.cpp:711
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:164
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
double FocalLength() const
Returns the focal length.
Definition: Camera.cpp:2794
double p_minRingLongitude180
The minimum ring longitude in the 180 domain.
Definition: Camera.h:551
bool IntersectsLongitudeDomain(Pvl &pvl)
Checks whether the ground range intersects the longitude domain or not.
Definition: Camera.cpp:1239
Distance measurement, usually in meters.
Definition: Distance.h:47
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:135
bool RawFocalPlanetoImage()
Computes the image coordinate for the current universal ground point.
Definition: Camera.cpp:468
double p_maxres
The maximum resolution.
Definition: Camera.h:519
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:2313
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
virtual bool SetDetector(const double sample, const double line)
Compute distorted focal plane coordinate from detector position (sampel,line)
bool SetGround(Latitude latitude, Longitude longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:413
int Bands() const
Returns the number of bands in the image.
Definition: Camera.cpp:2856
double BetaLine(double alphaLine)
Returns a beta line given an alpha line.
Definition: AlphaCube.h:98
SpiceInt naifSpkCode() const
This returns the NAIF SPK code to use when reading from SPK kernels.
Definition: Spice.cpp:870
This class is used to rewrite the &quot;alpha&quot; keywords out of the AlphaCube group or Instrument group...
Definition: AlphaCube.h:61
CameraSkyMap * SkyMap()
Returns a pointer to the CameraSkyMap object.
Definition: Camera.cpp:2926
double DetectorLine() const
Return detector line.
bool HasReferenceBand() const
Checks to see if the Camera object has a reference band.
Definition: Camera.cpp:2732
double AlphaLine(double betaLine)
Returns an alpha line given a beta line.
Definition: AlphaCube.h:90
double p_minRingLongitude
The minimum ring longitude (azimuth)
Definition: Camera.h:549
virtual double exposureDuration() const
Return the exposure duration for the pixel that the camera is set to.
Definition: Camera.cpp:3113
int p_bands
The number of bands in the image.
Definition: Camera.h:531
bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
Definition: Camera.cpp:392
int BetaSamples() const
Returns the number of samples in the beta cube.
Definition: AlphaCube.h:86
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:248
void setHasIntersection(bool b)
Sets the flag to indicate whether this ShapeModel has an intersection.
Definition: ShapeModel.cpp:465
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:166
Convert between parent image coordinates and detector coordinates.
double DetectorSample() const
Return detector sample.
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1277
iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions...
Definition: Spice.cpp:804
bool p_ignoreProjection
Whether or no to ignore the Projection.
Definition: Camera.h:536
virtual bool SetGround(const Latitude &lat, const Longitude &lon)
Compute undistorted focal plane coordinate from ground position.
CameraDetectorMap * p_detectorMap
A pointer to the DetectorMap.
Definition: Camera.h:562
QString instrumentNameLong() const
This method returns the full instrument name.
Definition: Camera.cpp:2936
int sampleCount() const
Definition: Cube.cpp:1404
Convert between undistorted focal plane and ground coordinates.
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
double p_minlat
The minimum latitude.
Definition: Camera.h:514
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:69
Convert between distorted focal plane and detector coordinates.
std::vector< double > ReferenceVector(const std::vector< double > &jVec)
Given a direction vector in J2000, return a reference frame direction.
SpiceRotation * bodyRotation() const
Accessor method for the body rotation.
Definition: Spice.cpp:1465
QString m_instrumentNameShort
Shortened instrument name.
Definition: Camera.h:495
CameraGroundMap * GroundMap()
Returns a pointer to the CameraGroundMap object.
Definition: Camera.cpp:2916
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
int Samples() const
Returns the number of samples in the image.
Definition: Camera.cpp:2836
virtual bool SetUndistortedFocalPlane(double ux, double uy)
Compute distorted focal plane x/y.
virtual bool SetSky(const double ra, const double dec)
Compute undistorted focal plane coordinate from ra/dec.
double EmissionAngle() const
Returns the emission angle in degrees.
Definition: Sensor.cpp:339
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
double kilometers() const
Get the displacement in kilometers.
void ringRangeResolution()
Analogous to above GroundRangeResolution method.
Definition: Camera.cpp:1056
void subSolarPoint(double &lat, double &lon)
Returns the sub-solar latitude/longitude in universal coordinates (0-360 positive east...
Definition: Spice.cpp:1238
double HighestImageResolution()
Returns the highest/best resolution in the entire image.
Definition: Camera.cpp:784
double p_pixelPitch
The pixel pitch, in millimeters per pixel.
Definition: Camera.h:512
bool GroundRange(double &minlat, double &maxlat, double &minlon, double &maxlon, Pvl &pvl)
Computes the Ground Range.
Definition: Camera.cpp:1256
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
bool RaDecRange(double &minra, double &maxra, double &mindec, double &maxdec)
Computes the RaDec range.
Definition: Camera.cpp:1782
virtual bool SetFocalPlane(double dx, double dy)
Compute undistorted focal plane x/y.
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:204
double Sample()
Returns the current sample number.
Definition: Camera.cpp:2752
bool hasNormal() const
Returns surface point normal status.
Definition: ShapeModel.cpp:319
double AlphaSample(double betaSample)
Returns an alpha sample given a beta sample.
Definition: AlphaCube.h:94
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
A single keyword-value pair.
Definition: PvlKeyword.h:98
CameraFocalPlaneMap * p_focalPlaneMap
A pointer to the FocalPlaneMap.
Definition: Camera.h:561
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
int bandCount() const
Returns the number of virtual bands for the cube.
Definition: Cube.cpp:1077
double UniversalRingRadius()
This returns a universal radius, which is just the radius in meters.
void SetFocalPlaneMap(CameraFocalPlaneMap *map)
Sets the Focal Plane Map.
Definition: Camera.cpp:2426
int p_childBand
Band value for child.
Definition: Camera.h:559
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:1562
double HighestObliqueImageResolution()
Returns the highest/best oblique resolution in the entire image.
Definition: Camera.cpp:806
Distort/undistort focal plane coordinates.
double NorthAzimuth()
Returns the North Azimuth.
Definition: Camera.cpp:1968
std::pair< double, double > StartEndEphemerisTimes()
Calculates the start and end ephemeris times.
Definition: Camera.cpp:2546
double p_childSample
Sample value for child.
Definition: Camera.h:557
AlphaCube * p_alphaCube
!&lt; Flag showing if ring range was computed successfully.
Definition: Camera.h:556
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:112
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition: Sensor.cpp:270
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition: Sensor.cpp:201
virtual bool isDEM() const =0
Indicates whether this shape model is from a DEM.
void BasicMapping(Pvl &map)
Writes the basic mapping group to the specified Pvl.
Definition: Camera.cpp:1430
Container for cube-like labels.
Definition: Pvl.h:135
void clearSurfacePoint()
Clears or resets the current surface point.
Definition: ShapeModel.cpp:327
double SpacecraftAltitude()
Returns the distance from the spacecraft to the subspacecraft point in km.
Definition: Sensor.cpp:689
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
QString instrumentNameShort() const
This method returns the shortened instrument name.
Definition: Camera.cpp:2946
double UniversalLatitude()
This returns a universal latitude (planetocentric).
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2896
int Band()
Returns the current band.
Definition: Camera.cpp:2762
double UndistortedFocalPlaneZ() const
Return undistorted focal plane z.
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2489
Define shapes and provide utilities for Isis3 targets.
Definition: ShapeModel.h:68
double FocalPlaneY() const
Return undistorted focal plane y.
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:2116
double CelestialNorthClockAngle()
Computes the celestial north clock angle at the current line/sample or ra/dec.
Definition: Camera.cpp:3087
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition: Sensor.cpp:211
bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
Definition: Projection.cpp:483
Defines an angle and provides unit conversions.
Definition: Angle.h:58
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double p_maxra
The maxumum right ascension.
Definition: Camera.h:541
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:282
double LowestObliqueImageResolution()
Returns the lowest/worst oblique resolution in the entire image.
Definition: Camera.cpp:795
double BetaSample(double alphaSample)
Returns a beta sample given an alpha sample.
Definition: AlphaCube.h:102
QString m_spacecraftNameLong
Full spacecraft name.
Definition: Camera.h:496
int p_samples
The number of samples in the image.
Definition: Camera.h:529
double Longitude() const
This returns a longitude with correct longitude direction and domain as specified in the label object...
double FocalPlaneY() const
Return distorted focal plane y.
virtual bool IsBandIndependent()
Virtual method that checks if the band is independent.
Definition: Camera.cpp:2711
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:306
Base class for Map Projections of plane shapes.
double p_maxlon
The maximum longitude.
Definition: Camera.h:517
double DetectorSample() const
Return detector sample.
double LowestImageResolution()
Returns the lowest/worst resolution in the entire image.
Definition: Camera.cpp:773
CameraGroundMap * p_groundMap
A pointer to the GroundMap.
Definition: Camera.h:563
double PixelPitch() const
Returns the pixel pitch.
Definition: Camera.cpp:2804
double p_maxRingLongitude180
The maximum ring longitude in the 180 domain.
Definition: Camera.h:552
double Line()
Returns the current line number.
Definition: Camera.cpp:2772
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
double FocalPlaneY() const
Return distorted focal plane y.
double RaDecResolution()
Returns the RaDec resolution.
Definition: Camera.cpp:1924
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:432
double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition: Camera.cpp:744
Isis exception class.
Definition: IException.h:99
double p_minres
The minimum resolution.
Definition: Camera.h:518
double p_minlon180
The minimum longitude in the 180 domain.
Definition: Camera.h:522
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:888
Adds specific functionality to C++ strings.
Definition: IString.h:179
virtual bool SetDetector(const double sample, const double line)
Compute parent position from a detector coordinate.
double p_minra
The minimum right ascension.
Definition: Camera.h:540
double LineResolution()
Returns the line resolution at the current position in meters.
Definition: Camera.cpp:722
void SetDistortionMap(CameraDistortionMap *map)
Sets the Distortion Map.
Definition: Camera.cpp:2411
Convert between undistorted focal plane and ra/dec coordinates.
Definition: CameraSkyMap.h:47
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:497
The distance is being specified in meters.
Definition: Distance.h:56
void IgnoreProjection(bool ignore)
Set whether or not the camera should ignore the Projection.
Definition: Camera.cpp:2975
double p_maxRingRadius
The maximum ring radius.
Definition: Camera.h:548
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:118
virtual QList< QPointF > PixelIfovOffsets()
Returns the pixel ifov offsets from center of pixel, which defaults to the (pixel pitch * summing mod...
Definition: Camera.cpp:2815
double FocalPlaneX() const
Return distorted focal plane x.
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:76
virtual int SpkCenterId() const
Provides the center of motion body for SPK NAIF kernel.
Definition: Camera.cpp:3055
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2866
Projection * p_projection
A pointer to the Projection.
Definition: Camera.h:535
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:592
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:2616
double p_minRingRadius
!&lt; Flag showing if the raDec range has been computed successfully.
Definition: Camera.h:547
double p_maxdec
The maximum declination.
Definition: Camera.h:539
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:367
ProjectionType projectionType() const
Returns an enum value for the projection type.
Definition: Projection.cpp:213
SpiceDouble m_uB[3]
This contains the sun position (u) in the bodyfixed reference frame (B).
Definition: Spice.h:364
double FocalPlaneX() const
Return distorted focal plane x.
int ParentSamples() const
Returns the number of samples in the parent alphacube.
Definition: Camera.cpp:2876
int p_geometricTilingStartSize
The ideal geometric tile size to start with when projecting.
Definition: Camera.h:566
CameraSkyMap * p_skyMap
A pointer to the SkyMap.
Definition: Camera.h:564
int lineCount() const
Definition: Cube.cpp:1331
double UndistortedFocalPlaneX() const
Return undistorted focal plane x.
double SampleResolution()
Returns the sample resolution at the current position in meters.
Definition: Camera.cpp:700
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition: Camera.cpp:2742
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
int AlphaSamples() const
Returns the number of samples in the alpha cube.
Definition: AlphaCube.h:78
double UniversalRingLongitude()
This returns a universal ring longitude (clockwise in 0 to 360 domain).
bool p_pointComputed
!&lt; Flag showing if ground range was computed successfully.
Definition: Camera.h:527
int Lines() const
Returns the number of lines in the image.
Definition: Camera.cpp:2846
double p_childLine
Line value for child.
Definition: Camera.h:558
void GetGeometricTilingHint(int &startSize, int &endSize)
This will get the geometric tiling hint; these values are typically used for ProcessRubberSheet::SetT...
Definition: Camera.cpp:2667
double DetectorResolution()
Returns the detector resolution at the current position in meters.
Definition: Camera.cpp:679
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:958
void GroundRangeResolution()
Computes the ground range and min/max resolution.
Definition: Camera.cpp:815
int p_geometricTilingEndSize
The ideal geometric tile size to end with when projecting.
Definition: Camera.h:568
double ObliqueDetectorResolution()
This function provides an improved estimate of the detector resolution (in meters) when the target is...
Definition: Camera.cpp:641
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double WorldY() const
This returns the world Y coordinate provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:530
double Declination()
Returns the declination angle (sky latitude).
Definition: Sensor.cpp:564
These projections are used to map triaxial and irregular-shaped bodies.
Definition: Projection.h:180
IO Handler for Isis Cubes.
Definition: Cube.h:158
void subSpacecraftPoint(double &lat, double &lon)
Returns the sub-spacecraft latitude/longitude in universal coordinates (0-360 positive east...
Definition: Spice.cpp:1189

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:15:27