1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file tcExportText.cpp
22 * @brief Exports a set of channels to a file.
25 #include "tcExportText.h"
26 #include "tcChannel.h"
27 #include "tcChannelManager.h"
28 #include "tcGeoImageData.h"
29 #include "tcPixelData.h"
31 #include <QVBoxLayout>
33 #include <QListWidget>
35 #include <QPushButton>
36 #include <QMessageBox>
37 #include <QFileDialog>
38 #include <QTextStream>
41 * Constructors + destructor
44 /// Primary constructor.
45 tcExportText::tcExportText(const QList
<tcGeoImageData
*>& imagery
, QWidget
* parent
)
49 tcChannelManager
* channelManager
= m_imagery
[0]->channelManager();
50 setWindowTitle(tr("Export as Text"));
52 QVBoxLayout
* layout
= new QVBoxLayout(this);
54 QLabel
* labelClassificationChannel
= new QLabel(tr("Classification channel"), this);
55 layout
->addWidget(labelClassificationChannel
);
56 m_comboClassificationChannel
= new QComboBox(this);
57 layout
->addWidget(m_comboClassificationChannel
);
58 labelClassificationChannel
->setBuddy(m_comboClassificationChannel
);
59 for (int i
= 0; i
< channelManager
->numChannels(); ++i
)
61 tcChannel
* channel
= channelManager
->channel(i
);
62 m_comboClassificationChannel
->addItem(channel
->name());
64 connect(m_comboClassificationChannel
, SIGNAL(currentIndexChanged(int)),
65 this, SLOT(setClassificationChannel(int)));
67 QLabel
* labelFilterChannel
= new QLabel(tr("Filter channel"), this);
68 layout
->addWidget(labelFilterChannel
);
69 m_comboFilterChannel
= new QComboBox(this);
70 layout
->addWidget(m_comboFilterChannel
);
71 labelFilterChannel
->setBuddy(m_comboFilterChannel
);
72 m_comboFilterChannel
->addItem(tr("(Export all pixels)"));
73 for (int i
= 0; i
< channelManager
->numChannels(); ++i
)
75 tcChannel
* channel
= channelManager
->channel(i
);
76 m_comboFilterChannel
->addItem(channel
->name());
78 connect(m_comboFilterChannel
, SIGNAL(currentIndexChanged(int)),
79 this, SLOT(setFilterChannel(int)));
80 m_comboFilterType
= new QComboBox(this);
81 layout
->addWidget(m_comboFilterType
);
82 m_comboFilterType
->addItem(tr("Export dark values"));
83 m_comboFilterType
->addItem(tr("Export light values"));
84 m_comboFilterType
->setEnabled(false);
85 connect(m_comboFilterType
, SIGNAL(currentIndexChanged(int)),
86 this, SLOT(setFilterType(int)));
88 QLabel
* labelChannels
= new QLabel(tr("Channels to export"), this);
89 layout
->addWidget(labelChannels
);
90 m_listChannels
= new QListWidget(this);
91 layout
->addWidget(m_listChannels
);
92 labelChannels
->setBuddy(m_listChannels
);
93 for (int i
= 0; i
< channelManager
->numChannels(); ++i
)
95 tcChannel
* channel
= channelManager
->channel(i
);
96 m_listChannels
->addItem(channel
->name());
97 QListWidgetItem
* item
= m_listChannels
->item(i
);
98 item
->setCheckState(Qt::Unchecked
);
101 QPushButton
* btnSave
= new QPushButton(tr("Export"), this);
102 layout
->addWidget(btnSave
);
103 connect(btnSave
, SIGNAL(clicked(bool)), this, SLOT(exportToFile()));
107 tcExportText::~tcExportText()
115 /// Export to a file.
116 void tcExportText::exportToFile()
118 tcChannelManager
* channelManager
= m_imagery
[0]->channelManager();
120 // Get the data together.
121 tcChannel
* classification
= channelManager
->channel(m_comboClassificationChannel
->currentIndex());
122 tcChannel
* filter
= channelManager
->channel(m_comboFilterChannel
->currentIndex()-1);
123 int filterType
= m_comboFilterType
->currentIndex();
124 QList
<tcChannel
*> channels
;
125 for (int i
= 0; i
< m_listChannels
->count(); ++i
)
127 if (m_listChannels
->item(i
)->checkState() == Qt::Checked
)
129 tcChannel
* channel
= channelManager
->channel(i
);
136 Q_ASSERT(0 != classification
);
137 Q_ASSERT(filterType
< 2);
139 // Check there are enough channels.
140 if (channels
.count() == 0)
142 QMessageBox::warning(this,
143 tr("No Channels Ticked."),
144 tr("You haven't ticked any channels to export."));
148 // Get the portion of the image
151 tcGeoImageData::LocalCoord min = m_imagery[0]->minLocal();
152 tcGeoImageData::LocalCoord range = m_imagery[0]->rangeLocal();
153 tcGeoImageData::LocalCoord minEffective = m_imagery[0]->minEffectiveLocal();
154 tcGeoImageData::LocalCoord rangeEffective = m_imagery[0]->rangeEffectiveLocal();
155 double rx1 = (minEffective.x - min.x) / range.x;
156 double ry1 = 1.0 - (minEffective.y + rangeEffective.y - min.y) / range.y;
157 double rx2 = (minEffective.x + rangeEffective.x - min.x) / range.x;
158 double ry2 = 1.0 - (minEffective.y - min.y) / range.y;
167 #define REWRITE_PORTION() \
168 { x1 = rx1; y1 = ry1; x2 = rx2; y2 = ry2; }
170 // Get all the pixel data objects
172 Reference
<tcPixelData
<float> > classificationData
= dynamicCast
<tcPixelData
<float>*>(classification
->portion(&x1
,&y1
,&x2
,&y2
));
173 if (0 == classificationData
)
175 QMessageBox::warning(this,
176 tr("No Classification Data."),
177 tr("No classification pixel data was found in this portion."));
180 Reference
<tcAbstractPixelData
> filterData
;
184 filterData
= filter
->portion(&x1
,&y1
,&x2
,&y2
);
187 QMessageBox::warning(this,
188 tr("No Filter Data."),
189 tr("No filter pixel data was found in this portion."));
193 QList
<Reference
<tcAbstractPixelData
> > channelsData
;
194 foreach (tcChannel
* channel
, channels
)
197 channelsData
+= channel
->portion(&x1
,&y1
,&x2
,&y2
);
198 if (0 == channelsData
[channelsData
.count()-1])
200 QMessageBox::warning(this,
201 tr("No %1 Data.").arg(channel
->name()),
202 tr("No %1 pixel data was found in this portion.").arg(channel
->name()));
207 QString filename
= QFileDialog::getSaveFileName(this,
208 tr("Export channels"),
210 tr("ASCII Data Files (*.adf)"));
212 if (!filename
.isEmpty())
214 // Open the file ready to write the data
215 QFile
file(filename
);
216 if (!file
.open(QIODevice::WriteOnly
| QIODevice::Text
))
218 QMessageBox::warning(this,
220 tr("Could not open '%1' for writing.").arg(filename
));
224 QTextStream
out(&file
);
226 // Go through the classification data and sample the other channels
227 int width
= classificationData
->width();
228 int height
= classificationData
->height();
229 for (int j
= 0; j
< height
; ++j
)
231 for (int i
= 0; i
< width
; ++i
)
233 int index
= j
*height
+ i
;
234 float x
= (float)i
/(width
-1);
235 float y
= (float)j
/(height
-1);
239 float val
= filterData
->sampleFloat(x
,y
);
247 else if (filterType
== 1)
256 out
<< classificationData
->buffer()[index
];
257 for (int i
= 0; i
< channelsData
.count(); ++i
)
259 out
<< " " << channelsData
[i
]->sampleFloat(x
, y
);
271 /// Set the channel to classify the pixels.
272 void tcExportText::setClassificationChannel(int channel
)
276 /// Set the channel to filter which pixels to export.
277 void tcExportText::setFilterChannel(int channel
)
279 m_comboFilterType
->setEnabled(channel
!= 0);
282 /// Set the type of filtering.
283 void tcExportText::setFilterType(int channel
)