Skip to content
Permalink
Browse files

PG raster: support mosaics with no metadata

Fixes #39017
  • Loading branch information
elpaso authored and nyalldawson committed Sep 26, 2020
1 parent 9953570 commit 84e204954fda63159885ec9322b73aea4f9505bf
@@ -1221,10 +1221,7 @@ bool QgsPostgresRasterProvider::init()
where = QStringLiteral( "WHERE %1" ).arg( subsetString() );
}

// If we dropped here from the fast track because there was something wrong reading metadata
// we can safely assume that the raster is NOT tiled and add LIMIT 1 in the query below to
// speed things up.

// Unfortunately we cannot safely assume that the raster is untiled and just LIMIT 1
// Fastest SQL: fetch all metadata in one pass
// 0 1 3 3 4 5 6 7 8 9 10 11 12 13 14
// encode | upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands | pixeltype | nodatavalue | isoutdb | path
@@ -1237,9 +1234,7 @@ bool QgsPostgresRasterProvider::init()
(ST_Metadata( band )).*,
(ST_BandMetadata( band )).*
FROM cte_band
)" ).arg( quotedIdentifier( mRasterColumn ),
tableToQuery,
where.isEmpty() &&mUseEstimatedMetadata ? QStringLiteral( "LIMIT 1" ) : where ) };
)" ).arg( quotedIdentifier( mRasterColumn ), tableToQuery, where ) };

QgsDebugMsgLevel( QStringLiteral( "Raster information sql: %1" ).arg( sql ), 4 );

@@ -80,6 +80,7 @@ def setUpClass(cls):
cls._load_test_table(
'public', 'int16_regression_36689', 'bug_36689_pg_raster')
cls._load_test_table('public', 'bug_37968_dem_linear_cdn_extract')
cls._load_test_table('public', 'bug_39017_untiled_no_metadata')

# Fix timing issues in backend
# time.sleep(1)
@@ -493,8 +494,8 @@ def testNegativeScaleY(self):
table='bug_37968_dem_linear_cdn_extract', schema='public'), 'pg_layer', 'postgresraster')

self.assertTrue(rl.isValid())
compareWkt(rl.extent().asWktPolygon(
), 'POLYGON((-40953.223387096 170588, -40873.21532258 170588, -40873.21532258 170668, -40953.223387096 170668, -40953.23387096))')
self.assertTrue(compareWkt(rl.extent().asWktPolygon(
), 'POLYGON((-40953 170588, -40873 170588, -40873 170668, -40953 170668, -40953 170588))', 1))
block = rl.dataProvider().block(1, rl.extent(), 6, 6)
data = []
for i in range(6):
@@ -503,6 +504,57 @@ def testNegativeScaleY(self):

self.assertEqual(data, [52, 52, 52, 52, 44, 43, 52, 52, 52, 48, 44, 44, 49, 52, 49, 44, 44, 44, 43, 47, 46, 44, 44, 44, 42, 42, 43, 44, 44, 48, 42, 43, 43, 44, 44, 47])

def testUntiledMosaicNoMetadata(self):
"""Test regression https://github.com/qgis/QGIS/issues/39017
+-----------+------------------------------+
| | |
| rid = 1 | rid = 2 |
| | |
+-----------+------------------------------+
"""

rl = QgsRasterLayer(
self.dbconn + " sslmode=disable table={table} schema={schema}".format(
table='bug_39017_untiled_no_metadata', schema='public'), 'pg_layer', 'postgresraster')
self.assertTrue(rl.isValid())
self.assertTrue(compareWkt(rl.extent().asWktPolygon(
), 'POLYGON((47.061 40.976, 47.123 40.976, 47.123 41.000, 47.061 41.000, 47.061 40.976))', 0.01))

rl1 = QgsRasterLayer(
self.dbconn + " sslmode=disable table={table} schema={schema} sql=\"rid\"=1".format(
table='bug_39017_untiled_no_metadata', schema='public'), 'pg_layer', 'postgresraster')
self.assertTrue(rl1.isValid())
self.assertTrue(compareWkt(rl1.extent().asWktPolygon(
), 'POLYGON((47.061 40.976, 47.070 40.976, 47.070 41.000, 47.061 41.000, 47.061 40.976))', 0.01))

rl2 = QgsRasterLayer(
self.dbconn + " sslmode=disable table={table} schema={schema} sql=\"rid\"=2".format(
table='bug_39017_untiled_no_metadata', schema='public'), 'pg_layer', 'postgresraster')
self.assertTrue(rl2.isValid())
self.assertTrue(compareWkt(rl2.extent().asWktPolygon(
), 'POLYGON((47.061 40.976, 47.123 40.976, 47.123 41.000, 47.070 41.000, 47.070 40.976))', 0.01))

extent_1 = rl1.extent()
extent_2 = rl2.extent()

def _6x6_block_data(layer, extent):
block = layer.dataProvider().block(1, extent, 6, 6)
data = []
for i in range(6):
for j in range(6):
data.append(int(block.value(i, j)))
return data

rl_r1 = _6x6_block_data(rl, extent_1)
r1_r1 = _6x6_block_data(rl1, extent_1)
self.assertEqual(rl_r1, r1_r1)

rl_r2 = _6x6_block_data(rl, extent_2)
r2_r2 = _6x6_block_data(rl2, extent_2)
self.assertEqual(rl_r2, r2_r2)


if __name__ == '__main__':
unittest.main()

Large diffs are not rendered by default.

0 comments on commit 84e2049

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