tcElevationOptimization: fix typo s/write/read/
[tecorrec.git] / geo / tcExportText.cpp
blobc771d1fc2b63c2107a6e9d7ab0cbe08d588025ae
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 /**
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>
32 #include <QLabel>
33 #include <QListWidget>
34 #include <QComboBox>
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)
46 : QWidget(parent)
47 , m_imagery(imagery)
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()));
106 /// Destructor.
107 tcExportText::~tcExportText()
112 * Public slots
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);
130 if (0 != channel)
132 channels += channel;
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."));
145 return;
148 // Get the portion of the image
149 Q_ASSERT(0);
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;
160 double rx1 = 0.0;
161 double ry1 = 0.0;
162 double rx2 = 1.0;
163 double ry2 = 1.0;
165 double x1,y1,x2,y2;
167 #define REWRITE_PORTION() \
168 { x1 = rx1; y1 = ry1; x2 = rx2; y2 = ry2; }
170 // Get all the pixel data objects
171 REWRITE_PORTION();
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."));
178 return;
180 Reference<tcAbstractPixelData> filterData;
181 if (0 != filter)
183 REWRITE_PORTION();
184 filterData = filter->portion(&x1,&y1,&x2,&y2);
185 if (0 == filterData)
187 QMessageBox::warning(this,
188 tr("No Filter Data."),
189 tr("No filter pixel data was found in this portion."));
190 return;
193 QList<Reference<tcAbstractPixelData> > channelsData;
194 foreach (tcChannel* channel, channels)
196 REWRITE_PORTION();
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()));
203 return;
207 QString filename = QFileDialog::getSaveFileName(this,
208 tr("Export channels"),
209 QString(),
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,
219 tr("Open failed."),
220 tr("Could not open '%1' for writing.").arg(filename));
221 return;
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);
236 // Check filter
237 if (0 != filterData)
239 float val = filterData->sampleFloat(x,y);
240 if (filterType == 0)
242 if (val > 0.0f)
244 continue;
247 else if (filterType == 1)
249 if (val <= 0.0f)
251 continue;
255 // Write vales
256 out << classificationData->buffer()[index];
257 for (int i = 0; i < channelsData.count(); ++i)
259 out << " " << channelsData[i]->sampleFloat(x, y);
261 out << "\n";
268 * Private slots
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)