7 #include "ProjectionFactory.h"
16 #include "Displacement.h"
19 #include "IException.h"
21 #include "Projection.h"
22 #include "RingPlaneProjection.h"
23 #include "TProjection.h"
28 Plugin ProjectionFactory::m_projPlugin;
57 if (m_projPlugin.fileName() ==
"") {
58 FileName localFile(
"Projection.plugin");
60 m_projPlugin.read(localFile.
expanded());
62 FileName systemFile(
"$ISISROOT/lib/Projection.plugin");
64 m_projPlugin.read(systemFile.
expanded());
70 QString proj = mapGroup[
"ProjectionName"];
75 ptr = m_projPlugin.GetPlugin(proj);
78 QString msg =
"Unsupported projection, unable to find plugin for [" +
80 throw IException(e, IException::Unknown, msg, _FILEINFO_);
91 QString message =
"Unable to initialize Projection information ";
92 message +=
"from group [Mapping]";
93 throw IException(e, IException::Io, message, _FILEINFO_);
120 bool allowDefaults) {
125 if (m_projPlugin.fileName() ==
"") {
126 FileName localFile(
"Projection.plugin");
128 m_projPlugin.read(localFile.
expanded());
130 FileName systemFile(
"$ISISROOT/lib/Projection.plugin");
132 m_projPlugin.read(systemFile.
expanded());
138 QString proj = mapGroup[
"ProjectionName"];
141 QFunctionPointer ptr;
143 ptr = m_projPlugin.GetPlugin(proj);
146 QString msg =
"Unsupported projection, unable to find plugin for [" +
148 throw IException(e, IException::Unknown, msg, _FILEINFO_);
155 return (
Projection *) (*plugin)(label, allowDefaults);
158 QString message =
"Unable to initialize Projection information ";
159 message +=
"from group [Mapping]";
160 throw IException(e, IException::Io, message, _FILEINFO_);
189 int &samples,
int &lines,
194 double localRadius = proj->
LocalRadius(trueScaleLat);
200 double scale, pixelResolution;
203 pixelResolution = mapGroup[
"PixelResolution"];
204 scale = (2.0 *
Isis::PI * localRadius) / (360.0 * pixelResolution);
211 scale = mapGroup[
"Scale"];
212 pixelResolution = (2.0 *
Isis::PI * localRadius) / (360.0 * scale);
224 bool sizeFound =
false;
225 double upperLeftX =
Null, upperLeftY =
Null;
228 samples = dims[
"Samples"];
229 lines = dims[
"Lines"];
231 upperLeftX = mapGroup[
"UpperLeftCornerX"];
232 upperLeftY = mapGroup[
"UpperLeftCornerY"];
235 if (!sizeMatch) sizeFound =
false;
243 QString msg =
"Invalid ground range [MinimumLatitude,MaximumLatitude,";
244 msg +=
"MinimumLongitude,MaximumLongitude] missing or invalid";
245 throw IException(IException::Unknown, msg, _FILEINFO_);
248 double minX, maxX, minY, maxY;
249 if (!proj->
XYRange(minX, maxX, minY, maxY)) {
250 QString msg =
"Invalid ground range [MinimumLatitude,MaximumLatitude,";
251 msg +=
"MinimumLongitude,MaximumLongitude] cause invalid computation ";
252 msg +=
"of image size";
253 throw IException(IException::Unknown, msg, _FILEINFO_);
267 double minXFlipped = minX;
268 double maxXFlipped = maxX;
269 double minYFlipped = minY;
270 double maxYFlipped = maxY;
281 if (fabs(fmod(minXFlipped, pixelResolution)) > 1.0e-6) {
282 if (pixelResolution - fabs(fmod(minXFlipped, pixelResolution)) > 1.0e-6) {
283 double sampleOffset = floor(minXFlipped / pixelResolution);
285 minXFlipped = sampleOffset * pixelResolution;
295 if (maxXFlipped < minXFlipped + pixelResolution) {
296 maxXFlipped = minXFlipped + pixelResolution;
308 if (fabs(fmod(maxYFlipped, pixelResolution)) > 1.0e-6) {
309 if (abs(pixelResolution - fabs(fmod(maxYFlipped, pixelResolution))) > 1.0e-6) {
310 double lineOffset = ceil(maxYFlipped / pixelResolution);
311 maxYFlipped = lineOffset * pixelResolution;
319 if (minYFlipped > maxYFlipped - pixelResolution) {
320 minYFlipped = maxYFlipped - pixelResolution;
325 samples = (int)((maxXFlipped - minXFlipped) / pixelResolution + 0.5);
326 lines = (int)((maxYFlipped - minYFlipped) / pixelResolution + 0.5);
335 upperLeftX = minXFlipped;
345 upperLeftY = maxYFlipped;
366 (QString) mapGroup[
"PixelResolution"],
367 "meters/pixel"), Isis::Pvl::Replace);
370 (QString) mapGroup[
"Scale"],
371 "pixels/degree"), Isis::Pvl::Replace);
374 (QString) mapGroup[
"UpperLeftCornerX"],
375 "meters"), Isis::Pvl::Replace);
378 (QString) mapGroup[
"UpperLeftCornerY"],
379 "meters"), Isis::Pvl::Replace);
382 (QString) mapGroup[
"EquatorialRadius"],
383 "meters"), Isis::Pvl::Replace);
386 (QString) mapGroup[
"PolarRadius"],
387 "meters"), Isis::Pvl::Replace);
397 QString msg =
"Unable to create projection";
399 IException finalError(IException::Unknown, msg, _FILEINFO_);
400 finalError.
append(errors);
433 int &samples,
int &lines,
bool sizeMatch) {
445 double scale, pixelResolution;
448 pixelResolution = mapGroup[
"PixelResolution"];
449 scale = (2.0 *
Isis::PI * localRadius) / (360.0 * pixelResolution);
455 scale = mapGroup[
"Scale"];
456 pixelResolution = (2.0 *
Isis::PI * localRadius) / (360.0 * scale);
472 bool sizeFound =
false;
473 double upperLeftX =
Null, upperLeftY =
Null;
476 samples = dims[
"Samples"];
477 lines = dims[
"Lines"];
479 upperLeftX = mapGroup[
"UpperLeftCornerX"];
480 upperLeftY = mapGroup[
"UpperLeftCornerY"];
494 QString msg =
"Invalid ring range [MinimumRingRadius,MaximumRingRadius,";
495 msg +=
"MinimumRingLongitude,MaximumRingLongitude] missing or invalid";
496 throw IException(IException::Unknown, msg, _FILEINFO_);
499 double minX, maxX, minY, maxY;
500 if (!proj->
XYRange(minX, maxX, minY, maxY)) {
501 QString msg =
"Invalid ring range [MinimumRingRadius,MaximumRingRadius,";
502 msg +=
"MinimumRingLongitude,MaximumRingLongitude] cause invalid computation ";
503 msg +=
"of image size";
504 throw IException(IException::Unknown, msg, _FILEINFO_);
513 if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
514 if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
515 double sampleOffset = floor(minX / pixelResolution);
516 minX = sampleOffset * pixelResolution;
521 if (maxX < minX + pixelResolution) {
522 maxX = minX + pixelResolution;
524 if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
525 if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
526 double lineOffset = -1.0 * ceil(maxY / pixelResolution);
527 maxY = -1.0 * lineOffset * pixelResolution;
532 if (minY > maxY - pixelResolution) {
533 minY = maxY - pixelResolution;
537 samples = (int)((maxX - minX) / pixelResolution + 0.5);
538 lines = (int)((maxY - minY) / pixelResolution + 0.5);
555 mapGroup.AddKeyword(
Isis::PvlKeyword(
"SampleProjectionOffset", sampleOffset),
563 (QString) mapGroup[
"PixelResolution"],
564 "meters/pixel"), Isis::Pvl::Replace);
567 (QString) mapGroup[
"Scale"],
568 "pixels/degree"), Isis::Pvl::Replace);
571 (QString) mapGroup[
"UpperLeftCornerX"],
572 "meters"), Isis::Pvl::Replace);
575 (QString) mapGroup[
"UpperLeftCornerY"],
576 "meters"), Isis::Pvl::Replace);
586 QString msg =
"Unable to create projection";
588 IException finalError(IException::Unknown, msg, _FILEINFO_);
589 finalError.
append(errors);
622 int &samples,
int &lines,
627 double localRadius = proj->
LocalRadius(trueScaleLat);
632 double scale, pixelResolution;
635 pixelResolution = mapGroup[
"PixelResolution"];
636 scale = (2.0 *
Isis::PI * localRadius) / (360.0 * pixelResolution);
641 scale = mapGroup[
"Scale"];
642 pixelResolution = (2.0 *
Isis::PI * localRadius) / (360.0 * scale);
653 double minX = DBL_MAX;
654 double maxX = -DBL_MAX;
655 double minY = DBL_MAX;
656 double maxY = -DBL_MAX;
659 int eband = cam.
Bands();
661 for(
int band = 1; band <= eband; band++) {
665 for(
int line = 0; line <= cam.
Lines(); line++) {
669 for(samp = 0; samp <= cam.
Samples(); samp++) {
670 if (cam.
SetImage((
double)samp + 0.5, (double)line + 0.5)) {
679 if ((line != 0) && (line != cam.
Lines()))
break;
686 for(samp = cam.
Samples(); samp >= 0; samp--) {
687 if (cam.
SetImage((
double)samp + 0.5, (double)line + 0.5)) {
705 if (cam.
Sample() >= 0.5 && cam.
Line() >= 0.5 &&
720 if (cam.
Sample() >= 0.5 && cam.
Line() >= 0.5 &&
738 for(
double lat = p_minlat; lat <= p_maxlat; lat += (p_maxlat - p_minlat) / 10.0) {
739 if (SetUniversalGround(lat, 0.0)) {
740 if (Sample() >= 0.5 && Line() >= 0.5 &&
741 Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
752 for(
double lat = p_minlat; lat <= p_maxlat; lat += (p_maxlat - p_minlat) / 10.0) {
753 if (SetUniversalGround(lat, 180.0)) {
754 if (Sample() >= 0.5 && Line() >= 0.5 &&
755 Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
756 p_minlon180 = -180.0;
771 if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
772 if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
773 double sampleOffset = floor(minX / pixelResolution);
774 minX = sampleOffset * pixelResolution;
779 if (maxX < minX + pixelResolution) {
780 maxX = minX + pixelResolution;
782 if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
783 if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
784 double lineOffset = -1.0 * ceil(maxY / pixelResolution);
785 maxY = -1.0 * lineOffset * pixelResolution;
790 if (minY > maxY - pixelResolution) {
791 minY = maxY - pixelResolution;
795 samples = (int)((maxX - minX) / pixelResolution + 0.5);
796 lines = (int)((maxY - minY) / pixelResolution + 0.5);
799 double upperLeftX = minX;
803 double upperLeftY = maxY;
809 (QString) mapGroup[
"PixelResolution"],
810 "meters/pixel"), Isis::Pvl::Replace);
813 (QString) mapGroup[
"Scale"],
814 "pixels/degree"), Isis::Pvl::Replace);
817 (QString) mapGroup[
"UpperLeftCornerX"],
818 "meters"), Isis::Pvl::Replace);
821 (QString) mapGroup[
"UpperLeftCornerY"],
822 "meters"), Isis::Pvl::Replace);
825 (QString) mapGroup[
"EquatorialRadius"],
826 "meters"), Isis::Pvl::Replace);
829 (QString) mapGroup[
"PolarRadius"],
830 "meters"), Isis::Pvl::Replace);
840 QString msg =
"Unable to create projection";
842 throw IException(e, IException::Unknown, msg, _FILEINFO_);
873 int &samples,
int &lines,
Camera &cam) {
883 double scale, pixelResolution;
886 pixelResolution = mapGroup[
"PixelResolution"];
887 scale = (2.0 *
Isis::PI * localRadius) / (360.0 * pixelResolution);
894 scale = mapGroup[
"Scale"];
895 pixelResolution = (2.0 *
Isis::PI * localRadius) / (360.0 * scale);
899 "meters/pixel"), Isis::Pvl::Replace);
905 double minX = DBL_MAX;
906 double maxX = -DBL_MAX;
907 double minY = DBL_MAX;
908 double maxY = -DBL_MAX;
911 int eband = cam.
Bands();
913 for(
int band = 1; band <= eband; band++) {
917 for(
int line = 0; line <= cam.
Lines(); line++) {
921 for(samp = 0; samp <= cam.
Samples(); samp++) {
922 if (cam.
SetImage((
double)samp + 0.5, (double)line + 0.5)) {
931 if ((line != 0) && (line != cam.
Lines()))
break;
938 for(samp = cam.
Samples(); samp >= 0; samp--) {
939 if (cam.
SetImage((
double)samp + 0.5, (double)line + 0.5)) {
959 for(
double rad = p_minRadius; rad <= p_maxRadius; rad += (p_maxRadius - p_minRadius) / 10.0) {
960 if (SetUniversalGround(rad, 0.0)) {
961 if (Sample() >= 0.5 && Line() >= 0.5 &&
962 Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
973 for(
double rad = p_minrad; rad <= p_maxrad; rad += (p_maxrad - p_minrad) / 10.0) {
974 if (SetUniversalGround(rad, 180.0)) {
975 if (Sample() >= 0.5 && Line() >= 0.5 &&
976 Sample() <= p_samples + 0.5 && Line() <= p_lines + 0.5) {
992 if (fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
993 if (pixelResolution - fabs(fmod(minX, pixelResolution)) > 1.0e-6) {
994 double sampleOffset = floor(minX / pixelResolution);
995 minX = sampleOffset * pixelResolution;
1000 if (maxX < minX + pixelResolution) {
1001 maxX = minX + pixelResolution;
1004 if (fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
1005 if (pixelResolution - fabs(fmod(maxY, pixelResolution)) > 1.0e-6) {
1006 double lineOffset = -1.0 * ceil(maxY / pixelResolution);
1007 maxY = -1.0 * lineOffset * pixelResolution;
1012 if (minY > maxY - pixelResolution) {
1013 minY = maxY - pixelResolution;
1017 samples = (int)((maxX - minX) / pixelResolution + 0.5);
1018 lines = (int)((maxY - minY) / pixelResolution + 0.5);
1021 double upperLeftX = minX;
1023 Isis::Pvl::Replace);
1025 double upperLeftY = maxY;
1027 Isis::Pvl::Replace);
1031 (QString) mapGroup[
"PixelResolution"],
1032 "meters/pixel"), Isis::Pvl::Replace);
1035 (QString) mapGroup[
"Scale"],
1036 "pixels/degree"), Isis::Pvl::Replace);
1039 (QString) mapGroup[
"UpperLeftCornerX"],
1040 "meters"), Isis::Pvl::Replace);
1043 (QString) mapGroup[
"UpperLeftCornerY"],
1044 "meters"), Isis::Pvl::Replace);
1054 QString msg =
"Unable to create projection";
1055 if (label.
fileName() !=
"") msg +=
" from file [" + label.
fileName() +
"]";
1056 throw IException(e, IException::Unknown, msg, _FILEINFO_);
1070 return CreateFromCube(*cube.
label());
1082 return RingsCreateFromCube(*cube.
label());
1100 double pixelResolution = mapGroup[
"PixelResolution"];
1103 double upperLeftX = mapGroup[
"UpperLeftCornerX"];
1104 double upperLeftY = mapGroup[
"UpperLeftCornerY"];
1117 QString msg =
"Unable to initialize cube projection";
1118 if (label.
fileName() !=
"") msg +=
" from file [" + label.
fileName() +
"]";
1119 throw IException(e, IException::Unknown, msg, _FILEINFO_);
1139 double pixelResolution = mapGroup[
"PixelResolution"];
1142 double upperLeftX = mapGroup[
"UpperLeftCornerX"];
1143 double upperLeftY = mapGroup[
"UpperLeftCornerY"];
1156 QString msg =
"Unable to initialize cube projection";
1157 if (label.
fileName() !=
"") msg +=
" from file [" + label.
fileName() +
"]";
1158 throw IException(e, IException::Unknown, msg, _FILEINFO_);