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->setContentsMargins(0, 0, 0, 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);
315 m_xUnitsCombo->currentIndex()).toInt();
317 if (cvp && vertices.size()) {
328 if (rubberBandTool()->currentMode() == RubberBandTool::LineMode) {
329 double startSample = Null;
330 double endSample = Null;
331 double startLine = Null;
332 double endLine = Null;
335 startSample, startLine);
340 int lineLength = qRound(sqrt(pow(startSample - endSample, 2) +
341 pow(startLine - endLine, 2)));
346 if (groundMap->
SetImage(startSample, startLine)) {
347 startPoint = resultToSurfacePoint(groundMap);
350 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
351 tr(
"Failed to project points along line"),
352 tr(
"Failed to project (calculate a latitude, longitude, and radius) for the "
353 "starting point of the line (sample [%1], line [%2]).")
354 .arg(startSample).arg(startLine));
359 if (lineLength > 0) {
360 for(
int index = 0; index <= lineLength; index++) {
362 double sample = (index / (double)lineLength) * (endSample - startSample) +
365 sample -= (interp.
Samples() / 2.0 - 0.5);
367 double line = (index / (double)lineLength) * (endLine - startLine) +
369 line -= (interp.
Lines() / 2.0 - 0.5);
376 if (!IsSpecial(result)) {
377 double plotXValue = index + 1;
382 if (groundMap->
SetImage(sample, line)) {
386 plotXValue = xDistance.
meters();
391 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
392 tr(
"Failed to project points along line"),
393 tr(
"Failed to project (calculate a latitude, longitude, and radius) for a "
394 "point along the line (sample [%1], line [%2]).")
395 .arg(startSample).arg(startLine));
400 data.append(QPointF(plotXValue, result));
405 QMessageBox::information(NULL,
"Error",
406 "The selected Area contains no valid pixels",
410 else if (rubberBandTool()->currentMode() == RubberBandTool::RotatedRectangleMode) {
440 double clickSample = Null;
441 double clickLine = Null;
442 double acrossSample = Null;
443 double acrossLine = Null;
444 double endSample = Null;
445 double endLine = Null;
448 clickSample, clickLine);
450 acrossSample, acrossLine);
454 double acrossVectorX = acrossSample - clickSample;
455 double acrossVectorY = acrossLine - clickLine;
458 int acrossLength = qRound(sqrt(acrossVectorX * acrossVectorX +
459 acrossVectorY * acrossVectorY));
461 double sampleStepAcross = (1.0 / (double)acrossLength) * acrossVectorX;
462 double lineStepAcross = (1.0 / (double)acrossLength) * acrossVectorY;
464 double lengthVectorSample = endSample - clickSample;
465 double lengthVectorLine = endLine - clickLine;
468 int rectangleLength = qRound(sqrt(lengthVectorSample * lengthVectorSample +
469 lengthVectorLine * lengthVectorLine));
472 if (rectangleLength == 0) {
479 double midStartSample = (clickSample + acrossSample) / 2.0;
480 double midStartLine = (clickLine + acrossLine) / 2.0;
481 if (groundMap->
SetImage(midStartSample, midStartLine)) {
482 startPoint = resultToSurfacePoint(groundMap);
485 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
486 tr(
"Failed to project points along line"),
487 tr(
"Failed to project (calculate a latitude, longitude, and radius) for the "
488 "starting point of the line (sample [%1], line [%2]).")
489 .arg(midStartSample).arg(midStartLine));
495 for(
int index = 0; index <= rectangleLength; index++) {
499 double sample = (index / (double)rectangleLength) * lengthVectorSample +
502 sample -= (interp.
Samples() / 2.0 - 0.5);
504 double line = (index / (double)rectangleLength) * lengthVectorLine +
506 line -= (interp.
Lines() / 2.0 - 0.5);
508 double sampleMid = sample + (acrossLength / 2.0) * sampleStepAcross;
509 double lineMid = line + (acrossLength / 2.0) * lineStepAcross;
513 for(
int acrossPixel = 0;
514 acrossPixel <= acrossLength;
518 double pixelValue = interp.
Interpolate(sample + 0.5, line + 0.5,
521 if (!IsSpecial(pixelValue)) {
522 acrossStats.
AddData(pixelValue);
525 sample += sampleStepAcross;
526 line += lineStepAcross;
529 if (!IsSpecial(acrossStats.
Average())) {
530 double plotXValue = index + 1;
533 if (groundMap->
SetImage(sampleMid, lineMid)) {
537 plotXValue = xDistance.
meters();
542 QMessageBox::warning(qobject_cast<QWidget *>(parent()),
543 tr(
"Failed to project points along line"),
544 tr(
"Failed to project (calculate a latitude, longitude, and radius) for a "
545 "point along the line (sample [%1], line [%2]).")
546 .arg(sampleMid).arg(lineMid));
551 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.
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.
double LocalRadius() const
Returns the radius of the camera model or projection.
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.