16
16
#include " sqlite3.h"
17
17
18
18
#include " qgsgeopackagedataitems.h"
19
- #include " qgsgeopackageconnection .h"
19
+ #include " qgsogrdbconnection .h"
20
20
#include " qgslogger.h"
21
21
#include " qgssettings.h"
22
22
#include " qgsproject.h"
23
23
#include " qgsvectorlayer.h"
24
24
#include " qgsrasterlayer.h"
25
25
#include " qgsogrprovider.h"
26
+ #include " qgsogrdataitems.h"
26
27
#include " qgsnewgeopackagelayerdialog.h"
27
28
#include " qgsmessageoutput.h"
28
29
#include " qgsvectorlayerexporter.h"
29
30
#include " qgsgeopackagerasterwritertask.h"
30
- #include " gdal.h"
31
31
32
32
#include < QAction>
33
33
#include < QMessageBox>
@@ -62,10 +62,10 @@ QgsGeoPackageRootItem::~QgsGeoPackageRootItem()
62
62
QVector<QgsDataItem *> QgsGeoPackageRootItem::createChildren ()
63
63
{
64
64
QVector<QgsDataItem *> connections;
65
-
66
- Q_FOREACH ( const QString &connName, QgsGeoPackageConnection::connectionList () )
65
+ const QStringList connList ( QgsOgrDbConnection::connectionList ( QStringLiteral ( " GPKG " ) ) );
66
+ for ( const QString &connName : connList )
67
67
{
68
- QgsGeoPackageConnection connection ( connName );
68
+ QgsOgrDbConnection connection ( connName, QStringLiteral ( " GPKG " ) );
69
69
QgsDataItem *conn = new QgsGeoPackageConnectionItem ( this , connection.name (), connection.uri ().encodedUri () );
70
70
71
71
connections.append ( conn );
@@ -102,9 +102,10 @@ void QgsGeoPackageRootItem::connectionsChanged()
102
102
103
103
void QgsGeoPackageRootItem::newConnection ()
104
104
{
105
- // TODO use QgsFileWidget
106
- QString path = QFileDialog::getOpenFileName ( nullptr , tr ( " Open GeoPackage" ), " " , tr ( " GeoPackage Database (*.gpkg)" ) );
107
- storeConnection ( path );
105
+ if ( QgsOgrDataCollectionItem::createConnection ( QStringLiteral ( " GeoPackage" ), QStringLiteral ( " GeoPackage Database (*.gpkg)" ), QStringLiteral ( " GPKG" ) ) )
106
+ {
107
+ refreshConnections ();
108
+ }
108
109
}
109
110
110
111
@@ -115,36 +116,13 @@ void QgsGeoPackageRootItem::createDatabase()
115
116
dialog.setCrs ( QgsProject::instance ()->defaultCrsForNewLayers () );
116
117
if ( dialog.exec () == QDialog::Accepted )
117
118
{
118
- storeConnection ( dialog.databasePath () );
119
- }
120
- }
121
- #endif
122
-
123
- bool QgsGeoPackageRootItem::storeConnection ( const QString &path )
124
- {
125
- QFileInfo fileInfo ( path );
126
- QString connName = fileInfo.fileName ();
127
- if ( ! path.isEmpty () )
128
- {
129
- bool ok = true ;
130
- while ( ok && ! QgsGeoPackageConnection ( connName ).path ( ).isEmpty ( ) )
119
+ if ( QgsOgrDataCollectionItem::storeConnection ( dialog.databasePath (), QStringLiteral ( " GPKG" ) ) )
131
120
{
132
-
133
- connName = QInputDialog::getText ( nullptr , tr ( " Cannot add connection '%1'" ).arg ( connName ),
134
- tr ( " A connection with the same name already exists,\n please provide a new name:" ), QLineEdit::Normal,
135
- QLatin1String ( " " ), &ok );
136
- }
137
- if ( ok && ! connName.isEmpty () )
138
- {
139
- QgsGeoPackageConnection connection ( connName );
140
- connection.setPath ( path );
141
- connection.save ();
142
121
refreshConnections ();
143
- return true ;
144
122
}
145
123
}
146
- return false ;
147
124
}
125
+ #endif
148
126
149
127
150
128
QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem ( QgsDataItem *parent, QString name, QString path )
@@ -154,144 +132,21 @@ QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, Q
154
132
mCapabilities |= Collapse;
155
133
}
156
134
157
- QList<QgsGeoPackageLayerInfo *> QgsGeoPackageConnectionItem::subLayers ( const QString &path ) const
158
- {
159
135
160
- QList<QgsGeoPackageLayerInfo *> children;
161
-
162
- // Vector layers
163
- QgsVectorLayer layer ( mPath , QStringLiteral ( " ogr_tmp" ), QStringLiteral ( " ogr" ) );
164
- if ( ! layer.isValid ( ) )
165
- {
166
- QgsDebugMsgLevel ( tr ( " Layer is not a valid GeoPackage Vector layer %1" ).arg ( mPath ), 3 );
167
- }
168
- else
169
- {
170
- // Collect mixed-geom layers
171
- QMultiMap<int , QStringList> subLayers;
172
- Q_FOREACH ( const QString &descriptor, layer.dataProvider ()->subLayers ( ) )
173
- {
174
- QStringList pieces = descriptor.split ( ' :' );
175
- subLayers.insert ( pieces[0 ].toInt (), pieces );
176
- }
177
- int prevIdx = -1 ;
178
- Q_FOREACH ( const int &idx, subLayers.keys ( ) )
179
- {
180
- if ( idx == prevIdx )
181
- {
182
- continue ;
183
- }
184
- prevIdx = idx;
185
- QList<QStringList> values = subLayers.values ( idx );
186
- for ( int i = 0 ; i < values.size (); ++i )
187
- {
188
- QStringList pieces = values.at ( i );
189
- QString layerId = pieces[0 ];
190
- QString name = pieces[1 ];
191
- // QString featuresCount = pieces[2]; // Not used
192
- QString geometryType = pieces[3 ];
193
- QgsLayerItem::LayerType layerType;
194
- layerType = layerTypeFromDb ( geometryType );
195
- // example URI for mixed-geoms geoms: '/path/gdal_sample_v1.2_no_extensions.gpkg|layerid=7|geometrytype=Point'
196
- // example URI for mixed-geoms attr table: '/path/gdal_sample_v1.2_no_extensions.gpkg|layername=MyLayer|layerid=7'
197
- // example URI for single geoms: '/path/gdal_sample_v1.2_no_extensions.gpkg|layerid=6'
198
- QString uri;
199
- // Check if it's a mixed geometry type
200
- if ( i == 0 && values.size () > 1 )
201
- {
202
- uri = QStringLiteral ( " %1|layerid=%2|layername=%3" ).arg ( mPath , layerId, name );
203
- children.append ( new QgsGeoPackageLayerInfo ( mPath , uri, name, QgsLayerItem::LayerType::TableLayer ) );
204
- }
205
- if ( layerType != QgsLayerItem::LayerType::NoType )
206
- {
207
- if ( geometryType.contains ( QStringLiteral ( " Collection" ), Qt::CaseInsensitive ) )
208
- {
209
- QgsDebugMsgLevel ( QStringLiteral ( " Layer %1 is a geometry collection: skipping %2" ).arg ( name, mPath ), 3 );
210
- }
211
- else
212
- {
213
- if ( values.size () > 1 )
214
- {
215
- uri = QStringLiteral ( " %1|layerid=%2|geometrytype=%3" ).arg ( mPath , layerId, geometryType );
216
- }
217
- else
218
- {
219
- uri = QStringLiteral ( " %1|layerid=%2" ).arg ( mPath , layerId );
220
- }
221
- QgsDebugMsgLevel ( QStringLiteral ( " Adding GeoPackage Vector item %1 %2 %3" ).arg ( name, uri, geometryType ), 3 );
222
- children.append ( new QgsGeoPackageLayerInfo ( mPath , uri, name, layerType ) );
223
- }
224
- }
225
- else
226
- {
227
- QgsDebugMsgLevel ( QStringLiteral ( " Layer type is not a supported GeoPackage Vector layer %1" ).arg ( mPath ), 3 );
228
- }
229
- QgsDebugMsgLevel ( QStringLiteral ( " Adding GeoPackage Vector item %1 %2 %3" ).arg ( name, uri, geometryType ), 3 );
230
- }
231
- }
232
- }
233
- // Raster layers
234
- QgsRasterLayer rlayer ( mPath , QStringLiteral ( " gdal_tmp" ), QStringLiteral ( " gdal" ), false );
235
- if ( rlayer.dataProvider ()->subLayers ( ).size () > 0 )
236
- {
237
- Q_FOREACH ( const QString &uri, rlayer.dataProvider ()->subLayers ( ) )
238
- {
239
- QStringList pieces = uri.split ( ' :' );
240
- QString name = pieces.value ( pieces.length () - 1 );
241
- QgsDebugMsgLevel ( QStringLiteral ( " Adding GeoPackage Raster item %1 %2 %3" ).arg ( name, uri ), 3 );
242
- children.append ( new QgsGeoPackageLayerInfo ( mPath , uri, name, QgsLayerItem::LayerType::Raster ) );
243
- }
244
- }
245
- else if ( rlayer.isValid ( ) )
246
- {
247
- // Get the identifier
248
- GDALAllRegister ();
249
- // do not print errors, but write to debug
250
- CPLPushErrorHandler ( CPLQuietErrorHandler );
251
- CPLErrorReset ();
252
- GDALDatasetH hDS = GDALOpen ( mPath .toUtf8 ().constData (), GA_ReadOnly );
253
- CPLPopErrorHandler ();
254
-
255
- if ( ! hDS )
256
- {
257
- QgsDebugMsg ( QString ( " GDALOpen error # %1 : %2 " ).arg ( CPLGetLastErrorNo () ).arg ( CPLGetLastErrorMsg () ) );
258
-
259
- }
260
- else
261
- {
262
- QString uri ( QStringLiteral ( " GPKG:%1" ).arg ( mPath ) );
263
- QString name = GDALGetMetadataItem ( hDS, " IDENTIFIER" , NULL );
264
- GDALClose ( hDS );
265
- // Fallback: will not be able to delete the table
266
- if ( name.isEmpty () )
267
- {
268
- name = QFileInfo ( mPath ).fileName ();
269
- }
270
- else
271
- {
272
- uri += QStringLiteral ( " :%1" ).arg ( name );
273
- }
274
-
275
- QgsDebugMsgLevel ( QStringLiteral ( " Adding GeoPackage Raster item %1 %2 %3" ).arg ( name, mPath ), 3 );
276
- children.append ( new QgsGeoPackageLayerInfo ( mPath , uri, name, QgsLayerItem::LayerType::Raster ) );
277
- }
278
- }
279
- return children;
280
- }
281
136
282
137
QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren ()
283
138
{
284
139
QVector<QgsDataItem *> children;
285
- QList<QgsGeoPackageLayerInfo *> layers = subLayers ( mPath );
286
- for ( const QgsGeoPackageLayerInfo *info : qgsAsConst ( layers ) )
140
+ QList<QgsOgrDbLayerInfo *> layers = QgsOgrLayerItem:: subLayers ( mPath , QStringLiteral ( " GPKG " ) );
141
+ for ( const QgsOgrDbLayerInfo *info : qgsAsConst ( layers ) )
287
142
{
288
- if ( info->type () == QgsLayerItem::LayerType::Raster )
143
+ if ( info->layerType () == QgsLayerItem::LayerType::Raster )
289
144
{
290
145
children.append ( new QgsGeoPackageRasterLayerItem ( this , info->name (), info->path (), info->uri () ) );
291
146
}
292
147
else
293
148
{
294
- children.append ( new QgsGeoPackageVectorLayerItem ( this , info->name (), info->path (), info->uri (), info->type ( ) ) );
149
+ children.append ( new QgsGeoPackageVectorLayerItem ( this , info->name (), info->path (), info->uri (), info->layerType ( ) ) );
295
150
}
296
151
}
297
152
qDeleteAll ( layers );
@@ -479,32 +334,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
479
334
}
480
335
481
336
482
- QgsLayerItem::LayerType QgsGeoPackageConnectionItem::layerTypeFromDb ( const QString &geometryType )
483
- {
484
- if ( geometryType.contains ( QStringLiteral ( " Point" ), Qt::CaseInsensitive ) )
485
- {
486
- return QgsLayerItem::LayerType::Point ;
487
- }
488
- else if ( geometryType.contains ( QStringLiteral ( " Polygon" ), Qt::CaseInsensitive ) )
489
- {
490
- return QgsLayerItem::LayerType::Polygon;
491
- }
492
- else if ( geometryType.contains ( QStringLiteral ( " LineString" ), Qt::CaseInsensitive ) )
493
- {
494
- return QgsLayerItem::LayerType::Line;
495
- }
496
- else if ( geometryType.contains ( QStringLiteral ( " Collection" ), Qt::CaseInsensitive ) )
497
- {
498
- return QgsLayerItem::LayerType::Vector;
499
- }
500
- // To be moved in a parent class that would also work for gdal and rasters
501
- else if ( geometryType.contains ( QStringLiteral ( " Raster" ), Qt::CaseInsensitive ) )
502
- {
503
- return QgsLayerItem::LayerType::Raster;
504
- }
505
- return QgsLayerItem::LayerType::TableLayer;
506
- }
507
-
508
337
bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer ( const QString uri, QString &errCause )
509
338
{
510
339
bool result = false ;
@@ -625,7 +454,7 @@ bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( const QString uri
625
454
626
455
void QgsGeoPackageConnectionItem::deleteConnection ()
627
456
{
628
- QgsGeoPackageConnection ::deleteConnection ( name () );
457
+ QgsOgrDbConnection ::deleteConnection ( name (), QStringLiteral ( " GeoPackage " ) );
629
458
mParent ->refreshConnections ();
630
459
}
631
460
@@ -635,7 +464,7 @@ void QgsGeoPackageConnectionItem::addTable()
635
464
QgsNewGeoPackageLayerDialog dialog ( nullptr );
636
465
QFileInfo fileInfo ( mPath );
637
466
QString connName = fileInfo.fileName ();
638
- QgsGeoPackageConnection connection ( connName );
467
+ QgsOgrDbConnection connection ( connName, QStringLiteral ( " GeoPackage " ) );
639
468
if ( ! connection.path ().isEmpty () )
640
469
{
641
470
dialog.setDatabasePath ( connection.path () );
0 commit comments