Skip to content
Permalink
Browse files

PG raster: update extent when filter changes

plus other changes:
- fix extent calculation when filter is set
- more tests
  • Loading branch information
elpaso committed Mar 4, 2020
1 parent 71b9b76 commit 9815b2ae841107c45c3025842ad1e3180927f5fd
@@ -808,6 +808,12 @@ void QgsRasterLayer::setDataProvider( QString const &provider, const QgsDataProv
//mark the layer as valid
mValid = true;

if ( mDataProvider->supportsSubsetString() )
connect( this, &QgsRasterLayer::subsetStringChanged, this, &QgsMapLayer::configChanged, Qt::UniqueConnection );
else
disconnect( this, &QgsRasterLayer::subsetStringChanged, this, &QgsMapLayer::configChanged );


QgsDebugMsgLevel( QStringLiteral( "exiting." ), 4 );
}

@@ -891,6 +897,7 @@ void QgsRasterLayer::setDataSource( const QString &dataSource, const QString &ba
{
setDefaultContrastEnhancement();
}

emit statusChanged( tr( "QgsRasterLayer created" ) );
}
emit dataSourceChanged();
@@ -1265,9 +1272,9 @@ bool QgsRasterLayer::setSubsetString( const QString &subset )
// get the updated data source string from the provider
mDataSource = mDataProvider->dataSourceUri();


