Skip to content

Commit 6e34681

Browse files
committed
Use the OGR generic methods
1 parent 1b72a0d commit 6e34681

File tree

2 files changed

+17
-218
lines changed

2 files changed

+17
-218
lines changed

src/providers/ogr/qgsgeopackagedataitems.cpp

+17-188
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616
#include "sqlite3.h"
1717

1818
#include "qgsgeopackagedataitems.h"
19-
#include "qgsgeopackageconnection.h"
19+
#include "qgsogrdbconnection.h"
2020
#include "qgslogger.h"
2121
#include "qgssettings.h"
2222
#include "qgsproject.h"
2323
#include "qgsvectorlayer.h"
2424
#include "qgsrasterlayer.h"
2525
#include "qgsogrprovider.h"
26+
#include "qgsogrdataitems.h"
2627
#include "qgsnewgeopackagelayerdialog.h"
2728
#include "qgsmessageoutput.h"
2829
#include "qgsvectorlayerexporter.h"
2930
#include "qgsgeopackagerasterwritertask.h"
30-
#include "gdal.h"
3131

3232
#include <QAction>
3333
#include <QMessageBox>
@@ -62,10 +62,10 @@ QgsGeoPackageRootItem::~QgsGeoPackageRootItem()
6262
QVector<QgsDataItem *> QgsGeoPackageRootItem::createChildren()
6363
{
6464
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 )
6767
{
68-
QgsGeoPackageConnection connection( connName );
68+
QgsOgrDbConnection connection( connName, QStringLiteral( "GPKG" ) );
6969
QgsDataItem *conn = new QgsGeoPackageConnectionItem( this, connection.name(), connection.uri().encodedUri() );
7070

7171
connections.append( conn );
@@ -102,9 +102,10 @@ void QgsGeoPackageRootItem::connectionsChanged()
102102

103103
void QgsGeoPackageRootItem::newConnection()
104104
{
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+
}
108109
}
109110

110111

@@ -115,36 +116,13 @@ void QgsGeoPackageRootItem::createDatabase()
115116
dialog.setCrs( QgsProject::instance()->defaultCrsForNewLayers() );
116117
if ( dialog.exec() == QDialog::Accepted )
117118
{
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" ) ) )
131120
{
132-
133-
connName = QInputDialog::getText( nullptr, tr( "Cannot add connection '%1'" ).arg( connName ),
134-
tr( "A connection with the same name already exists,\nplease 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();
142121
refreshConnections();
143-
return true;
144122
}
145123
}
146-
return false;
147124
}
125+
#endif
148126

149127

150128
QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, QString name, QString path )
@@ -154,144 +132,21 @@ QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, Q
154132
mCapabilities |= Collapse;
155133
}
156134

157-
QList<QgsGeoPackageLayerInfo *> QgsGeoPackageConnectionItem::subLayers( const QString &path ) const
158-
{
159135

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-
}
281136

282137
QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren()
283138
{
284139
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 ) )
287142
{
288-
if ( info->type() == QgsLayerItem::LayerType::Raster )
143+
if ( info->layerType() == QgsLayerItem::LayerType::Raster )
289144
{
290145
children.append( new QgsGeoPackageRasterLayerItem( this, info->name(), info->path(), info->uri() ) );
291146
}
292147
else
293148
{
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( ) ) );
295150
}
296151
}
297152
qDeleteAll( layers );
@@ -479,32 +334,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
479334
}
480335

481336

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-
508337
bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( const QString uri, QString &errCause )
509338
{
510339
bool result = false;
@@ -625,7 +454,7 @@ bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( const QString uri
625454

626455
void QgsGeoPackageConnectionItem::deleteConnection()
627456
{
628-
QgsGeoPackageConnection::deleteConnection( name() );
457+
QgsOgrDbConnection::deleteConnection( name(), QStringLiteral( "GeoPackage" ) );
629458
mParent->refreshConnections();
630459
}
631460

@@ -635,7 +464,7 @@ void QgsGeoPackageConnectionItem::addTable()
635464
QgsNewGeoPackageLayerDialog dialog( nullptr );
636465
QFileInfo fileInfo( mPath );
637466
QString connName = fileInfo.fileName();
638-
QgsGeoPackageConnection connection( connName );
467+
QgsOgrDbConnection connection( connName, QStringLiteral( "GeoPackage" ) );
639468
if ( ! connection.path().isEmpty() )
640469
{
641470
dialog.setDatabasePath( connection.path() );

src/providers/ogr/qgsgeopackagedataitems.h

-30
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,6 @@
2020
#include "qgsdataprovider.h"
2121

2222

23-
/**
24-
* Holds the information about a gpkg layer
25-
*/
26-
class QgsGeoPackageLayerInfo
27-
{
28-
public:
29-
QgsGeoPackageLayerInfo( const QString &path, const QString &uri, const QString &name, const QgsLayerItem::LayerType &type )
30-
: mPath( path )
31-
, mUri( uri )
32-
, mName( name )
33-
, mType( type )
34-
{
35-
}
36-
const QString path() const { return mPath; }
37-
const QString uri() const { return mUri; }
38-
const QString name() const { return mName; }
39-
QgsLayerItem::LayerType type() const { return mType; }
40-
private:
41-
QString mPath;
42-
QString mUri;
43-
QString mName;
44-
QgsLayerItem::LayerType mType = QgsLayerItem::LayerType::NoType;
45-
};
46-
4723
/**
4824
* \brief The QgsGeoPackageAbstractLayerItem class is the base class for GeoPackage raster and vector layers
4925
*/
@@ -94,8 +70,6 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
9470

9571
public:
9672
QgsGeoPackageConnectionItem( QgsDataItem *parent, QString name, QString path );
97-
//! Extract layers information from the geopackage
98-
QList<QgsGeoPackageLayerInfo *> subLayers( const QString &path ) const;
9973
QVector<QgsDataItem *> createChildren() override;
10074
virtual bool equal( const QgsDataItem *other ) override;
10175

@@ -142,10 +116,6 @@ class QgsGeoPackageRootItem : public QgsDataCollectionItem
142116
void connectionsChanged();
143117
void createDatabase();
144118
#endif
145-
146-
private:
147-
bool storeConnection( const QString &path );
148-
149119
};
150120

151121

0 commit comments

Comments
 (0)