Skip to content
Permalink
Browse files

Merge pull request #5727 from nyalldawson/sublayer

Fix ogr sublayer handling of names containing ":"
  • Loading branch information
nyalldawson committed Nov 28, 2017
2 parents 2156e89 + a95aeca commit 7a09f0890ee7fa08e8fd7ee550cc6b000bd28329
Showing with 109 additions and 62 deletions.
  1. +8 −0 python/core/qgsdataprovider.sip
  2. +2 −1 python/plugins/processing/tools/dataobjects.py
  3. +4 −4 src/app/qgisapp.cpp
  4. +2 −2 src/app/qgsoptions.cpp
  5. +2 −2 src/app/qgsprojectproperties.cpp
  6. +3 −3 src/app/qgsversionmigration.cpp
  7. +1 −0 src/core/qgsdataprovider.cpp
  8. +8 −0 src/core/qgsdataprovider.h
  9. +1 −1 src/gui/qgsmetadatawidget.cpp
  10. +3 −3 src/plugins/grass/qgsgrassmapcalc.cpp
  11. +1 −1 src/plugins/grass/qgsgrassmodule.cpp
  12. +1 −1 src/plugins/grass/qgsgrassmoduleinput.cpp
  13. +1 −1 src/plugins/grass/qgsgrassmoduleoptions.cpp
  14. +5 −5 src/plugins/grass/qgsgrassmoduleparam.cpp
  15. +1 −1 src/providers/arcgisrest/qgsafsprovider.cpp
  16. +1 −1 src/providers/arcgisrest/qgsamsdataitems.cpp
  17. +1 −1 src/providers/arcgisrest/qgsamssourceselect.cpp
  18. +1 −1 src/providers/arcgisrest/qgsarcgisrestutils.cpp
  19. +1 −1 src/providers/gdal/qgsgdaldataitems.cpp
  20. +1 −1 src/providers/gdal/qgsgdalprovider.cpp
  21. +4 −4 src/providers/grass/qgsgrass.cpp
  22. +2 −2 src/providers/grass/qgsgrassprovidermodule.cpp
  23. +1 −1 src/providers/grass/qgsgrassrasterprovider.cpp
  24. +2 −2 src/providers/ogr/qgsogrdataitems.cpp
  25. +16 −3 src/providers/ogr/qgsogrprovider.cpp
  26. +1 −1 src/providers/wfs/qgswfsprovider.cpp
  27. +1 −1 src/server/qgsserverrequest.cpp
  28. +2 −2 src/server/services/wfs/qgswfsgetfeature.cpp
  29. +1 −1 src/server/services/wfs/qgswfsparameters.cpp
  30. +1 −1 src/server/services/wfs/qgswfstransaction.cpp
  31. +1 −1 src/server/services/wfs/qgswfstransaction_1_0_0.cpp
  32. +4 −4 src/server/services/wms/qgswmsparameters.cpp
  33. +1 −1 src/server/services/wms/qgswmsrenderer.cpp
  34. +1 −1 tests/src/core/testqgsmaprendererjob.cpp
  35. +1 −1 tests/src/core/testqgsrastersublayer.cpp
  36. +3 −3 tests/src/python/test_provider_ogr.py
  37. +19 −3 tests/src/python/test_provider_ogr_gpkg.py
@@ -164,9 +164,17 @@ class QgsDataProvider : QObject

Sub-layers are used when the provider's source can combine layers
it knows about in some way before it hands them off to the provider.

.. seealso:: SUBLAYER_SEPARATOR
:rtype: list of str
%End

static QString SUBLAYER_SEPARATOR;
%Docstring
String sequence used for separating components of sublayers strings.
.. seealso:: subLayers()
.. versionadded:: 3.0
%End

virtual QStringList subLayerStyles() const;
%Docstring
@@ -32,6 +32,7 @@