if ( res )
{
setExtent( mDataProvider->extent() );
emit subsetStringChanged();
triggerRepaint();
}
@@ -32,7 +32,8 @@ QgsPostgresRasterProvider::QgsPostgresRasterProvider( const QString &uri, const
: QgsRasterDataProvider( uri, providerOptions )
, mShared( new QgsPostgresRasterSharedData )
{
mUri = QgsDataSourceUri( uri );

mUri = uri;

// populate members from the uri structure
mSchemaName = mUri.schema();
@@ -703,7 +704,14 @@ bool QgsPostgresRasterProvider::setSubsetString( const QString &subset, bool upd
init();
return false;
}

mStatistics.clear();
mShared->invalidateCache();

// Update datasource uri too
mUri.setSql( subset );
setDataSourceUri( mUri.uri( false ) );

return true;
}

@@ -1589,7 +1597,7 @@ QgsRasterBandStats QgsPostgresRasterProvider::bandStatistics( int bandNo, int st
// Query the backend
QString where { extent.isEmpty() ? QString() : QStringLiteral( "WHERE %1 && ST_GeomFromText( %2, %3 )" )
.arg( quotedIdentifier( mRasterColumn ) )
.arg( extent.asWktPolygon() )
.arg( quotedValue( extent.asWktPolygon() ) )
.arg( mCrs.postgisSrid() ) };

if ( ! mSqlWhereClause.isEmpty() )
@@ -154,8 +154,8 @@ class QgsPostgresRasterProvider : public QgsRasterDataProvider

bool supportsSubsetString() const override { return true; }

virtual QString subsetString() const override;
virtual bool setSubsetString( const QString &subset, bool updateFeatureCount = true ) override;
QString subsetString() const override;
bool setSubsetString( const QString &subset, bool updateFeatureCount = true ) override;

bool hasSufficientPermsAndCapabilities();
void disconnectDb();
@@ -33,6 +33,7 @@
QgsPointXY,
QgsRaster,
QgsProviderRegistry,
QgsRasterBandStats,
)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath, compareWkt
@@ -148,6 +149,16 @@ def testWhereCondition(self):

self.assertAlmostEqual(rl.dataProvider().identify(rl.extent().center(), QgsRaster.IdentifyFormatValue).results()[1], 223.38, 2)

self.assertTrue(compareWkt(rl_nowhere.extent().asWktPolygon(), 'POLYGON((4080050 2430625, 4080200 2430625, 4080200 2430750, 4080050 2430750, 4080050 2430625))'))

self.assertTrue(compareWkt(rl.extent().asWktPolygon(), 'POLYGON((4080150 2430625, 4080200 2430625, 4080200 2430650, 4080150 2430650, 4080150 2430625))'))

self.assertNotEqual(rl.extent(), rl_nowhere.extent())

# Now check if setSubsetString updates the extent
self.assertTrue(rl_nowhere.setSubsetString('"category" = \'cat2\''))
self.assertEqual(rl.extent(), rl_nowhere.extent())

def testNoPk(self):
"""Read raster with no PK"""

@@ -253,6 +264,45 @@ def testUntiledMultipleRows(self):
data.append(int(block.value(i, j)))
self.assertEqual(data, [136, 142, 161, 169])

def testSetSubsetString(self):
"""Test setSubsetString"""

rl = QgsRasterLayer(self.dbconn + " sslmode=disable table={table} schema={schema} sql=\"pk\" = 2".format(table='raster_3035_untiled_multiple_rows', schema='public'), 'pg_layer', 'postgresraster')
self.assertTrue(rl.isValid())

block = rl.dataProvider().block(1, rl.extent(), 2, 2)
data = []
for i in range(2):
for j in range(2):
data.append(int(block.value(i, j)))
self.assertEqual(data, [136, 142, 161, 169])

stats = rl.dataProvider().bandStatistics(1, QgsRasterBandStats.Min | QgsRasterBandStats.Max, rl.extent())
self.assertEqual(int(stats.minimumValue), 136)
self.assertEqual(int(stats.maximumValue), 169)

self.assertTrue(rl.setSubsetString('"pk" = 1'))
block = rl.dataProvider().block(1, rl.extent(), 2, 2)
data = []
for i in range(2):
for j in range(2):
data.append(int(block.value(i, j)))
self.assertEqual(data, [136, 142, 145, 153])

# Check that we have new statistics
stats = rl.dataProvider().bandStatistics(1, QgsRasterBandStats.Min | QgsRasterBandStats.Max, rl.extent())
self.assertEqual(int(stats.minimumValue), 136)
self.assertEqual(int(stats.maximumValue), 153)

# Set invalid filter
self.assertFalse(rl.setSubsetString('"pk_wrong" = 1'))
block = rl.dataProvider().block(1, rl.extent(), 2, 2)
data = []
for i in range(2):
for j in range(2):
data.append(int(block.value(i, j)))
self.assertEqual(data, [136, 142, 145, 153])


if __name__ == '__main__':
unittest.main()
@@ -7,8 +7,11 @@ CREATE TABLE "public"."raster_3035_untiled_multiple_rows" ("pk" SERIAL PRIMARY K
INSERT INTO "public"."raster_3035_untiled_multiple_rows" ("rast", "pk")
VALUES ('0100000100000000000000394000000000000039C000000000D9204F41000000008F8B424100000000000000000000000000000000DB0B0000020002004A003C1CC66A610843880B0E436E0A1143BBAD1943'::raster, 1);
INSERT INTO "public"."raster_3035_untiled_multiple_rows" ("rast", "pk")
VALUES ('0100000100000000000000394000000000000039C000000000D9204F41000000008F8B424100000000000000000000000000000000DB0B0000020002004A003C1CC66A610843880B0E436E0A2143BBAD2943'::raster, 2)
;
VALUES ('0100000100000000000000394000000000000039C000000000D9204F41000000008F8B424100000000000000000000000000000000DB0B0000020002004A003C1CC66A610843880B0E436E0A2143BBAD2943'::raster, 2);

-- offset row
INSERT INTO "public"."raster_3035_untiled_multiple_rows" ("rast", "pk")
VALUES ('0100000100000000000000394000000000000039C000000000D9204F41000000008F8B424100000000000000000000000000000000DB0B0000020002004A003C1CC66A610843880B0E436E0A2143BBAD2943'::raster, 3);

CREATE INDEX ON "public"."raster_3035_untiled_multiple_rows" USING gist (st_convexhull("rast"));
ANALYZE "public"."raster_3035_untiled_multiple_rows";

0 comments on commit 9815b2a

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