Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Chip.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7
8#include "Chip.h"
9#include "Camera.h"
10#include "Cube.h"
11#include "IException.h"
12#include "Interpolator.h"
13#include "IString.h"
14#include "LineManager.h"
15#include "PolygonTools.h"
16#include "Portal.h"
17#include "Projection.h"
18#include "Statistics.h"
19#include "TProjection.h"
20
21#include <algorithm>
22#include <cmath>
23#include <string>
24#include <vector>
25
26#include <geos/geom/Point.h>
27#include <tnt/tnt_array2d_utils.h>
28
29using namespace std;
30namespace Isis {
31
36 Init(3, 3);
37 }
38
44 Chip::Chip(const Chip &other) {
47 m_buf = other.m_buf;
49 m_tackLine = other.m_tackLine;
50
53
56
58 m_chipLine = other.m_chipLine;
60 m_cubeLine = other.m_cubeLine;
61
62 if (other.m_clipPolygon) {
64 other.m_clipPolygon->clone().release());
65 }
66 else {
67 m_clipPolygon = NULL;
68 }
69
70 m_affine = other.m_affine;
72 m_filename = other.m_filename;
73 }
74
75
82 Chip::Chip(const int samples, const int lines) {
83 Init(samples, lines);
84 }
85
86
89 if (m_clipPolygon != NULL) delete m_clipPolygon;
90 }
91
92
100 void Chip::SetAllValues(const double &d) {
101 for (unsigned int i = 0; i < m_buf.size(); i++) {
102 fill(m_buf[i].begin(), m_buf[i].end(), d);
103 }
104 }
105
106
116 void Chip::Init(const int samples, const int lines) {
117 SetReadInterpolator(Interpolator::CubicConvolutionType);
118 SetSize(samples, lines);
120 m_clipPolygon = NULL;
121 }
122
123
134 void Chip::SetSize(const int samples, const int lines) {
135 if ( samples <= 0.0 || lines <= 0.0 ) {
136 QString msg;
137 msg += "Unable to set chip size to [";
138 msg += toString(samples) + ", ";
139 msg += toString(lines) + "]. Samples and lines must be greater than zero.";
140 throw IException(IException::User, msg, _FILEINFO_);
141 }
142 m_chipSamples = samples;
143 m_chipLines = lines;
144 m_buf.clear();
145 m_buf.resize(lines);
146 for (int i = 0; i < lines; i++) {
147 m_buf[i].resize(samples);
148 }
149 m_affine.Identity();
150 m_tackSample = ((samples - 1) / 2) + 1;
151 m_tackLine = ((lines - 1) / 2) + 1;
152 }
153
154
162 bool Chip::IsInsideChip(double sample, double line) {
163 double minSamp = m_cubeTackSample - ((m_chipSamples - 1) / 2);
164 double maxSamp = m_cubeTackSample + ((m_chipSamples - 1) / 2);
165
166 double minLine = m_cubeTackLine - ((m_chipLines - 1) / 2);
167 double maxLine = m_cubeTackLine + ((m_chipLines - 1) / 2);
168
169 if ( sample < minSamp || sample > maxSamp ) return false;
170 if ( line < minLine || line > maxLine ) return false;
171 return true;
172 }
173
174
182 void Chip::TackCube(const double cubeSample, const double cubeLine) {
183 m_cubeTackSample = cubeSample;
184 m_cubeTackLine = cubeLine;
185 m_affine.Identity();
187 }
188
189
203 void Chip::Load(Cube &cube, const double rotation, const double scale, const int band) {
204 // Initialize our affine transform
205 m_affine.Identity();
206
207 // We want an affine which translates from chip to cube. Note that we want to give adjusted
208 // chip coordinates such that (0,0) is at the chip tack point and maps to the cube tack point.
209 m_affine.Scale(scale);
210 m_affine.Rotate(rotation);
212
213 // Now go read the data from the cube into the chip
214 Read(cube, band);
215
216 // Store off the cube address in case someone wants to match this chip
217 m_filename = cube.fileName();
218 }
219
220
244 void Chip::Load(Cube &cube, const Affine &affine, const bool &keepPoly, const int band) {
245
246 // Set the tackpoint center to the cube location
247 SetTransform(affine);
249
250 // Remove the clipping polygon if requested
251 if (!keepPoly) {
252 delete m_clipPolygon;
253 m_clipPolygon = 0;
254 }
255
256 // Now go read the data from the cube into the chip
257 Read(cube, band);
258
259 // Store off the cube address in case someone wants to match this chip
260 m_filename = cube.fileName();
261 }
262
263
300 void Chip::Load(Cube &cube, Chip &match, Cube &matchChipCube, const double scale, const int band)
301 {
302 // See if the match cube has a camera or projection
303 Camera *matchCam = NULL;
304 TProjection *matchProj = NULL;
305 try {
306 matchCam = matchChipCube.camera();
307 }
308 catch (IException &error1) {
309 try {
310 matchProj = (TProjection *) matchChipCube.projection();
311 }
312 catch (IException &error2) {
313 QString msg = "Can not geom chip. ";
314 msg += "Match chip cube [" + matchChipCube.fileName();
315 msg += "] is not a camera or map projection";
316
317 IException fullError(IException::User, msg, _FILEINFO_);
318 fullError.append(error1);
319 fullError.append(error2);
320
321 throw fullError;
322 }
323 }
324
325 // See if the cube we are loading has a camera/projection
326 Camera *cam = NULL;
327 Projection *proj = NULL;
328 try {
329 cam = cube.camera();
330 }
331 catch (IException &error1) {
332 try {
333 proj = cube.projection();
334 }
335 catch (IException &error2) {
336 QString msg = "Can not geom chip. ";
337 msg += "Chip cube [" + cube.fileName();
338 msg += "] is not a camera or map projection";
339
340 IException fullError(IException::User, msg, _FILEINFO_);
341 fullError.append(error1);
342 fullError.append(error2);
343
344 throw fullError;
345 }
346 }
347
348 // Ok we can attempt to create an affine transformation that maps our chip to the match chip.
349 // We will need a set of at least 3 control points so we can fit the affine transform.
350 // We will try to find 4 points, one from each corner of the chip.
351 vector<double> x(4), y(4);
352 vector<double> xp(4), yp(4);
353
354 // Choose these control points by beginning at each corner and moving inward in the chip
355 // until an acceptable point is found
356 // i = 0, start at upper left corner (1, 1)
357 // i = 1, start at lower left corner (1, Lines()-1)
358 // i = 2, start at upper right corner (Samples()-1, 1)
359 // i = 3, start at lower right corner (Samples()-1, Lines()-1)
360 for (int i = 0; i < (int) xp.size(); i++) {
361 // define initial values for starting/ending sample/line for each index
362 int startSamp = 1;
363 int startLine = 1;
364 int endSamp = Samples() - 1;
365 int endLine = Lines() - 1;
366
367 bool pointfound = false;
368 while (!pointfound) {
369 // start and end may cross (see MovePoints())
370 // if we move outside chip, break out of loop
371 if (startSamp < 1 || startSamp > Samples() - 1 ||
372 endSamp < 1 || endSamp > Samples() - 1 ||
373 startLine < 1 || startLine > Lines() - 1 ||
374 endLine < 1 || endLine > Lines() - 1) {
375 // unable to find acceptable control point from this corner
376 // erase point and go to the next corner
377 x.erase(x.begin() + i);
378 y.erase(y.begin() + i);
379 xp.erase(xp.begin() + i);
380 yp.erase(yp.begin() + i);
381 i--;
382 break;
383 }
384 int chipSamp, chipLine;
385 if (i < 2) {
386 chipSamp = startSamp;
387 }
388 else {
389 chipSamp = endSamp;
390 }
391 if (i % 2 == 0) {
392 chipLine = startLine;
393 }
394 else {
395 chipLine = endLine;
396 }
397 // Determine the offset from the tack point in our chip to one of the four corners.
398 int sampOffset = chipSamp - TackSample();
399 int lineOffset = chipLine - TackLine();
400
401 // Use this offset to compute a chip position in the match chip.
402 double matchChipSamp = match.TackSample() + sampOffset;
403 double matchChipLine = match.TackLine() + lineOffset;
404
405 // Now get the lat/lon at that chip position.
406 match.SetChipPosition(matchChipSamp, matchChipLine);
407 double lat, lon;
408 if (matchCam != NULL) {
409 matchCam->SetImage(match.CubeSample(), match.CubeLine());
410 if (!matchCam->HasSurfaceIntersection() ) {
411 vector<int> newlocation = MovePoints(startSamp, startLine, endSamp, endLine);
412 startSamp = newlocation[0];
413 startLine = newlocation[1];
414 endSamp = newlocation[2];
415 endLine = newlocation[3];
416 continue;
417 }
418 lat = matchCam->UniversalLatitude();
419 lon = matchCam->UniversalLongitude();
420 }
421 else {
422 matchProj->SetWorld(match.CubeSample(), match.CubeLine() );
423 if (!matchProj->IsGood() ) {
424 vector<int> newlocation = MovePoints(startSamp, startLine, endSamp, endLine);
425 startSamp = newlocation[0];
426 startLine = newlocation[1];
427 endSamp = newlocation[2];
428 endLine = newlocation[3];
429 continue;
430 }
431 lat = matchProj->UniversalLatitude();
432 lon = matchProj->UniversalLongitude();
433 }
434
435 // Now use that lat/lon to find a line/sample in our chip
436 double line, samp;
437 if (cam != NULL) {
438 cam->SetUniversalGround(lat, lon);
439 if (!cam->HasSurfaceIntersection() ) {
440 vector<int> newlocation = MovePoints(startSamp, startLine, endSamp, endLine);
441 startSamp = newlocation[0];
442 startLine = newlocation[1];
443 endSamp = newlocation[2];
444 endLine = newlocation[3];
445 continue;
446 }
447 samp = cam->Sample(); // getting negative sample?!?!?!
448 line = cam->Line();
449 }
450 else {
451 proj->SetUniversalGround(lat, lon);
452 if (!proj->IsGood()) {
453 vector<int> newlocation = MovePoints(startSamp, startLine, endSamp, endLine);
454 startSamp = newlocation[0];
455 startLine = newlocation[1];
456 endSamp = newlocation[2];
457 endLine = newlocation[3];
458 continue;
459 }
460 samp = proj->WorldX();
461 line = proj->WorldY();
462 }
463
464 // if (line < 1 || line > cube.lineCount()) continue;
465 // if (samp < 1 || samp > cube.sampleCount()) continue;
466
467 // Ok save this control point
468 pointfound = true;
469 x[i] = sampOffset;
470 y[i] = lineOffset;
471 xp[i] = samp;
472 yp[i] = line;
473
474 // If we get 3 points on the same line, affine transform will fail.
475 // Choose a one degree default tolerance for linearity check method.
476 double tol = 1.0;
477 // If we have already removed a point, use a stricter tolerance of 2 degrees.
478 if (xp.size() == 3) {
479 tol = 2.0;
480 }
481 if (i > 1) {
482 if ( PointsColinear(xp[0], yp[0], xp[1], yp[1], xp[i], yp[i], tol) ) {
483 // try to find a point further along that is not colinear
484 pointfound = false;
485 vector<int> newlocation = MovePoints(startSamp, startLine, endSamp, endLine);
486 startSamp = newlocation[0];
487 startLine = newlocation[1];
488 endSamp = newlocation[2];
489 endLine = newlocation[3];
490 continue;
491 }
492 }
493 }
494 }
495
496 if (xp.size() < 3) {
497 QString msg = "Cannot find enough points to perform Affine transformation. ";
498 msg += "Unable to load chip from [" + cube.fileName();
499 msg += "] to match chip from [" + matchChipCube.fileName() + "].";
500 throw IException(IException::User, msg, _FILEINFO_);
501 }
502
503 // Now take our control points and create the affine map
504 m_affine.Solve(&x[0], &y[0], &xp[0], &yp[0], (int)x.size());
505
506 // TLS 8/3/06 Apply scale
507 m_affine.Scale(scale);
508
509 // Finally we need to make the affine map the tack point to the requested cube sample/line
510 m_affine.Compute(0.0, 0.0);
511 double cubeSampleOffset = m_cubeTackSample - m_affine.xp();
512 double cubeLineOffset = m_cubeTackLine - m_affine.yp();
513 m_affine.Translate(cubeSampleOffset, cubeLineOffset);
514
515 // Now go read the data from the cube into the chip
516 Read(cube, band);
517
518 // Store off the cube address in case someone wants to match
519 // this chip
520 m_filename = cube.fileName();
521 }
522
523
546 bool Chip::PointsColinear(const double x0, const double y0, const double x1, const double y1,
547 const double x2, const double y2, const double tol) {
548 // check angles at each point of the triangle composed of the 3 points
549 // if any angle is near 0 or 180 degrees, then the points are almost colinear
550
551 // we have the following property:
552 // sin(theta) = |v x w|/(|v|*|w|) where
553 // v=(vx,vy) and w=(wx,wy) are the vectors that define the angle theta
554 // |v| is the magnitude (norm) of the vector. In 2D, this is |v| = sqrt(vx^2 + vy^2)
555 // v x w is the cross product of the vectors. In 2D, this is v x w = vx*wy-vy*wx
556 // See equations (5) and (6) at http://mathworld.wolfram.com/CrossProduct.html
557
558
559 // first find the vectors that define the angles at each point
560 // For example, if we shift the point P0 to the origin,
561 // the vectors defining the angle at P0
562 // are v01 = (x1-x0, y1-y0) and v02 = (x2-x0, y2-y0)
563 // Note: v10 = -v01 and |v x w| = |w x v|
564 // so we only need 3 vectors and the order we use these doesn't matter
565 vector<double> v01, v12, v20;
566 v01.push_back(x1 - x0);
567 v01.push_back(y1 - y0);
568 v12.push_back(x2 - x1);
569 v12.push_back(y2 - y1);
570 v20.push_back(x0 - x2);
571 v20.push_back(y0 - y2);
572
573 // sin(angle at P0) = |v01 x v02|/(|v01|*|v02|) =
574 // |v01x*v02y-v01y*v02x|/(sqrt(v01x^2+v01y^2)*sqrt(v01x^2+v02y^2))
575 double sinP0 = fabs(v01[0] * v20[1] - v01[1] * v20[0]) /
576 sqrt((pow(v01[0], 2) + pow(v01[1], 2)) * (pow(v12[0], 2) + pow(v12[1], 2)));
577 // sin(angle at P1)
578 double sinP1 = fabs(v12[0] * v20[1] - v12[1] * v20[0]) /
579 sqrt((pow(v12[0], 2) + pow(v12[1], 2)) * (pow(v20[0], 2) + pow(v20[1], 2)));
580 // sin(angle at P2)
581 double sinP2 = fabs(v20[0] * v01[1] - v20[1] * v01[0]) /
582 sqrt((pow(v20[0], 2) + pow(v20[1], 2)) * (pow(v01[0], 2) + pow(v01[1], 2)));
583
584 // We will seek angles with sine near 0 (thus a multiple of 180 degrees or pi radians)
585 // We will use a tolerance of tol degrees (tol*pi/180 radians)
586 // Compare the smallest sine value to the sine of tol,
587 // if it is less, then the angle is less than tol degrees or
588 // greater than 180-tol degrees, so points are almost colinear
589 double minSinValue = min(sinP0, min(sinP1, sinP2));
590 if ( minSinValue < sin(tol * PI / 180) ) {
591 return true;
592 }
593 else {
594 return false;
595 }
596 }
597
598
615 vector<int> Chip::MovePoints(const int startSamp, const int startLine,
616 const int endSamp, const int endLine) {
617 vector<int> newlocations(4);
618 int sinc = (endSamp - startSamp) / 4;
619 // Ensures that the inc can cause start and end to cross
620 if (sinc < 1) {
621 sinc = 1;
622 }
623 int linc = (endLine - startLine) / 3;
624 // Ensures that the inc can cause start and end to cross
625 if (linc < 1) {
626 linc = 1;
627 }
628 newlocations[0] = startSamp + sinc;
629 newlocations[1] = startLine + linc;
630 newlocations[2] = endSamp - sinc;
631 newlocations[3] = endLine - linc;
632 return newlocations;
633 }
634
643 void Chip::SetChipPosition(const double sample, const double line) {
644 m_chipSample = sample;
645 m_chipLine = line;
646 m_affine.Compute(sample - TackSample(), line - TackLine());
647 m_cubeSample = m_affine.xp();
648 m_cubeLine = m_affine.yp();
649 }
650
651
660 void Chip::SetCubePosition(const double sample, const double line) {
661 m_cubeSample = sample;
662 m_cubeLine = line;
663 m_affine.ComputeInverse(sample, line);
665 m_chipLine = m_affine.y() + TackLine();
666 }
667
668
681 void Chip::SetValidRange(const double minimum, const double maximum) {
682 if (minimum >= maximum) {
683 QString msg = "Unable to set valid chip range to [" + toString(minimum);
684 msg += ", " + toString(maximum) + "]. First parameter must be smaller than the second.";
685 throw IException(IException::Programmer, msg, _FILEINFO_);
686 }
687
688 m_validMinimum = minimum;
689 m_validMaximum = maximum;
690 }
691
692
701 bool Chip::IsValid(double percentage) {
702 int validCount = 0;
703 for (int samp = 1; samp <= Samples(); samp++) {
704 for (int line = 1; line <= Lines(); line++) {
705 if (IsValid(samp, line)) validCount++;
706 }
707 }
708 double validPercentage = 100.0 * (double) validCount /
709 (double)(Samples() * Lines());
710 if (validPercentage < percentage) return false;
711 return true;
712 }
713
714
727 Chip Chip::Extract(int samples, int lines, int samp, int line) {
728 if ( samples > Samples() || lines > Lines() ) {
729 QString msg = "Cannot extract sub-chip of size [" + toString(samples);
730 msg += ", " + toString(lines) + "] from chip of size [" + toString(Samples());
731 msg += ", " + toString(Lines()) + "]";
732 throw IException(IException::Programmer, msg, _FILEINFO_);
733 }
734
735 Chip chipped(samples, lines);
736 for (int oline = 1; oline <= lines; oline++) {
737 for (int osamp = 1; osamp <= samples; osamp++) {
738 int thisSamp = samp + (osamp - chipped.TackSample());
739 int thisLine = line + (oline - chipped.TackLine());
740 if ((thisSamp < 1) ||
741 (thisLine < 1) ||
742 (thisSamp > Samples()) ||
743 (thisLine > Lines()) ) {
744 chipped.SetValue(osamp, oline, Isis::Null);
745 }
746 else {
747 chipped.SetValue(osamp, oline, GetValue(thisSamp, thisLine));
748 }
749 }
750 }
751
752 chipped.m_affine = m_affine;
755 chipped.m_tackSample = chipped.TackSample() + TackSample() - samp;
756 chipped.m_tackLine = chipped.TackLine() + TackLine() - line;
757
758 return chipped;
759 }
760
772 void Chip::Extract(int samp, int line, Chip &chipped) {
773 int samples = chipped.Samples();
774 int lines = chipped.Lines();
775 //chipped.Init(samples, lines);
776 chipped.m_tackSample = ((samples - 1) / 2) + 1;
777 chipped.m_tackLine = ((lines - 1) / 2) + 1;
778
779 for (int oline = 1; oline <= lines; oline++) {
780 for (int osamp = 1; osamp <= samples; osamp++) {
781 int thisSamp = samp + (osamp - chipped.TackSample());
782 int thisLine = line + (oline - chipped.TackLine());
783 if ((thisSamp < 1) ||
784 (thisLine < 1) ||
785 (thisSamp > Samples()) ||
786 (thisLine > Lines()) ) {
787 chipped.SetValue(osamp, oline, Isis::Null);
788 }
789 else {
790 chipped.SetValue(osamp, oline, GetValue(thisSamp, thisLine));
791 }
792 }
793 }
794
795 chipped.m_affine = m_affine;
798 chipped.m_tackSample = chipped.TackSample() + TackSample() - samp;
799 chipped.m_tackLine = chipped.TackLine() + TackLine() - line;
800
801 return;
802 }
803
804
846 void Chip::Extract(Chip &chipped, Affine &affine) {
847 // Create an interpolator and portal for interpolation
848 Interpolator interp(Interpolator::BiLinearType);
849 Portal port(interp.Samples(), interp.Lines(), Isis::Double,
850 interp.HotSample(), interp.HotLine());
851
852 int samples = chipped.Samples();
853 int lines = chipped.Lines();
854
855 for (int oline = 1; oline <= lines; oline++) {
856 int relativeLine = oline - chipped.TackLine();
857 for (int osamp = 1; osamp <= samples; osamp++) {
858 int relativeSamp = osamp - chipped.TackSample();
859 affine.Compute(relativeSamp, relativeLine);
860 double xp = affine.xp() + TackSample();
861 double yp = affine.yp() + TackLine();
862 port.SetPosition(xp, yp, 1);
863 for (int i = 0; i < port.size(); i++) {
864 int csamp = port.Sample(i);
865 int cline = port.Line(i);
866 if ((csamp < 1) ||
867 (cline < 1) ||
868 (csamp > Samples()) ||
869 (cline > Lines()) ) {
870 port[i] = Isis::Null;
871 }
872 else {
873 port[i] = GetValue(csamp, cline);
874 }
875 }
876 chipped.SetValue(osamp, oline, interp.Interpolate(xp, yp, port.DoubleBuffer()));
877 }
878 }
879
882 chipped.m_filename = m_filename;
883
884 // Make necessary adjustments to remaining chip elements. Note that this matrix multiply
885 // acheives a completed transform of two Affine matrices.
886 // No translations are required - only update tack points.
887 chipped.m_affine = Affine(TNT::matmult(affine.Forward(), m_affine.Forward()));
888
889 affine.Compute(0.0, 0.0);
890 chipped.m_cubeTackSample = m_cubeTackSample + affine.xp();
891 chipped.m_cubeTackLine = m_cubeTackLine + affine.yp();
892
893 chipped.m_chipSample = chipped.TackSample();
894 chipped.m_chipLine = chipped.TackLine();
895 chipped.m_cubeSample = chipped.m_cubeTackSample;
896 chipped.m_cubeLine = chipped.m_cubeTackLine;
897
898 return;
899 }
900
901
910 Isis::Statistics *stats = new Isis::Statistics();
911
912 stats->SetValidRange(m_validMinimum, m_validMaximum);
913
914 for (int i = 0; i < m_chipSamples; i++) {
915 stats->AddData(&m_buf[i][0], m_chipLines);
916 }
917
918 return stats;
919 }
920
921
939 void Chip::Read(Cube &cube, const int band) {
940 // Create an interpolator and portal for geoming
942 Portal port(interp.Samples(), interp.Lines(), cube.pixelType(),
943 interp.HotSample(), interp.HotLine());
944 // Loop through the pixels in the chip and geom them
945 for (int line = 1; line <= Lines(); line++) {
946 for (int samp = 1; samp <= Samples(); samp++) {
947 SetChipPosition((double)samp, (double)line);
948 if ((CubeSample() < 0.5) ||
949 (CubeLine() < 0.5) ||
950 (CubeSample() > cube.sampleCount() + 0.5) ||
951 (CubeLine() > cube.lineCount() + 0.5)) {
952
953 m_buf[line-1][samp-1] = Isis::NULL8;
954 }
955 else if (m_clipPolygon == NULL) {
956 port.SetPosition(CubeSample(), CubeLine(), band);
957 cube.read(port);
958 m_buf[line-1][samp-1] =
959 interp.Interpolate(CubeSample(), CubeLine(), port.DoubleBuffer());
960 }
961 else {
962 std::unique_ptr<geos::geom::Point> pnt = globalFactory->createPoint(
963 geos::geom::Coordinate(CubeSample(), CubeLine()));
964 if (pnt->within(m_clipPolygon)) {
965 port.SetPosition(CubeSample(), CubeLine(), band);
966 cube.read(port);
967 m_buf[line-1][samp-1] =
968 interp.Interpolate(CubeSample(), CubeLine(), port.DoubleBuffer());
969 }
970 else {
971 m_buf[line-1][samp-1] = Isis::NULL8;
972 }
973 pnt.reset();
974 }
975 }
976 }
977 }
978
979
985 void Chip::Write(const QString &filename) {
986 Cube c;
987 c.setDimensions(Samples(), Lines(), 1);
988 c.create(filename);
989 LineManager line(c);
990 for (int i = 1; i <= Lines(); i++) {
991 line.SetLine(i);
992 for (int j = 1; j <= Samples(); j++) {
993 line[j-1] = GetValue(j, i);
994 }
995 c.write(line);
996 }
997 c.close();
998 }
999
1000
1008 void Chip::SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon) {
1009 if (m_clipPolygon != NULL) delete m_clipPolygon;
1011 }
1012
1013
1021 Chip &Chip::operator=(const Chip &other) {
1023 m_chipLines = other.m_chipLines;
1024 m_buf = other.m_buf;
1025 m_tackSample = other.m_tackSample;
1026 m_tackLine = other.m_tackLine;
1027
1030
1033
1034 m_chipSample = other.m_chipSample;
1035 m_chipLine = other.m_chipLine;
1036 m_cubeSample = other.m_cubeSample;
1037 m_cubeLine = other.m_cubeLine;
1038
1039 // Free allocated memory.
1040 if (m_clipPolygon) {
1041 delete m_clipPolygon;
1042 m_clipPolygon = NULL;
1043 }
1044
1045 if (other.m_clipPolygon) {
1047 other.m_clipPolygon->clone().release());
1048 }
1049
1050 m_affine = other.m_affine;
1052 m_filename = other.m_filename;
1053
1054 return *this;
1055 }
1056} // end namespace isis
Affine basis function.
Definition Affine.h:65
AMatrix Forward() const
Returns the forward Affine matrix.
Definition Affine.h:127
double xp() const
Returns the computed x'.
Definition Affine.h:86
double yp() const
Returns the computed y'.
Definition Affine.h:95
void Compute(double x, double y)
Compute (xp,yp) given (x,y).
Definition Affine.cpp:191
int size() const
Returns the total number of pixels in the shape buffer.
Definition Buffer.h:97
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition Buffer.cpp:145
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition Buffer.h:138
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
Definition Buffer.cpp:127
virtual double Line() const
Returns the current line number.
Definition Camera.cpp:2740
virtual double Sample() const
Returns the current sample number.
Definition Camera.cpp:2720
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition Camera.cpp:156
virtual bool SetUniversalGround(const double latitude, const double longitude)
Sets the lat/lon values to get the sample/line values.
Definition Camera.cpp:382
double CubeLine() const
Definition Chip.h:210
Affine m_affine
Transform set by SetTransform.
Definition Chip.h:366
void SetReadInterpolator(const Interpolator::interpType type)
Sets Interpolator Type for loading a chip.
Definition Chip.h:323
double m_cubeTackSample
cube sample at the chip tack
Definition Chip.h:352
void SetSize(const int samples, const int lines)
Change the size of the Chip.
Definition Chip.cpp:134
void Write(const QString &filename)
Writes the contents of the Chip to a cube.
Definition Chip.cpp:985
double GetValue(int sample, int line)
Loads a Chip with a value.
Definition Chip.h:145
Interpolator::interpType m_readInterpolator
Interpolator type set by.
Definition Chip.h:369
void SetTransform(const Affine &affine, const bool &keepPoly=true)
Sets the internal Affine transform to new translation.
Definition Chip.h:290
int Samples() const
Definition Chip.h:99
double m_cubeSample
cube sample set by SetCubePosition
Definition Chip.h:360
void SetValidRange(const double minimum=Isis::ValidMinimum, const double maximum=Isis::ValidMaximum)
Set the valid range of data in the chip.
Definition Chip.cpp:681
bool PointsColinear(double x0, double y0, double x1, double y1, double x2, double y2, double tol)
This method is called by Load() to determine whether the given 3 points are nearly colinear.
Definition Chip.cpp:546
double m_cubeLine
cube line set by SetCubePosition
Definition Chip.h:361
int TackSample() const
This method returns a chip's fixed tack sample; the middle of the chip.
Definition Chip.h:176
std::vector< std::vector< double > > m_buf
Chip buffer.
Definition Chip.h:348
bool IsInsideChip(double sample, double line)
Definition Chip.cpp:162
int Lines() const
Definition Chip.h:106
void SetAllValues(const double &d)
Single value assignment operator.
Definition Chip.cpp:100
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
Definition Chip.cpp:643
double m_chipLine
chip line set by SetChip/CubePosition
Definition Chip.h:359
double m_validMinimum
valid minimum chip pixel value
Definition Chip.h:355
int m_tackSample
Middle sample of the chip.
Definition Chip.h:349
Isis::Statistics * Statistics()
Returns a statistics object of the current data in the chip.
Definition Chip.cpp:909
void SetClipPolygon(const geos::geom::MultiPolygon &clipPolygon)
Sets the clipping polygon for this chip.
Definition Chip.cpp:1008
std::vector< int > MovePoints(int startSamp, int startLine, int endSamp, int endLine)
This method is called by Load() to move a control point across the chip.
Definition Chip.cpp:615
void Read(Cube &cube, const int band)
This method reads data from a cube and puts it into the chip.
Definition Chip.cpp:939
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition Chip.cpp:182
double CubeSample() const
Definition Chip.h:203
bool IsValid(int sample, int line)
Definition Chip.h:240
int m_tackLine
Middle line of the chip.
Definition Chip.h:350
virtual ~Chip()
Destroys the Chip object.
Definition Chip.cpp:88
Chip Extract(int samples, int lines, int samp, int line)
Extract a sub-chip from a chip.
Definition Chip.cpp:727
int m_chipLines
Number of lines in the chip.
Definition Chip.h:347
geos::geom::MultiPolygon * m_clipPolygon
clipping polygon set by SetClipPolygon
Definition Chip.h:363
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Definition Chip.cpp:203
int TackLine() const
This method returns a chip's fixed tack line; the middle of the chip.
Definition Chip.h:187
Chip & operator=(const Chip &other)
Copy assignment operator.
Definition Chip.cpp:1021
Chip()
Constructs a Chip.
Definition Chip.cpp:35
void SetCubePosition(const double sample, const double line)
Compute the position of the chip given a cube coordinate.
Definition Chip.cpp:660
void SetValue(int sample, int line, const double &value)
Sets a value in the chip.
Definition Chip.h:126
void Init(const int samples, const int lines)
Common initialization used by constructors.
Definition Chip.cpp:116
double m_cubeTackLine
cube line at the chip tack
Definition Chip.h:353
double m_chipSample
chip sample set by SetChip/CubePosition
Definition Chip.h:358
QString m_filename
FileName of loaded cube.
Definition Chip.h:373
int m_chipSamples
Number of samples in the chip.
Definition Chip.h:346
double m_validMaximum
valid maximum chip pixel value
Definition Chip.h:356
IO Handler for Isis Cubes.
Definition Cube.h:168
int lineCount() const
Definition Cube.cpp:1767
void setDimensions(int ns, int nl, int nb)
Used prior to the Create method to specify the size of the cube.
Definition Cube.cpp:1230
Camera * camera()
Return a camera associated with the cube.
Definition Cube.cpp:1464
int sampleCount() const
Definition Cube.cpp:1840
void create(const QString &cfile)
This method will create an isis cube for writing.
Definition Cube.cpp:416
PixelType pixelType() const
Definition Cube.cpp:1791
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition Cube.cpp:820
virtual QString fileName() const
Returns the opened cube's filename.
Definition Cube.cpp:1596
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition Cube.cpp:984
void close(bool remove=false)
Closes the cube and updates the labels.
Definition Cube.cpp:262
Projection * projection()
Definition Cube.cpp:1827
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception's causational exc...
Pixel interpolator.
int Samples()
Returns the number of samples needed by the interpolator.
int Lines()
Returns the number of lines needed by the interpolator.
double HotSample()
Returns the sample coordinate of the center pixel in the buffer for the interpolator.
double HotLine()
Returns the line coordinate of the center pixel in the buffer for the interpolator.
double Interpolate(const double isamp, const double iline, const double buf[])
Performs an interpolation on the data according to the parameters set in the constructor.
Buffer manager, for moving through a cube in lines.
Definition LineManager.h:39
bool SetLine(const int line, const int band=1)
Positions the buffer at the requested line and returns a status indicator if the set was succesful or...
static geos::geom::MultiPolygon * CopyMultiPolygon(const geos::geom::MultiPolygon *mpolygon)
This static method will create a deep copy of a geos::geom::MultiPolygon.
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
Buffer for containing a two dimensional section of an image.
Definition Portal.h:36
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Definition Portal.h:93
Base class for Map Projections.
Definition Projection.h:155
virtual bool SetUniversalGround(const double coord1, const double coord2)
This method is used to set the lat/lon or radius/azimuth (i.e.
virtual bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
virtual double WorldY() const
This returns the world Y coordinate provided SetGround, SetCoordinate, SetUniversalGround,...
virtual double WorldX() const
This returns the world X coordinate provided SetGround, SetCoordinate, SetUniversalGround,...
bool IsGood() const
This indicates if the last invocation of SetGround, SetCoordinate, SetUniversalGround,...
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition Sensor.cpp:212
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition Sensor.cpp:188
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition Sensor.cpp:235
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:93
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Base class for Map TProjections.
virtual double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
virtual double UniversalLatitude()
This returns a universal latitude (planetocentric).
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
const double Null
Value for an Isis Null pixel.
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.