from qgis.core import (QgsVectorFileWriter,
QgsMapLayer,
QgsDataProvider,
QgsRasterLayer,
QgsWkbTypes,
QgsVectorLayer,
@@ -309,7 +310,7 @@ def getRasterSublayer(path, param):
subLayer = subLayer[1:]
else:
# remove driver name and file name
subLayer.replace(subLayer.split(":")[0], "")
subLayer.replace(subLayer.split(QgsDataProvider.SUBLAYER_SEPARATOR)[0], "")
subLayer.replace(path, "")
# remove any : or " left over
if subLayer.startswith(":"):
@@ -4230,7 +4230,7 @@ bool QgisApp::addVectorLayers( const QStringList &layerQStringList, const QStrin
else if ( !sublayers.isEmpty() ) // there is 1 layer of data available
{
//set friendly name for datasources with only one layer
QStringList elements = sublayers.at( 0 ).split( ':' );
QStringList elements = sublayers.at( 0 ).split( QgsDataProvider::SUBLAYER_SEPARATOR );
QString subLayerNameFormatted = elements.size() >= 2 ? QgsMapLayer::formatLayerName( elements.at( 1 ) ) : QString();

if ( elements.size() >= 4 && layer->name().compare( elements.at( 1 ), Qt::CaseInsensitive ) != 0
@@ -4443,7 +4443,7 @@ void QgisApp::askUserForGDALSublayers( QgsRasterLayer *layer )
else
{
// remove driver name and file name
name.remove( name.split( ':' )[0] );
name.remove( name.split( QgsDataProvider::SUBLAYER_SEPARATOR )[0] );
name.remove( path );
}
// remove any : or " left over
@@ -4591,7 +4591,7 @@ void QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
// OGR provider returns items in this format:
// <layer_index>:<name>:<feature_count>:<geom_type>

QStringList elements = sublayer.split( QStringLiteral( ":" ) );
QStringList elements = sublayer.split( QgsDataProvider::SUBLAYER_SEPARATOR );
// merge back parts of the name that may have been split
while ( elements.size() > 5 )
{
@@ -10025,7 +10025,7 @@ QgsVectorLayer *QgisApp::addVectorLayer( const QString &vectorLayerPath, const Q
QStringList sublayers = layer->dataProvider()->subLayers();
if ( !sublayers.isEmpty() )
{
QStringList elements = sublayers.at( 0 ).split( ':' );
QStringList elements = sublayers.at( 0 ).split( QgsDataProvider::SUBLAYER_SEPARATOR );
QString subLayerNameFormatted = elements.size() >= 2 ? QgsMapLayer::formatLayerName( elements.at( 1 ) ) : QString();

if ( elements.size() >= 4 && layer->name().compare( elements.at( 1 ), Qt::CaseInsensitive ) != 0
@@ -2346,11 +2346,11 @@ void QgsOptions::addScaleToScaleList( QListWidgetItem *newItem )
QListWidgetItem *duplicateItem = mListGlobalScales->findItems( newItem->text(), Qt::MatchExactly ).value( 0 );
delete duplicateItem;

int newDenominator = newItem->text().split( QStringLiteral( ":" ) ).value( 1 ).toInt();
int newDenominator = newItem->text().split( ':' ).value( 1 ).toInt();
int i;
for ( i = 0; i < mListGlobalScales->count(); i++ )
{
int denominator = mListGlobalScales->item( i )->text().split( QStringLiteral( ":" ) ).value( 1 ).toInt();
int denominator = mListGlobalScales->item( i )->text().split( ':' ).value( 1 ).toInt();
if ( newDenominator > denominator )
break;
}
@@ -1992,11 +1992,11 @@ void QgsProjectProperties::addScaleToScaleList( QListWidgetItem *newItem )
QListWidgetItem *duplicateItem = lstScales->findItems( newItem->text(), Qt::MatchExactly ).value( 0 );
delete duplicateItem;

int newDenominator = newItem->text().split( QStringLiteral( ":" ) ).value( 1 ).toInt();
int newDenominator = newItem->text().split( ':' ).value( 1 ).toInt();
int i;
for ( i = 0; i < lstScales->count(); i++ )
{
int denominator = lstScales->item( i )->text().split( QStringLiteral( ":" ) ).value( 1 ).toInt();
int denominator = lstScales->item( i )->text().split( ':' ).value( 1 ).toInt();
if ( newDenominator > denominator )
break;
}
@@ -201,7 +201,7 @@ QgsError Qgs2To3Migration::migrateSettings()
if ( line.isEmpty() )
continue;

QStringList parts = line.split( ";" );
const QStringList parts = line.split( ';' );

Q_ASSERT_X( parts.count() == 2, "QgsVersionMigration::migrateSettings()", "Can't split line in 2 parts." );

@@ -327,10 +327,10 @@ QPair<QString, QString> Qgs2To3Migration::transformKey( QString fullOldKey, QStr

if ( newKeyPart.endsWith( "/*" ) )
{
QStringList newKeyparts = newKeyPart.split( "/" );
QStringList newKeyparts = newKeyPart.split( '/' );
// Throw away the *
newKeyparts.removeLast();
QStringList oldKeyParts = fullOldKey.split( "/" );
QStringList oldKeyParts = fullOldKey.split( '/' );
for ( int i = 0; i < newKeyparts.count(); ++i )
{
oldKeyParts.replace( i, newKeyparts.at( i ) );
@@ -15,6 +15,7 @@

#include "qgsdataprovider.h"

QString QgsDataProvider::SUBLAYER_SEPARATOR = QString( "!!::!!" );

void QgsDataProvider::setProviderProperty( QgsDataProvider::ProviderProperty property, const QVariant &value )
{
@@ -218,12 +218,20 @@ class CORE_EXPORT QgsDataProvider : public QObject
*
* Sub-layers are used when the provider's source can combine layers
* it knows about in some way before it hands them off to the provider.
*
* \see SUBLAYER_SEPARATOR
*/
virtual QStringList subLayers() const
{
return QStringList(); // Empty
}

/**
* String sequence used for separating components of sublayers strings.
* \see subLayers()
* \since QGIS 3.0
*/
static QString SUBLAYER_SEPARATOR;

/**
* Sub-layer styles for each sub-layer handled by this provider,
@@ -715,7 +715,7 @@ void QgsMetadataWidget::updatePanel() const
if ( !categories.isEmpty() )
{
int row = categories.at( 0 )->row();
mCategoriesModel->setStringList( tabKeywords->item( row, 1 )->text().split( QStringLiteral( "," ) ) );
mCategoriesModel->setStringList( tabKeywords->item( row, 1 )->text().split( ',' ) );
}
else
{
@@ -512,7 +512,7 @@ QStringList QgsGrassMapcalc::checkRegion()

struct Cell_head window;

QStringList mm = obj->value().split( QStringLiteral( "@" ) );
QStringList mm = obj->value().split( '@' );
if ( mm.size() < 1 )
continue;

@@ -571,7 +571,7 @@ bool QgsGrassMapcalc::inputRegion( struct Cell_head *window, QgsCoordinateRefere

struct Cell_head mapWindow;

QStringList mm = obj->value().split( QStringLiteral( "@" ) );
QStringList mm = obj->value().split( '@' );
if ( mm.size() < 1 )
continue;

@@ -652,7 +652,7 @@ void QgsGrassMapcalc::setOption()
{
case QgsGrassMapcalcObject::Map :
{
QStringList mapMapset = mObject->value().split( QStringLiteral( "@" ) );
QStringList mapMapset = mObject->value().split( '@' );
if ( !mMapComboBox->setCurrent( mapMapset.value( 0 ), mapMapset.value( 1 ) ) )
{
mMapComboBox->setEditText( mObject->value() );
@@ -672,7 +672,7 @@ void QgsGrassModule::run()
}
else // option
{
QStringList opt = arg.split( "=" );
QStringList opt = arg.split( '=' );
//env = "GIS_OPT_" + opt.takeFirst().toUpper();
//env += "=" + opt.join( "=" ); // rejoin rest
environment.insert( "GIS_OPT_" + opt.takeFirst().toUpper(), opt.join( "=" ) );
@@ -858,7 +858,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
{
int mask = 0;

Q_FOREACH ( const QString &typeName, opt.split( "," ) )
Q_FOREACH ( const QString &typeName, opt.split( ',' ) )
{
mask |= QgsGrass::vectorType( typeName );
}
@@ -845,7 +845,7 @@ bool QgsGrassModuleStandardOptions::getCurrentMapRegion( QgsGrassModuleInput *in
return false;
}

QStringList mm = input->currentMap().split( QStringLiteral( "@" ) );
QStringList mm = input->currentMap().split( '@' );
QString map = mm.value( 0 );
QString mapset = QgsGrass::getDefaultMapset();
if ( mm.size() > 1 )
@@ -436,7 +436,7 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
{
QDomElement e = n.toElement();
QString val = e.text().trimmed();
minMax = val.split( QStringLiteral( "-" ) );
minMax = val.split( '-' );
if ( minMax.size() == 2 )
{
mHaveLimits = true;
@@ -902,7 +902,7 @@ void QgsGrassModuleGdalInput::updateQgisLayers()
}
else if ( vector->providerType() == QLatin1String( "ogr" ) )
{
QStringList items = provider->dataSourceUri().split( QStringLiteral( "|" ) );
QStringList items = provider->dataSourceUri().split( '|' );

if ( items.size() > 1 )
{
@@ -913,7 +913,7 @@ void QgsGrassModuleGdalInput::updateQgisLayers()

for ( int i = 1; i < items.size(); i++ )
{
QStringList args = items[i].split( QStringLiteral( "=" ) );
QStringList args = items[i].split( '=' );

if ( args.size() != 2 )
continue;
@@ -1219,7 +1219,7 @@ void QgsGrassModuleSelection::onLayerChanged()
{
QString uri = vectorLayer->dataProvider()->dataSourceUri();
QgsDebugMsg( "uri = " + uri );
QString layerCode = uri.split( QStringLiteral( "/" ) ).last();
QString layerCode = uri.split( '/' ).last();
if ( mLayerInput->currentLayerCodes().contains( layerCode ) )
{
// Qt::UserRole+1 may be also uri (AddLayer) but hardly matching layer id
@@ -1464,7 +1464,7 @@ void QgsGrassModuleFile::browse()

if ( mType == Multiple )
{
QString path = mLineEdit->text().split( QStringLiteral( "," ) ).first();
QString path = mLineEdit->text().split( ',' ).first();
if ( path.isEmpty() )
path = lastDir;
else
@@ -59,7 +59,7 @@ QgsAfsProvider::QgsAfsProvider( const QString &uri )
mLayerDescription = layerData[QStringLiteral( "description" )].toString();

// Set extent
QStringList coords = mSharedData->mDataSource.param( QStringLiteral( "bbox" ) ).split( QStringLiteral( "," ) );
QStringList coords = mSharedData->mDataSource.param( QStringLiteral( "bbox" ) ).split( ',' );
if ( coords.size() == 4 )
{
bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false;
@@ -103,7 +103,7 @@ QVector<QgsDataItem *> QgsAmsConnectionItem::createChildren()
QString format = QStringLiteral( "jpg" );
bool found = false;
QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
foreach ( const QString &encoding, serviceData["supportedImageFormatTypes"].toString().split( "," ) )
foreach ( const QString &encoding, serviceData["supportedImageFormatTypes"].toString().split( ',' ) )
{
foreach ( const QByteArray &fmt, supportedFormats )
{
@@ -44,7 +44,7 @@ bool QgsAmsSourceSelect::connectToService( const QgsOwsConnection &connection )
return false;
}

populateImageEncodings( serviceInfoMap[QStringLiteral( "supportedImageFormatTypes" )].toString().split( QStringLiteral( "," ) ) );
populateImageEncodings( serviceInfoMap[QStringLiteral( "supportedImageFormatTypes" )].toString().split( ',' ) );

QStringList layerErrors;
foreach ( const QVariant &layerInfo, serviceInfoMap["layers"].toList() )
@@ -388,7 +388,7 @@ QVariantMap QgsArcGisRestUtils::getObjects( const QString &layerurl, const QList
QUrl queryUrl( layerurl + "/query" );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
queryUrl.addQueryItem( QStringLiteral( "objectIds" ), ids.join( QStringLiteral( "," ) ) );
QString wkid = crs.indexOf( QLatin1String( ":" ) ) >= 0 ? crs.split( QStringLiteral( ":" ) )[1] : QLatin1String( "" );
QString wkid = crs.indexOf( QLatin1String( ":" ) ) >= 0 ? crs.split( ':' )[1] : QLatin1String( "" );
queryUrl.addQueryItem( QStringLiteral( "inSR" ), wkid );
queryUrl.addQueryItem( QStringLiteral( "outSR" ), wkid );
QString outFields = fetchAttributes.join( QStringLiteral( "," ) );
@@ -89,7 +89,7 @@ QVector<QgsDataItem *> QgsGdalLayerItem::createChildren()
else
{
// remove driver name and file name and initial ':'
name.remove( name.split( ':' )[0] + ':' );
name.remove( name.split( QgsDataProvider::SUBLAYER_SEPARATOR )[0] + ':' );
name.remove( mPath );
}
// remove any : or " left over
@@ -1154,7 +1154,7 @@ QString QgsGdalProvider::generateBandName( int bandNumber ) const
val = values.at( 1 );
if ( values.at( 0 ) == QLatin1String( "NETCDF_DIM_EXTRA" ) )
{
dimExtraValues = val.replace( QStringLiteral( "{" ), QString() ).replace( QStringLiteral( "}" ), QString() ).split( ',' );
dimExtraValues = val.replace( '{', QString() ).replace( '}', QString() ).split( ',' );
//http://qt-project.org/doc/qt-4.8/qregexp.html#capturedTexts
}
else
@@ -1515,7 +1515,7 @@ QStringList QgsGrass::grassObjects( const QgsGrassObject &mapsetObject, QgsGrass
fullName = fullName.trimmed();
if ( !fullName.isEmpty() )
{
QStringList nameMapset = fullName.split( QStringLiteral( "@" ) );
QStringList nameMapset = fullName.split( '@' );
if ( nameMapset.value( 1 ) == mapsetObject.mapset() || nameMapset.value( 1 ).isEmpty() )
{
list << nameMapset.value( 0 );
@@ -2133,7 +2133,7 @@ QgsRectangle QgsGrass::extent( const QString &gisdbase, const QString &location,
try
{
QString str = getInfo( QStringLiteral( "window" ), gisdbase, location, mapset, map, type );
QStringList list = str.split( QStringLiteral( "," ) );
QStringList list = str.split( ',' );
if ( list.size() != 4 )
{
throw QgsGrass::Exception( "Cannot parse GRASS map extent: " + str );
@@ -2157,7 +2157,7 @@ void QgsGrass::size( const QString &gisdbase, const QString &location, const QSt
try
{
QString str = getInfo( QStringLiteral( "size" ), gisdbase, location, mapset, map, QgsGrassObject::Raster );
QStringList list = str.split( QStringLiteral( "," ) );
QStringList list = str.split( ',' );
if ( list.size() != 2 )
{
throw QgsGrass::Exception( "Cannot parse GRASS map size: " + str );
@@ -2250,7 +2250,7 @@ QMap<QString, QString> QgsGrass::query( const QString &gisdbase, const QString &
try
{
QString str = getInfo( QStringLiteral( "query" ), gisdbase, location, mapset, map, type, x, y );
QStringList list = str.trimmed().split( QStringLiteral( ":" ) );
QStringList list = str.trimmed().split( ':' );
if ( list.size() == 2 )
{
result[list[0]] = list[1];
@@ -559,8 +559,8 @@ QVector<QgsDataItem *> QgsGrassMapsetItem::createChildren()
// somewhere not properly escaped (there was bug in QgsMimeDataUtils for example)
QString uri = mDirPath + "/" + name + "/" + layerName;
QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
QString typeName = layerName.split( QStringLiteral( "_" ) ).value( 1 );
QString baseLayerName = layerName.split( QStringLiteral( "_" ) ).value( 0 );
QString typeName = layerName.split( '_' ).value( 1 );
QString baseLayerName = layerName.split( '_' ).value( 0 );

if ( typeName == QLatin1String( "point" ) || typeName == QLatin1String( "node" ) )
layerType = QgsLayerItem::Point;
@@ -675,7 +675,7 @@ double QgsGrassRasterValue::value( double x, double y, bool *ok )

// TODO: use doubles instead of strings

QStringList list = str.trimmed().split( QStringLiteral( ":" ) );
QStringList list = str.trimmed().split( ':' );
if ( list.size() == 2 )
{
if ( list[1] == QLatin1String( "error" ) ) return value;
@@ -163,7 +163,7 @@ QList<QgsOgrDbLayerInfo *> QgsOgrLayerItem::subLayers( const QString &path, cons
int prevIdx = -1;
for ( const QString &descriptor : subLayersList )
{
QStringList pieces = descriptor.split( ':' );
QStringList pieces = descriptor.split( QgsDataProvider::SUBLAYER_SEPARATOR );
int idx = pieces[0].toInt();
subLayersMap.insert( idx, pieces );
if ( pieces.count() >= 4 && idx != prevIdx )
@@ -238,7 +238,7 @@ QList<QgsOgrDbLayerInfo *> QgsOgrLayerItem::subLayers( const QString &path, cons
const QStringList layers( rlayer.dataProvider()->subLayers( ) );
for ( const QString &uri : layers )
{
QStringList pieces = uri.split( ':' );
QStringList pieces = uri.split( QgsDataProvider::SUBLAYER_SEPARATOR );
QString name = pieces.value( pieces.length() - 1 );
QgsDebugMsgLevel( QStringLiteral( "Adding GeoPackage Raster item %1 %2 %3" ).arg( name, uri ), 3 );
children.append( new QgsOgrDbLayerInfo( path, uri, name, QStringLiteral( "" ), QStringLiteral( "Raster" ), QgsLayerItem::LayerType::Raster ) );

0 comments on commit 7a09f08

Please sign in to comment.
You can’t perform that action at this time.