1
|
Index: src/app/qgisapp.h
|
2
|
===================================================================
|
3
|
--- src/app/qgisapp.h (revision 13817)
|
4
|
+++ src/app/qgisapp.h (working copy)
|
5
|
@@ -753,10 +753,10 @@
|
6
|
void composerWillBeRemoved( QgsComposerView* v );
|
7
|
|
8
|
private:
|
9
|
- /** This method will open a dialog so the user can select the sublayers
|
10
|
- * to load
|
11
|
+ /** This method will open a dialog so the user can select the sublayers to load
|
12
|
*/
|
13
|
- void askUserForSublayers( QgsVectorLayer *layer );
|
14
|
+ void askUserForOGRSublayers( QgsVectorLayer *layer );
|
15
|
+ void askUserForGDALSublayers( QgsRasterLayer *layer );
|
16
|
/** Add a raster layer to the map (passed in as a ptr).
|
17
|
* It won't force a refresh.
|
18
|
*/
|
19
|
Index: src/app/qgisapp.cpp
|
20
|
===================================================================
|
21
|
--- src/app/qgisapp.cpp (revision 13817)
|
22
|
+++ src/app/qgisapp.cpp (working copy)
|
23
|
@@ -2620,7 +2620,7 @@
|
24
|
// sublayers selection dialog so the user can select the sublayers to actually load.
|
25
|
if ( sublayers.count() > 1 )
|
26
|
{
|
27
|
- askUserForSublayers( layer );
|
28
|
+ askUserForOGRSublayers( layer );
|
29
|
|
30
|
// The first layer loaded is not useful in that case. The user can select it in
|
31
|
// the list if he wants to load it.
|
32
|
@@ -2673,18 +2673,49 @@
|
33
|
return true;
|
34
|
} // QgisApp::addVectorLayer()
|
35
|
|
36
|
+void QgisApp::askUserForGDALSublayers( QgsRasterLayer *layer )
|
37
|
+{
|
38
|
+ if ( !layer )
|
39
|
+ return;
|
40
|
+
|
41
|
+ QStringList sublayers = layer->subLayers();
|
42
|
+
|
43
|
+ QgsDebugMsg( "sublayers:\n " + sublayers.join( " \n" ) + "\n" );
|
44
|
+
|
45
|
+ // We initialize a selection dialog and display it.
|
46
|
+ QgsOGRSublayersDialog chooseSublayersDialog( this );
|
47
|
+ chooseSublayersDialog.setWindowTitle( tr( "Select raster layers to add..." ) );
|
48
|
+
|
49
|
+ QStringList layers;
|
50
|
+ for ( int i = 0; i < sublayers.size(); i++ )
|
51
|
+ {
|
52
|
+ layers << QString( "%1|%2|1|%3" ).arg( i ).arg( sublayers[i] ).arg( tr( "Raster" ) );
|
53
|
+ }
|
54
|
+
|
55
|
+ chooseSublayersDialog.populateLayerTable( layers, "|" );
|
56
|
+
|
57
|
+ if ( chooseSublayersDialog.exec() )
|
58
|
+ {
|
59
|
+ foreach( QString layer, chooseSublayersDialog.getSelection() )
|
60
|
+ {
|
61
|
+ QgsRasterLayer *rlayer = new QgsRasterLayer( layer, layer );
|
62
|
+ if ( rlayer && rlayer->isValid() )
|
63
|
+ {
|
64
|
+ addRasterLayer( rlayer );
|
65
|
+ }
|
66
|
+ }
|
67
|
+ }
|
68
|
+}
|
69
|
+
|
70
|
// This method is the method that does the real job. If the layer given in
|
71
|
// parameter is NULL, then the method tries to act on the activeLayer.
|
72
|
-void QgisApp::askUserForSublayers( QgsVectorLayer *layer )
|
73
|
+void QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
|
74
|
{
|
75
|
if ( layer == NULL )
|
76
|
{
|
77
|
- if ( activeLayer() == NULL || activeLayer()->type() != QgsMapLayer::VectorLayer )
|
78
|
+ layer = qobject_cast<QgsVectorLayer *>( activeLayer() );
|
79
|
+ if ( !layer || layer->dataProvider()->name() != "ogr" )
|
80
|
return;
|
81
|
-
|
82
|
- layer = ( QgsVectorLayer* ) activeLayer();
|
83
|
- if ( layer->dataProvider()->name() != "ogr" )
|
84
|
- return;
|
85
|
}
|
86
|
|
87
|
QStringList sublayers = layer->dataProvider()->subLayers();
|
88
|
@@ -2692,6 +2723,7 @@
|
89
|
|
90
|
// We initialize a selection dialog and display it.
|
91
|
QgsOGRSublayersDialog chooseSublayersDialog( this );
|
92
|
+ chooseSublayersDialog.setWindowTitle( tr( "Select vector layers to add..." ) );
|
93
|
chooseSublayersDialog.populateLayerTable( sublayers );
|
94
|
|
95
|
if ( chooseSublayersDialog.exec() )
|
96
|
@@ -6332,16 +6364,28 @@
|
97
|
|
98
|
// create the layer
|
99
|
QgsRasterLayer *layer = new QgsRasterLayer( *myIterator, myBaseNameQString );
|
100
|
+ QStringList sublayers = layer->subLayers();
|
101
|
|
102
|
- addRasterLayer( layer );
|
103
|
+ if ( sublayers.size() > 0 )
|
104
|
+ {
|
105
|
+ askUserForGDALSublayers( layer );
|
106
|
|
107
|
- //only allow one copy of a ai grid file to be loaded at a
|
108
|
- //time to prevent the user selecting all adfs in 1 dir which
|
109
|
- //actually represent 1 coverate,
|
110
|
+ // The first layer loaded is not useful in that case. The user can select it in
|
111
|
+ // the list if he wants to load it.
|
112
|
+ delete layer;
|
113
|
+ }
|
114
|
+ else
|
115
|
+ {
|
116
|
+ addRasterLayer( layer );
|
117
|
|
118
|
- if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
|
119
|
- {
|
120
|
- break;
|
121
|
+ //only allow one copy of a ai grid file to be loaded at a
|
122
|
+ //time to prevent the user selecting all adfs in 1 dir which
|
123
|
+ //actually represent 1 coverate,
|
124
|
+
|
125
|
+ if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
|
126
|
+ {
|
127
|
+ break;
|
128
|
+ }
|
129
|
}
|
130
|
}
|
131
|
else
|
132
|
Index: src/app/ogr/qgsogrsublayersdialog.h
|
133
|
===================================================================
|
134
|
--- src/app/ogr/qgsogrsublayersdialog.h (revision 13817)
|
135
|
+++ src/app/ogr/qgsogrsublayersdialog.h (working copy)
|
136
|
@@ -19,18 +19,19 @@
|
137
|
|
138
|
#include <QDialog>
|
139
|
#include <ui_qgsogrsublayersdialogbase.h>
|
140
|
+#include "qgscontexthelp.h"
|
141
|
|
142
|
-
|
143
|
-
|
144
|
class QgsOGRSublayersDialog : public QDialog, private Ui::QgsOGRSublayersDialogBase
|
145
|
{
|
146
|
Q_OBJECT
|
147
|
public:
|
148
|
QgsOGRSublayersDialog( QWidget* parent = 0, Qt::WFlags fl = 0 );
|
149
|
~QgsOGRSublayersDialog();
|
150
|
- void populateLayerTable( QStringList theList );
|
151
|
+ void populateLayerTable( QStringList theList, QString delim = ":" );
|
152
|
QStringList getSelection();
|
153
|
|
154
|
+ public slots:
|
155
|
+ void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
|
156
|
};
|
157
|
|
158
|
#endif
|
159
|
Index: src/app/ogr/qgsogrsublayersdialog.cpp
|
160
|
===================================================================
|
161
|
--- src/app/ogr/qgsogrsublayersdialog.cpp (revision 13817)
|
162
|
+++ src/app/ogr/qgsogrsublayersdialog.cpp (working copy)
|
163
|
@@ -42,14 +42,14 @@
|
164
|
return list;
|
165
|
}
|
166
|
|
167
|
-void QgsOGRSublayersDialog::populateLayerTable( QStringList theList )
|
168
|
+void QgsOGRSublayersDialog::populateLayerTable( QStringList theList, QString delim )
|
169
|
{
|
170
|
for ( int i = 0; i < theList.size(); i++ )
|
171
|
{
|
172
|
- QString ligne = theList.at( i );
|
173
|
- QStringList elements = ligne.split( ":" );
|
174
|
+ QString line = theList.at( i );
|
175
|
+ QStringList elements = line.split( delim );
|
176
|
QStringList item = QStringList();
|
177
|
item << elements.at( 0 ) << elements.at( 1 ) << elements.at( 2 ) << elements.at( 3 );
|
178
|
- layersTable -> addTopLevelItem( new QTreeWidgetItem( item ) );
|
179
|
+ layersTable->addTopLevelItem( new QTreeWidgetItem( item ) );
|
180
|
}
|
181
|
}
|
182
|
Index: src/core/raster/qgsrasterlayer.cpp
|
183
|
===================================================================
|
184
|
--- src/core/raster/qgsrasterlayer.cpp (revision 13817)
|
185
|
+++ src/core/raster/qgsrasterlayer.cpp (working copy)
|
186
|
@@ -444,10 +444,8 @@
|
187
|
/**
|
188
|
* This helper checks to see whether the file name appears to be a valid raster file name
|
189
|
*/
|
190
|
-bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString,
|
191
|
- QString & retErrMsg )
|
192
|
+bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
|
193
|
{
|
194
|
-
|
195
|
GDALDatasetH myDataset;
|
196
|
registerGdalDrivers();
|
197
|
|
198
|
@@ -463,10 +461,15 @@
|
199
|
}
|
200
|
else if ( GDALGetRasterCount( myDataset ) == 0 )
|
201
|
{
|
202
|
- GDALClose( myDataset );
|
203
|
- myDataset = NULL;
|
204
|
- retErrMsg = "This raster file has no bands and is invalid as a raster layer.";
|
205
|
- return false;
|
206
|
+ QStringList layers = subLayers( myDataset );
|
207
|
+ if ( layers.size() == 0 )
|
208
|
+ {
|
209
|
+ GDALClose( myDataset );
|
210
|
+ myDataset = NULL;
|
211
|
+ retErrMsg = tr( "This raster file has no bands and is invalid as a raster layer." );
|
212
|
+ return false;
|
213
|
+ }
|
214
|
+ return true;
|
215
|
}
|
216
|
else
|
217
|
{
|
218
|
@@ -476,10 +479,8 @@
|
219
|
}
|
220
|
|
221
|
bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString )
|
222
|
-
|
223
|
{
|
224
|
QString retErrMsg;
|
225
|
-
|
226
|
return isValidRasterFileName( theFileNameQString, retErrMsg );
|
227
|
}
|
228
|
|
229
|
@@ -2610,7 +2611,7 @@
|
230
|
}
|
231
|
else
|
232
|
{
|
233
|
- QgsDebugMsg( "band " + QString::number( i ) + "has no metadata" );
|
234
|
+ QgsDebugMsg( "band " + QString::number( i ) + " has no metadata" );
|
235
|
}
|
236
|
|
237
|
char ** GDALcategories = GDALGetRasterCategoryNames( gdalBand );
|
238
|
@@ -3565,18 +3566,40 @@
|
239
|
emit statusChanged( theMessage );
|
240
|
}
|
241
|
|
242
|
+QStringList QgsRasterLayer::subLayers( GDALDatasetH dataset )
|
243
|
+{
|
244
|
+ QStringList subLayers;
|
245
|
+
|
246
|
+ char **metadata = GDALGetMetadata( dataset, "SUBDATASETS" );
|
247
|
+ if ( metadata )
|
248
|
+ {
|
249
|
+ for ( int i = 0; metadata[i] != NULL; i++ )
|
250
|
+ {
|
251
|
+ QString layer = QString::fromUtf8( metadata[i] );
|
252
|
+
|
253
|
+ int pos = layer.indexOf( "_NAME=" );
|
254
|
+ if ( pos >= 0 )
|
255
|
+ {
|
256
|
+ subLayers << layer.mid( pos + 6 );
|
257
|
+ }
|
258
|
+ }
|
259
|
+ }
|
260
|
+
|
261
|
+ QgsDebugMsg( "sublayers:\n " + subLayers.join( "\n " ) );
|
262
|
+
|
263
|
+ return subLayers;
|
264
|
+}
|
265
|
+
|
266
|
QStringList QgsRasterLayer::subLayers() const
|
267
|
{
|
268
|
-
|
269
|
if ( mDataProvider )
|
270
|
{
|
271
|
return mDataProvider->subLayers();
|
272
|
}
|
273
|
else
|
274
|
{
|
275
|
- return QStringList(); // Empty
|
276
|
+ return subLayers( mGdalDataset );
|
277
|
}
|
278
|
-
|
279
|
}
|
280
|
|
281
|
void QgsRasterLayer::thumbnailAsPixmap( QPixmap * theQPixmap )
|
282
|
@@ -5219,6 +5242,13 @@
|
283
|
GDALReferenceDataset( mGdalDataset );
|
284
|
}
|
285
|
|
286
|
+ if ( subLayers().size() > 0 )
|
287
|
+ {
|
288
|
+ // just to get the sublayers
|
289
|
+ mValid = false;
|
290
|
+ return true;
|
291
|
+ }
|
292
|
+
|
293
|
//check f this file has pyramids
|
294
|
GDALRasterBandH myGDALBand = GDALGetRasterBand( mGdalDataset, 1 ); //just use the first band
|
295
|
if ( myGDALBand == NULL )
|
296
|
@@ -5231,15 +5261,9 @@
|
297
|
mValid = false;
|
298
|
return false;
|
299
|
}
|
300
|
- if ( GDALGetOverviewCount( myGDALBand ) > 0 )
|
301
|
- {
|
302
|
- mHasPyramids = true;
|
303
|
- }
|
304
|
- else
|
305
|
- {
|
306
|
- mHasPyramids = false;
|
307
|
- }
|
308
|
|
309
|
+ mHasPyramids = GDALGetOverviewCount( myGDALBand ) > 0;
|
310
|
+
|
311
|
//populate the list of what pyramids exist
|
312
|
buildPyramidList();
|
313
|
|
314
|
Index: src/core/raster/qgsrasterlayer.h
|
315
|
===================================================================
|
316
|
--- src/core/raster/qgsrasterlayer.h (revision 13817)
|
317
|
+++ src/core/raster/qgsrasterlayer.h (working copy)
|
318
|
@@ -284,9 +284,10 @@
|
319
|
* returned in retError.
|
320
|
*/
|
321
|
static bool isValidRasterFileName( const QString & theFileNameQString, QString &retError );
|
322
|
-
|
323
|
static bool isValidRasterFileName( const QString & theFileNameQString );
|
324
|
+ static QStringList subLayers( GDALDatasetH dataset );
|
325
|
|
326
|
+
|
327
|
/** Return time stamp for given file name */
|
328
|
static QDateTime lastModified( const QString & name );
|
329
|
|
330
|
Index: src/ui/qgsogrsublayersdialogbase.ui
|
331
|
===================================================================
|
332
|
--- src/ui/qgsogrsublayersdialogbase.ui (revision 13817)
|
333
|
+++ src/ui/qgsogrsublayersdialogbase.ui (working copy)
|
334
|
@@ -1,103 +1,45 @@
|
335
|
-<ui version="4.0" >
|
336
|
+<?xml version="1.0" encoding="UTF-8"?>
|
337
|
+<ui version="4.0">
|
338
|
<class>QgsOGRSublayersDialogBase</class>
|
339
|
- <widget class="QDialog" name="QgsOGRSublayersDialogBase" >
|
340
|
- <property name="geometry" >
|
341
|
+ <widget class="QDialog" name="QgsOGRSublayersDialogBase">
|
342
|
+ <property name="geometry">
|
343
|
<rect>
|
344
|
<x>0</x>
|
345
|
<y>0</y>
|
346
|
<width>584</width>
|
347
|
- <height>535</height>
|
348
|
+ <height>236</height>
|
349
|
</rect>
|
350
|
</property>
|
351
|
- <property name="windowTitle" >
|
352
|
- <string>Select OGR layers to load</string>
|
353
|
+ <property name="windowTitle">
|
354
|
+ <string>Select layers to load</string>
|
355
|
</property>
|
356
|
- <property name="windowIcon" >
|
357
|
- <iconset>../../../qgis_1.0.0/src/plugins/ogrsublayers</iconset>
|
358
|
- </property>
|
359
|
- <layout class="QGridLayout" >
|
360
|
- <property name="leftMargin" >
|
361
|
+ <layout class="QGridLayout">
|
362
|
+ <property name="margin">
|
363
|
<number>9</number>
|
364
|
</property>
|
365
|
- <property name="topMargin" >
|
366
|
- <number>9</number>
|
367
|
- </property>
|
368
|
- <property name="rightMargin" >
|
369
|
- <number>9</number>
|
370
|
- </property>
|
371
|
- <property name="bottomMargin" >
|
372
|
- <number>9</number>
|
373
|
- </property>
|
374
|
- <property name="horizontalSpacing" >
|
375
|
+ <property name="spacing">
|
376
|
<number>6</number>
|
377
|
</property>
|
378
|
- <property name="verticalSpacing" >
|
379
|
- <number>6</number>
|
380
|
- </property>
|
381
|
- <item row="0" column="0" >
|
382
|
- <widget class="QLabel" name="txtHeading" >
|
383
|
- <property name="sizePolicy" >
|
384
|
- <sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
|
385
|
- <horstretch>0</horstretch>
|
386
|
- <verstretch>0</verstretch>
|
387
|
- </sizepolicy>
|
388
|
- </property>
|
389
|
- <property name="font" >
|
390
|
- <font>
|
391
|
- <family>Sans Serif</family>
|
392
|
- <pointsize>24</pointsize>
|
393
|
- <weight>75</weight>
|
394
|
- <italic>false</italic>
|
395
|
- <bold>true</bold>
|
396
|
- <underline>false</underline>
|
397
|
- <strikeout>false</strikeout>
|
398
|
- </font>
|
399
|
- </property>
|
400
|
- <property name="text" >
|
401
|
- <string>Sub layers list</string>
|
402
|
- </property>
|
403
|
- <property name="alignment" >
|
404
|
- <set>Qt::AlignCenter</set>
|
405
|
- </property>
|
406
|
- </widget>
|
407
|
- </item>
|
408
|
- <item row="8" column="0" >
|
409
|
- <widget class="QDialogButtonBox" name="buttonBox" >
|
410
|
- <property name="orientation" >
|
411
|
+ <item row="6" column="0">
|
412
|
+ <widget class="QDialogButtonBox" name="buttonBox">
|
413
|
+ <property name="orientation">
|
414
|
<enum>Qt::Horizontal</enum>
|
415
|
</property>
|
416
|
- <property name="standardButtons" >
|
417
|
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
418
|
+ <property name="standardButtons">
|
419
|
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
|
420
|
</property>
|
421
|
</widget>
|
422
|
</item>
|
423
|
- <item row="1" column="0" >
|
424
|
- <widget class="QTextEdit" name="textEdit" >
|
425
|
- <property name="html" >
|
426
|
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
427
|
-p, li { white-space: pre-wrap; }
|
428
|
-</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
429
|
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';">This is the list of all layers available in the datasource of the active layer. You can select the layers to load. The layers will be loaded when you press "OK".</p>
|
430
|
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"></p>
|
431
|
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';">The layer name is format dependent. Consult the OGR documentation or the documentation of your data format to determine the nature of the included information.</p>
|
432
|
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"></p>
|
433
|
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><span style=" font-weight:600;">Be advised: </span>selecting an already opened layer will not generate an error message and the layer will end up loaded twice!</p></body></html></string>
|
434
|
- </property>
|
435
|
- </widget>
|
436
|
- </item>
|
437
|
- <item row="2" column="0" >
|
438
|
- <widget class="QTreeWidget" name="layersTable" >
|
439
|
- <property name="windowModality" >
|
440
|
- <enum>Qt::NonModal</enum>
|
441
|
- </property>
|
442
|
- <property name="selectionMode" >
|
443
|
+ <item row="0" column="0">
|
444
|
+ <widget class="QTreeWidget" name="layersTable">
|
445
|
+ <property name="selectionMode">
|
446
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
447
|
</property>
|
448
|
- <property name="selectionBehavior" >
|
449
|
+ <property name="selectionBehavior">
|
450
|
<enum>QAbstractItemView::SelectRows</enum>
|
451
|
</property>
|
452
|
<column>
|
453
|
- <property name="text" >
|
454
|
+ <property name="text">
|
455
|
<string>1</string>
|
456
|
</property>
|
457
|
</column>
|
458
|
@@ -105,7 +47,7 @@
|
459
|
</item>
|
460
|
</layout>
|
461
|
</widget>
|
462
|
- <layoutdefault spacing="6" margin="11" />
|
463
|
+ <layoutdefault spacing="6" margin="11"/>
|
464
|
<resources/>
|
465
|
<connections>
|
466
|
<connection>
|
467
|
@@ -114,11 +56,11 @@
|
468
|
<receiver>QgsOGRSublayersDialogBase</receiver>
|
469
|
<slot>accept()</slot>
|
470
|
<hints>
|
471
|
- <hint type="sourcelabel" >
|
472
|
+ <hint type="sourcelabel">
|
473
|
<x>446</x>
|
474
|
<y>508</y>
|
475
|
</hint>
|
476
|
- <hint type="destinationlabel" >
|
477
|
+ <hint type="destinationlabel">
|
478
|
<x>351</x>
|
479
|
<y>473</y>
|
480
|
</hint>
|
481
|
@@ -130,11 +72,11 @@
|
482
|
<receiver>QgsOGRSublayersDialogBase</receiver>
|
483
|
<slot>reject()</slot>
|
484
|
<hints>
|
485
|
- <hint type="sourcelabel" >
|
486
|
+ <hint type="sourcelabel">
|
487
|
<x>541</x>
|
488
|
<y>507</y>
|
489
|
</hint>
|
490
|
- <hint type="destinationlabel" >
|
491
|
+ <hint type="destinationlabel">
|
492
|
<x>503</x>
|
493
|
<y>434</y>
|
494
|
</hint>
|