Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
MosaicController.cpp
1#include "MosaicController.h"
2
3#include <QAction>
4#include <QApplication>
5#include <QBuffer>
6#include <QFileDialog>
7#include <QFuture>
8#include <QFutureWatcher>
9#include <QGraphicsScene>
10#include <QGraphicsView>
11#include <QInputDialog>
12#include <QMenu>
13#include <QMessageBox>
14#include <QProgressBar>
15#include <QRegularExpression>
16#include <QSettings>
17#include <QUuid>
18#include <QtConcurrentMap>
19
20#include "ControlNet.h"
21#include "Cube.h"
22#include "DisplayProperties.h"
23#include "FileName.h"
24#include "IException.h"
25#include "ImageFileListWidget.h"
26#include "ImageReader.h"
27#include "MosaicSceneWidget.h"
28#include "ProgressBar.h"
29#include "Pvl.h"
30#include "PvlObject.h"
31#include "TextFile.h"
32
33
34namespace Isis {
35
45 MosaicController::MosaicController(QStatusBar *status, QSettings &settings) {
46 m_fileList = NULL;
47 m_scene = NULL;
48 m_worldScene = NULL;
49 m_imageReader = NULL;
50
51 m_mutex = new QMutex;
52
53 m_imageReader = new ImageReader(m_mutex);
54
55 connect(m_imageReader, SIGNAL(imagesReady(ImageList)), this, SLOT(imagesReady(ImageList)));
56
57 m_fileList = new ImageFileListWidget;
58 m_scene = new MosaicSceneWidget(status, true, false, NULL);
59 m_worldScene = new MosaicSceneWidget(status, false, false, NULL);
60
61 connect(this, SIGNAL(imagesAdded(ImageList)), m_scene, SLOT(addImages(ImageList)));
62 connect(this, SIGNAL(imagesAdded(ImageList)), m_worldScene, SLOT(addImages(ImageList)));
63 connect(this, SIGNAL(imagesAdded(ImageList *)), m_fileList, SLOT(addImages(ImageList *)));
64
65 connect(m_scene, SIGNAL(projectionChanged(Projection *)),
66 m_worldScene, SLOT(setProjection(Projection *)));
67 connect(m_scene, SIGNAL(visibleRectChanged(QRectF)),
68 m_worldScene, SLOT(setOutlineRect(QRectF)));
69
70 settings.beginGroup("MosaicController");
71 m_maxThreads = settings.value("maxThreads", 0).toInt();
72 settings.endGroup();
73
74 applyMaxThreadCount();
75 }
76
77
82 delete m_fileList;
83 delete m_scene;
84 delete m_worldScene;
85 delete m_imageReader;
86 }
87
88
93 QList<QAction *> exportActions = m_scene->getExportActions();
94
95 foreach (QAction * exportAct, exportActions) {
96 fileMenu.addAction(exportAct);
97 }
98
99 exportActions = m_fileList->getExportActions();
100
101 foreach (QAction * exportAct, exportActions) {
102 fileMenu.addAction(exportAct);
103 }
104 }
105
106
110 QProgressBar *MosaicController::getProgress() {
111 return m_imageReader->progress();
112 }
113
114
115 void MosaicController::saveProject(QString projFileName) {
116 Pvl projFile;
117
118 PvlObject imageProps("Images");
119
120 foreach (Image *image, m_images) {
121 imageProps += image->toPvl();
122 }
123
124 PvlObject qtInfoObject("QtInfo");
125 QDataStream stream;
126 PvlKeyword qtVersionKeyword("QtVersion", QString::number(stream.version()));
127 qtVersionKeyword.addCommentWrapped("See QDataStream Version for more info on QT version");
128 qtInfoObject += qtVersionKeyword;
129 projFile += qtInfoObject;
130 projFile += imageProps;
131 projFile += m_fileList->toPvl();
132 projFile += m_scene->toPvl();
133
134 projFile.write(projFileName);
135 }
136
137
138 QList<QAction *> MosaicController::getSettingsActions() {
139 QList<QAction *> settingsActs;
140
141 settingsActs.append(m_imageReader->actions(ImageDisplayProperties::FootprintViewProperties));
142 settingsActs.append(m_fileList->actions());
143
144 QAction *setThreads = new QAction("Set &Thread Limit", this);
145 connect(setThreads, SIGNAL(triggered(bool)),
146 this, SLOT(changeMaxThreads()));
147 settingsActs.append(setThreads);
148
149 return settingsActs;
150 }
151
152
153 void MosaicController::saveSettings(QSettings &settings) {
154 settings.beginGroup("MosaicController");
155 settings.setValue("maxThreads", m_maxThreads);
156 settings.endGroup();
157 }
158
159
165 m_imageReader->read(cubeNames);
166 }
167
168
169 void MosaicController::openProjectImages(PvlObject projectImages) {
170 m_imageReader->read(projectImages);
171 }
172
173
174 void MosaicController::imagesReady(ImageList images) {
175 m_images.append(images);
176
177 foreach (Image *image, images) {
178 connect(image, SIGNAL(destroyed(QObject *)),
179 this, SLOT(imageClosed(QObject *)));
180 }
181
182 // We really can't have all of the cubes in memory before
183 // the OS stops letting us open more files.
184 // Assume cameras are being used in other parts of code since it's
185 // unknown
186 QMutexLocker lock(m_mutex);
187 emit imagesAdded(images);
188 emit imagesAdded(&images);
189
190 Image *openImage;
191 foreach (openImage, images) {
192 openImage->closeCube();
193 }
194 }
195
196
197 void MosaicController::changeMaxThreads() {
198 bool ok = false;
199
200 QStringList options;
201
202 int current = 0;
203 options << tr("Use all available");
204
205 for(int i = 1; i < 24; i++) {
206 QString option = tr("Use %1 threads").arg(i + 1);
207
208 options << option;
209 if(m_maxThreads == i + 1)
210 current = i;
211 }
212
213 QString res = QInputDialog::getItem(NULL, tr("Concurrency"),
214 tr("Set the number of threads to use"),
215 options, current, false, &ok);
216
217 if (ok) {
218 m_maxThreads = options.indexOf(res) + 1;
219
220 applyMaxThreadCount();
221 }
222 }
223
224
229 Image *image = (Image *)imageObj;
230
231 if (image) {
232 ImageList::iterator foundElement;
233 foundElement = std::find(m_images.begin(), m_images.end(), image);
234 m_images.erase(foundElement);
235
236 if(m_images.empty())
237 emit allImagesClosed();
238 }
239 }
240
241
242 void MosaicController::readProject(QString filename) {
243 try {
244 Pvl projectPvl(filename);
245
246 // Convert versions <= isis3.4.1 to newer
247 if (projectPvl.hasObject("Cubes")) {
248 convertV1ToV2(projectPvl);
249 }
250
251 PvlKeyword qtVersionKeyword;
252 if (projectPvl.hasObject("QtInfo")) {
253 PvlObject &qtInfoObject = projectPvl.findObject("QtInfo");
254 qtVersionKeyword = qtInfoObject["QtVersion"];
255 }
256 else {
257 qtVersionKeyword = PvlKeyword("QtVersion", QString::number(QDataStream::Qt_5_15));
258 }
259
260 PvlObject &projImages(projectPvl.findObject("Images"));
261
262 if (projectPvl.hasObject("MosaicScene")) {
263 PvlObject &mosaicScene = projectPvl.findObject("MosaicScene");
264 mosaicScene += qtVersionKeyword;
265 m_scene->fromPvl(mosaicScene);
266 }
267
268 if (projectPvl.hasObject("ImageFileList"))
269 m_fileList->fromPvl(projectPvl.findObject("ImageFileList"));
270
271 m_imageReader->setQtVersion(int(qtVersionKeyword));
272 openProjectImages(projImages);
273 }
274 catch(IException &e) {
275 throw IException(e, IException::Unknown,
276 "Input file is not a valid qmos project", _FILEINFO_);
277 }
278 }
279
280
281 void MosaicController::saveList() {
282 QString output =
283 QFileDialog::getSaveFileName((QWidget *)parent(),
284 "Choose output file",
285 QDir::currentPath() + "/files.lis",
286 QString("List File (*.lis);;Text File (*.txt);;All Files (*.*)"));
287 if(output.isEmpty()) return;
288
289 TextFile file(output, "output");
290
291 Image *image;
292 foreach (image, m_images) {
293 file.PutLine( image->fileName() );
294 }
295 }
296
297
298 void MosaicController::applyMaxThreadCount() {
299 if (m_maxThreads <= 1) {
300 QThreadPool::globalInstance()->setMaxThreadCount(QThread::idealThreadCount());
301 }
302 else {
303 QThreadPool::globalInstance()->setMaxThreadCount(m_maxThreads - 1);
304 }
305 }
306
307
318 PvlObject &images = project.findObject("Cubes");
319
320 images.setName("Images");
321
322 QMap<QString, QString> imageFileToNewId;
323
324 for (int imgObjIndex = 0; imgObjIndex < images.objects(); imgObjIndex++) {
325 PvlObject &image = images.object(imgObjIndex);
326 image.setName("Image");
327
328
329 QBuffer idDataBuffer;
330 idDataBuffer.open(QIODevice::ReadWrite);
331
332 QDataStream idStream(&idDataBuffer);
333
334 QUuid newId = QUuid::createUuid();
335 QString fileName = image["FileName"][0];
336 idStream << newId;
337
338 idDataBuffer.seek(0);
339
340 QString idHex;
341 image += PvlKeyword("ID", QString(idDataBuffer.data().toHex()));
342
343 PvlKeyword oldDisplayPropsValues = image["Values"];
344 image.deleteKeyword("Values");
345
346 PvlObject displayProps("DisplayProperties");
347 displayProps += PvlKeyword("DisplayName", FileName(fileName).name());
348
349 // Convert display properties over
350 enum OldDispProps {
351 OldDispPropColor,
352 OldDispPropUntransferred1, // Selected
353 OldDispPropShowDNs,
354 OldDispPropShowFill,
355 OldDispPropShowLabel,
356 OldDispPropShowOutline,
357 OldDispPropUntransferred2, // Zooming
358 OldDispPropUntransferred3 // ZOrdering
359 };
360
361 QMap<int, QVariant> oldProps;
362 QByteArray oldHexValues(oldDisplayPropsValues[0].toLatin1());
363 QDataStream oldValuesStream(QByteArray::fromHex(oldHexValues));
364 oldValuesStream >> oldProps;
365
366 enum V2DispProps {
367 V2DispPropColor = 1,
368 V2DispPropShowDNs = 4,
369 V2DispPropShowFill = 8,
370 V2DispPropShowLabel = 16,
371 V2DispPropShowOutline = 32
372 };
373
374 QMap<int, QVariant> newProps;
375 newProps[V2DispPropColor] = oldProps[OldDispPropColor];
376 newProps[V2DispPropShowDNs] = oldProps[OldDispPropShowDNs];
377 newProps[V2DispPropShowFill] = oldProps[OldDispPropShowFill];
378 newProps[V2DispPropShowLabel] = oldProps[OldDispPropShowLabel];
379 newProps[V2DispPropShowOutline] = oldProps[OldDispPropShowOutline];
380
381 QBuffer newPropsDataBuffer;
382 newPropsDataBuffer.open(QIODevice::ReadWrite);
383
384 QDataStream newPropsStream(&newPropsDataBuffer);
385 newPropsStream << newProps;
386 newPropsDataBuffer.seek(0);
387
388 displayProps += PvlKeyword("Values", newPropsDataBuffer.data().toHex().data());
389 // Finished converting display properties from V1->V2
390
391
392 image += displayProps;
393
394 imageFileToNewId[fileName] = newId.toString().replace(QRegularExpression("[{}]"), "");
395 }
396
397 PvlObject &fileListOpts = project.findObject("MosaicFileList");
398 fileListOpts.setName("ImageFileList");
399
400 for (int fileListIndex = 0; fileListIndex < fileListOpts.objects(); fileListIndex++) {
401 PvlObject &fileListOrderObj = fileListOpts.object(fileListIndex);
402
403 for (int i = 0; i < fileListOrderObj.keywords(); i++) {
404 PvlKeyword &key = fileListOrderObj[i];
405
406 if (key.isNamed("Cube")) {
407 key.setName("Image");
408 key[0] = imageFileToNewId[key[0]];
409 }
410 }
411 }
412
413 PvlObject &sceneOpts = project.findObject("MosaicScene");
414
415 if (sceneOpts.hasObject("ZOrdering")) {
416 PvlObject &zOrdering = sceneOpts.findObject("ZOrdering");
417
418
419 for (int i = 0; i < zOrdering.keywords(); i++) {
420 PvlKeyword &key = zOrdering[i];
421
422 if (key.isNamed("ZValue")) {
423 key[0] = imageFileToNewId[key[0]];
424 }
425 }
426 }
427 }
428}
@ FootprintViewProperties
Every display property for footprint views, provided for convenience.
A colored, grouped cube list.
This represents a cube in a project-based GUI interface.
Definition Image.h:105
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:52
void append(Image *const &value)
Appends an image to the image list.
void convertV1ToV2(Pvl &project)
This converts qmos project files (no other project files existed) from their original version (file n...
MosaicController(QStatusBar *status, QSettings &settings)
MosaicWidget constructor.
void openImages(QStringList filenames)
Handle opening cubes by filename.
void addExportActions(QMenu &fileMenu)
Add actions that are export-related to the menu.
void imageClosed(QObject *image)
An open image is being deleted.
void imagesAdded(ImageList images)
Emitted when new images are available.
virtual ~MosaicController()
Free the allocated memory by this object.
This widget encompasses the entire mosaic scene.
Base class for Map Projections.
Definition Projection.h:154
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.
Definition Apollo.h:16