1#include "SpatialPlotTool.h"
5#include <geos/geom/Polygon.h>
6#include <geos/geom/Point.h>
12#include <QStackedWidget>
17#include "CubePlotCurve.h"
19#include "InterestOperator.h"
22#include "MdiCubeViewport.h"
24#include "PolygonTools.h"
25#include "Projection.h"
26#include "RingPlaneProjection.h"
27#include "TProjection.h"
29#include "RubberBandComboBox.h"
30#include "RubberBandTool.h"
31#include "Statistics.h"
32#include "SurfacePoint.h"
34#include "UniversalGroundMap.h"
71 rubberBandTool()->setDrawActiveViewportOnly(
false);
86 QString text =
"<b>Function:</b> Create a spatial plot of the selected pixels' DN values.";
112 Interpolator::NearestNeighborType);
114 Interpolator::BiLinearType);
116 Interpolator::CubicConvolutionType);
125 QHBoxLayout *layout =
new QHBoxLayout(wrapper);
126 layout->setMargin(0);
128 layout->addWidget(
new QLabel(
"Interpolation:"));
130 layout->addWidget(abstractToolWidgets);
131 layout->addWidget(m_xUnitsCombo);
132 layout->addStretch(1);
133 wrapper->setLayout(layout);
148 m_xUnitsCombo->currentIndex()).toInt();
150 while (m_xUnitsCombo->count())
151 m_xUnitsCombo->removeItem(0);
155 bool haveGroundMaps =
true;
160 if (haveGroundMaps) {
165 if (m_xUnitsCombo->findData(preferredUnits) != -1) {
166 m_xUnitsCombo->setCurrentIndex(
167 m_xUnitsCombo->findData(preferredUnits));
170 m_xUnitsCombo->setVisible(m_xUnitsCombo->count() > 1);
183 m_xUnitsCombo->currentIndex()).toInt(),
210 if (rubberBandTool()->isValid()) {
214 QMessageBox::information(NULL,
"Error",
215 "The selected Area contains no valid pixels",
228 if (activeViewport && rubberBandTool()->isValid()) {
234 m_xUnitsCombo->itemData(m_xUnitsCombo->currentIndex()).toInt()) {
243 if (data.size() > 0) {
244 QList<QPoint> rubberBandPoints = rubberBandTool()->vertices();
249 (*m_spatialCurves)[viewport]->setData(
new QwtPointSeriesData(data));
250 (*m_spatialCurves)[viewport]->setSource(
251 viewport, rubberBandPoints, band);
270 m_xUnitsCombo->currentIndex()).toInt();
272 QPen spatialPen(Qt::white);
273 spatialPen.setWidth(1);
274 spatialPen.setStyle(Qt::SolidLine);
282 targetWindow->
add(plotCurve);
321 m_xUnitsCombo->currentIndex()).toInt();
323 if (cvp && vertices.size()) {
334 if (rubberBandTool()->currentMode() == RubberBandTool::LineMode) {
335 double startSample =
Null;
336 double endSample =
Null;
337 double startLine =
Null;
338 double endLine =
Null;
341 startSample, startLine);
346 int lineLength = qRound(sqrt(pow(startSample - endSample, 2) +
347 pow(startLine - endLine, 2)));
352 if (groundMap->
SetImage(startSample, startLine)) {
353 startPoint = resultToSurfacePoint(groundMap);
356 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
357 tr(
"Failed to project points along line"),
358 tr(
"Failed to project (calculate a latitude, longitude, and radius) for the "
359 "starting point of the line (sample [%1], line [%2]).")
360 .arg(startSample).arg(startLine));
365 if (lineLength > 0) {
366 for(
int index = 0; index <= lineLength; index++) {
368 double sample = (index / (double)lineLength) * (endSample - startSample) +
371 sample -= (interp.
Samples() / 2.0 - 0.5);
373 double line = (index / (double)lineLength) * (endLine - startLine) +
375 line -= (interp.
Lines() / 2.0 - 0.5);
383 double plotXValue = index + 1;
388 if (groundMap->
SetImage(sample, line)) {
392 plotXValue = xDistance.
meters();
397 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
398 tr(
"Failed to project points along line"),
399 tr(
"Failed to project (calculate a latitude, longitude, and radius) for a "
400 "point along the line (sample [%1], line [%2]).")
401 .arg(startSample).arg(startLine));
406 data.append(QPointF(plotXValue, result));
411 QMessageBox::information(NULL,
"Error",
412 "The selected Area contains no valid pixels",
416 else if (rubberBandTool()->currentMode() == RubberBandTool::RotatedRectangleMode) {
446 double clickSample =
Null;
447 double clickLine =
Null;
448 double acrossSample =
Null;
449 double acrossLine =
Null;
450 double endSample =
Null;
451 double endLine =
Null;
454 clickSample, clickLine);
456 acrossSample, acrossLine);
460 double acrossVectorX = acrossSample - clickSample;
461 double acrossVectorY = acrossLine - clickLine;
464 int acrossLength = qRound(sqrt(acrossVectorX * acrossVectorX +
465 acrossVectorY * acrossVectorY));
467 double sampleStepAcross = (1.0 / (double)acrossLength) * acrossVectorX;
468 double lineStepAcross = (1.0 / (double)acrossLength) * acrossVectorY;
470 double lengthVectorSample = endSample - clickSample;
471 double lengthVectorLine = endLine - clickLine;
474 int rectangleLength = qRound(sqrt(lengthVectorSample * lengthVectorSample +
475 lengthVectorLine * lengthVectorLine));
478 if (rectangleLength == 0) {
485 double midStartSample = (clickSample + acrossSample) / 2.0;
486 double midStartLine = (clickLine + acrossLine) / 2.0;
487 if (groundMap->
SetImage(midStartSample, midStartLine)) {
488 startPoint = resultToSurfacePoint(groundMap);
491 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
492 tr(
"Failed to project points along line"),
493 tr(
"Failed to project (calculate a latitude, longitude, and radius) for the "
494 "starting point of the line (sample [%1], line [%2]).")
495 .arg(midStartSample).arg(midStartLine));
501 for(
int index = 0; index <= rectangleLength; index++) {
505 double sample = (index / (double)rectangleLength) * lengthVectorSample +
508 sample -= (interp.
Samples() / 2.0 - 0.5);
510 double line = (index / (double)rectangleLength) * lengthVectorLine +
512 line -= (interp.
Lines() / 2.0 - 0.5);
514 double sampleMid = sample + (acrossLength / 2.0) * sampleStepAcross;
515 double lineMid = line + (acrossLength / 2.0) * lineStepAcross;
519 for(
int acrossPixel = 0;
520 acrossPixel <= acrossLength;
524 double pixelValue = interp.
Interpolate(sample + 0.5, line + 0.5,
528 acrossStats.
AddData(pixelValue);
531 sample += sampleStepAcross;
532 line += lineStepAcross;
536 double plotXValue = index + 1;
539 if (groundMap->
SetImage(sampleMid, lineMid)) {
543 plotXValue = xDistance.
meters();
548 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
549 tr(
"Failed to project points along line"),
550 tr(
"Failed to project (calculate a latitude, longitude, and radius) for a "
551 "point along the line (sample [%1], line [%2]).")
552 .arg(sampleMid).arg(lineMid));
557 data.append(QPointF(plotXValue, acrossStats.
Average()));
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
double * DoubleBuffer() const
Returns the value of the shape buffer.
PixelType pixelType() const
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
This is a plot curve with information relating it to a particular cube or region of a cube.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
UniversalGroundMap * universalGroundMap() const
Distance measurement, usually in meters.
double kilometers() const
Get the distance in kilometers.
@ Meters
The distance is being specified in meters.
double meters() const
Get the distance in meters.
int Samples()
Returns the number of samples needed by the interpolator.
int Lines()
Returns the number of lines needed by the interpolator.
interpType
The interpolator type, including: None, Nearest Neighbor, BiLinear or Cubic Convultion.
void SetType(const interpType &type)
Sets the type of interpolation.
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.
This class is designed to encapsulate the concept of a Latitude.
This class is designed to encapsulate the concept of a Longitude.
Cube display widget for certain Isis MDI applications.
Units
These are all the possible units for the x or y data in a plot curve.
@ CubeDN
The data is a Cube DN value.
@ Kilometers
The data is in kilometers.
@ PixelNumber
The data is a pixel #.
@ Meters
The data is in meters.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
void replot()
Reset the scale of the plot, replot it and emit plot changed.
PlotCurve::Units xAxisUnits() const
This is the data-type of the curves' x data in this plot window.
Buffer for containing a two dimensional section of an image.
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Combo box for choosing a rubber band type.
@ RotatedRectangle
RotatedRectangle.
Distance LocalRadius() const
Returns the local radius at the intersection point.
This class is used to accumulate statistics on double arrays.
double Average() const
Computes and returns the average.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
This class defines a body-fixed surface point.
Distance GetDistanceToPoint(const SurfacePoint &other) const
Computes and returns the distance between two surface points.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection.
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
Isis::Projection * Projection() const
Return the projection associated with the ground map (NULL implies none)
Isis::Camera * Camera() const
Return the camera associated with the ground map (NULL implies none)
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
const double Null
Value for an Isis Null pixel.
bool IsSpecial(const double d)
Returns if the input pixel is special.