Skip to content

Commit

Permalink
Ensure correct encoded source is written to history and log
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 26, 2020
1 parent 320fecc commit 6cf9bee
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -4745,7 +4745,7 @@ QString QgsProcessingParameterFeatureSource::valueAsPythonString( const QVariant

// prefer to use layer source if possible (since it's persistent)
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
layerString = layer->source();
layerString = layer->providerType() != QLatin1String( "ogr" ) && layer->providerType() != QLatin1String( "gdal" ) && layer->providerType() != QLatin1String( "mdal" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( layer->providerType(), layer->source() ) : layer->source();

return QgsProcessingUtils::stringToPythonLiteral( layerString );
}
Expand Down
74 changes: 59 additions & 15 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -214,27 +214,51 @@ QgsMapLayer *QgsProcessingUtils::mapLayerFromStore( const QString &string, QgsMa

QgsMapLayer *QgsProcessingUtils::loadMapLayerFromString( const QString &string, const QgsCoordinateTransformContext &transformContext, LayerHint typeHint )
{
QStringList components = string.split( '|' );
if ( components.isEmpty() )
return nullptr;

QFileInfo fi;
if ( QFileInfo::exists( string ) )
fi = QFileInfo( string );
else if ( QFileInfo::exists( components.at( 0 ) ) )
fi = QFileInfo( components.at( 0 ) );
QString provider;
QString uri;
const bool useProvider = decodeProviderKeyAndUri( string, provider, uri );
if ( !useProvider )
uri = string;

QString name;
// for disk based sources, we use the filename to determine a layer name
if ( !useProvider || ( provider == QLatin1String( "ogr" ) || provider == QLatin1String( "gdal" ) || provider == QLatin1String( "mdal" ) ) )
{
QStringList components = uri.split( '|' );
if ( components.isEmpty() )
return nullptr;

QFileInfo fi;
if ( QFileInfo::exists( uri ) )
fi = QFileInfo( uri );
else if ( QFileInfo::exists( components.at( 0 ) ) )
fi = QFileInfo( components.at( 0 ) );
else
return nullptr;
name = fi.baseName();
}
else
return nullptr;

QString name = fi.baseName();
{
name = QgsDataSourceUri( uri ).table();
}

// brute force attempt to load a matching layer
if ( typeHint == LayerHint::UnknownType || typeHint == LayerHint::Vector )
{
QgsVectorLayer::LayerOptions options { transformContext };
options.loadDefaultStyle = false;
options.skipCrsValidation = true;
std::unique_ptr< QgsVectorLayer > layer = qgis::make_unique<QgsVectorLayer>( string, name, QStringLiteral( "ogr" ), options );

std::unique_ptr< QgsVectorLayer > layer;
if ( useProvider )
{
layer = qgis::make_unique<QgsVectorLayer>( uri, name, provider, options );
}
else
{
// fallback to ogr
layer = qgis::make_unique<QgsVectorLayer>( uri, name, QStringLiteral( "ogr" ), options );
}
if ( layer->isValid() )
{
return layer.release();
Expand All @@ -245,7 +269,18 @@ QgsMapLayer *QgsProcessingUtils::loadMapLayerFromString( const QString &string,
QgsRasterLayer::LayerOptions rasterOptions;
rasterOptions.loadDefaultStyle = false;
rasterOptions.skipCrsValidation = true;
std::unique_ptr< QgsRasterLayer > rasterLayer( new QgsRasterLayer( string, name, QStringLiteral( "gdal" ), rasterOptions ) );

std::unique_ptr< QgsRasterLayer > rasterLayer;
if ( useProvider )
{
rasterLayer = qgis::make_unique< QgsRasterLayer >( uri, name, provider, rasterOptions );
}
else
{
// fallback to gdal
rasterLayer = qgis::make_unique< QgsRasterLayer >( uri, name, QStringLiteral( "gdal" ), rasterOptions );
}

if ( rasterLayer->isValid() )
{
return rasterLayer.release();
Expand All @@ -255,7 +290,16 @@ QgsMapLayer *QgsProcessingUtils::loadMapLayerFromString( const QString &string,
{
QgsMeshLayer::LayerOptions meshOptions;
meshOptions.skipCrsValidation = true;
std::unique_ptr< QgsMeshLayer > meshLayer( new QgsMeshLayer( string, name, QStringLiteral( "mdal" ), meshOptions ) );

std::unique_ptr< QgsMeshLayer > meshLayer;
if ( useProvider )
{
meshLayer = qgis::make_unique< QgsMeshLayer >( uri, name, provider, meshOptions );
}
else
{
meshLayer = qgis::make_unique< QgsMeshLayer >( uri, name, QStringLiteral( "mdal" ), meshOptions );
}
if ( meshLayer->isValid() )
{
return meshLayer.release();
Expand Down
15 changes: 15 additions & 0 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -1069,13 +1069,27 @@ void TestQgsProcessing::mapLayers()

delete l;

// use encoded provider/uri string
l = QgsProcessingUtils::loadMapLayerFromString( QStringLiteral( "gdal://%1" ).arg( raster ), QgsCoordinateTransformContext() );
QVERIFY( l->isValid() );
QCOMPARE( l->type(), QgsMapLayerType::RasterLayer );
QCOMPARE( l->name(), QStringLiteral( "landsat" ) );
delete l;

//test with vector
l = QgsProcessingUtils::loadMapLayerFromString( vector, QgsCoordinateTransformContext() );
QVERIFY( l->isValid() );
QCOMPARE( l->type(), QgsMapLayerType::VectorLayer );
QCOMPARE( l->name(), QStringLiteral( "points" ) );
delete l;

// use encoded provider/uri string
l = QgsProcessingUtils::loadMapLayerFromString( QStringLiteral( "ogr://%1" ).arg( vector ), QgsCoordinateTransformContext() );
QVERIFY( l->isValid() );
QCOMPARE( l->type(), QgsMapLayerType::VectorLayer );
QCOMPARE( l->name(), QStringLiteral( "points" ) );
delete l;

l = QgsProcessingUtils::loadMapLayerFromString( QString(), QgsCoordinateTransformContext() );
QVERIFY( !l );
l = QgsProcessingUtils::loadMapLayerFromString( QStringLiteral( "so much room for activities!" ), QgsCoordinateTransformContext() );
Expand Down Expand Up @@ -5509,6 +5523,7 @@ void TestQgsProcessing::parameterFeatureSource()
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( v2 ), context ), QStringLiteral( "'%1'" ).arg( vector2 ) );
QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "postgres://uri='complex' username=\"complex\"" ), context ), QStringLiteral( "'postgres://uri=\\'complex\\' username=\\\"complex\\\"'" ) );

QVariantMap map = def->toVariantMap();
QgsProcessingParameterFeatureSource fromMap( "x" );
Expand Down

0 comments on commit 6cf9bee

Please sign in to comment.