def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement rl = QgsRasterLayer(self.gdalUri(), self.name) if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement, QgsDataSourceUri, QgsCredentials rl = QgsRasterLayer(self.gdalUri(), self.name) if not rl.isValid(): err = rl.error().summary() uri = QgsDataSourceUri(self.database().uri()) conninfo = uri.connectionInfo(False) username = uri.username() password = uri.password() for i in range(3): (ok, username, password) = QgsCredentials.instance().get( conninfo, username, password, err) if ok: uri.setUsername(username) uri.setPassword(password) rl = QgsRasterLayer(self.gdalUri(uri), self.name) if rl.isValid(): break if rl.isValid(): rl.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement rl = QgsRasterLayer(self.gdalUri(), self.name) if rl.isValid(): rl.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement # QGIS has no provider to load rasters, let's use GDAL uri = self.gpkgGdalUri() rl = QgsRasterLayer(uri, self.name) if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def testWriteAsImageInvalidOutputPath(self): tmpName = "/this/is/invalid/file.tif" source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal') source.setContrastEnhancement(algorithm=QgsContrastEnhancement.NoEnhancement) self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) self.assertEqual(fw.writeRaster(source.pipe(), provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), QgsRasterFileWriter.CreateDatasourceError) del fw
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement if self.database().connector.isGpkg(): # QGIS has no provider to load Geopackage rasters, let's use GDAL uri = self.ogrUri() else: # QGIS has no provider to load Rasterlite rasters, let's use GDAL uri = self.rasterliteGdalUri() rl = QgsRasterLayer(uri, self.name) if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def loadRaster(dlg, path, layerName): # Chargement d'un raster dans QGIS layer = QgsRasterLayer(path, layerName) if not layer.isValid(): messErreur(dlg, layerName + " ne peut pas être chargé.") return QgsProject.instance().addMapLayer(layer) messInfo(dlg, "Le fichier raster " + layerName + " a été correctement chargé.") messInfo(dlg, "") ContrastEnhancement = QgsContrastEnhancement.StretchToMinimumMaximum layer.setContrastEnhancement(ContrastEnhancement, QgsRaster.ContrastEnhancementCumulativeCut) layer.triggerRepaint() return layer
def loadRaster(self): """Load rasters when button is clicked.""" dbname, host, port, username, password = self.getConnectionParameters() schema = self.schema.itemText(self.schema.currentIndex()) table = self.table.itemText(self.table.currentIndex()) startdate = self.startdate.date() enddate = self.enddate.date() dates = [startdate] while dates[-1] < enddate: dates.append(dates[-1].addDays(1)) for dt in dates: connString = "PG: dbname={3} host={4} user={5} password={6} port={7} mode=2 schema={0} column=rast table={1} where='fdate=date\\'{2}\\''".format(schema, table, dt.toString("yyyy-M-d"), dbname, host, username, password, port) layer = QgsRasterLayer(connString, "{0}".format(dt.toString("yyyy-M-d"))) if layer.isValid(): layer.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) root = QgsProject.instance().layerTreeRoot() group = root.findGroup(schema) if group is None: group = root.addGroup(schema) QgsProject.instance().addMapLayer(layer, False) group.insertChildNode(0, QgsLayerTreeLayer(layer))
def testWriteAsImage(self): tmpName = tempfile.mktemp(suffix='.tif') source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal') source.setContrastEnhancement(algorithm=QgsContrastEnhancement.NoEnhancement) self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) self.assertEqual(fw.writeRaster(source.pipe(), provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), QgsRasterFileWriter.NoError) ds = gdal.Open(tmpName) self.assertEqual(ds.RasterCount, 4) self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672) self.assertEqual(ds.GetRasterBand(2).Checksum(), 4672) self.assertEqual(ds.GetRasterBand(3).Checksum(), 4672) self.assertEqual(ds.GetRasterBand(4).Checksum(), 4873) ds = None del fw os.unlink(tmpName)
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement, QgsDataSourceURI, QgsCredentials rl = QgsRasterLayer(self.gdalUri(), self.name) if not rl.isValid(): err = rl.error().summary() uri = QgsDataSourceURI(self.database().uri()) conninfo = uri.connectionInfo(False) username = uri.username() password = uri.password() for i in range(3): (ok, username, password) = QgsCredentials.instance().get(conninfo, username, password, err) if ok: uri.setUsername(username) uri.setPassword(password) rl = QgsRasterLayer(self.gdalUri(uri), self.name) if rl.isValid(): break if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def testTransparency(self): myPath = os.path.join(unitTestDataPath('raster'), 'band1_float32_noct_epsg4326.tif') myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() myRasterLayer = QgsRasterLayer(myPath, myBaseName) myMessage = 'Raster not loaded: %s' % myPath assert myRasterLayer.isValid(), myMessage renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1) myRasterLayer.setRenderer(renderer) myRasterLayer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum, QgsRasterMinMaxOrigin.MinMax) myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement() # print ("myContrastEnhancement.minimumValue = %.17g" % # myContrastEnhancement.minimumValue()) # print ("myContrastEnhancement.maximumValue = %.17g" % # myContrastEnhancement.maximumValue()) # Unfortunately the minimum/maximum values calculated in C++ and Python # are slightly different (e.g. 3.3999999521443642e+38 x # 3.3999999521444001e+38) # It is not clear where the precision is lost. # We set the same values as C++. myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38) myContrastEnhancement.setMaximumValue(3.3999999521443642e+38) #myType = myRasterLayer.dataProvider().dataType(1); #myEnhancement = QgsContrastEnhancement(myType); myTransparentSingleValuePixelList = [] rasterTransparency = QgsRasterTransparency() myTransparentPixel1 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel1.min = -2.5840000772112106e+38 myTransparentPixel1.max = -1.0879999684602689e+38 myTransparentPixel1.percentTransparent = 50 myTransparentSingleValuePixelList.append(myTransparentPixel1) myTransparentPixel2 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel2.min = 1.359999960575336e+37 myTransparentPixel2.max = 9.520000231087593e+37 myTransparentPixel2.percentTransparent = 70 myTransparentSingleValuePixelList.append(myTransparentPixel2) rasterTransparency.setTransparentSingleValuePixelList( myTransparentSingleValuePixelList) rasterRenderer = myRasterLayer.renderer() assert rasterRenderer rasterRenderer.setRasterTransparency(rasterTransparency) QgsProject.instance().addMapLayers([myRasterLayer, ]) myMapSettings = QgsMapSettings() myMapSettings.setLayers([myRasterLayer]) myMapSettings.setExtent(myRasterLayer.extent()) myChecker = QgsRenderChecker() myChecker.setControlName("expected_raster_transparency") myChecker.setMapSettings(myMapSettings) myResultFlag = myChecker.runTest("raster_transparency_python") assert myResultFlag, "Raster transparency rendering test failed"
class TestQgsRasterRendererCreateSld(unittest.TestCase): """ This class tests the creation of SLD from QGis raster layers """ @classmethod def setUpClass(self): pass def setUp(self): pass def tearDown(self): pass def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) def testSingleBandPseudoColorRenderer_Interpolated(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics(bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append(QgsColorRampShader.ColorRampItem(index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'ramp') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Discrete(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics(bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append(QgsColorRampShader.ColorRampItem(index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'intervals') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Exact(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics(bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append(QgsColorRampShader.ColorRampItem(index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries # !NOTE! can't reuse previous shader => segmentation fault shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(255): items.append(QgsColorRampShader.ColorRampItem(index, QColor.fromHsv(index, 255, 255, 255), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader) # self.raster_layer.setRenderer(rasterRenderer) # dom, root = self.rendererToSld(self.raster_layer.renderer()) # self.assertTrue( colorMap.hasAttribute( 'extendend' ) ) # self.assertEqual( colorMap.attribute( 'extendend' ), 'true' ) def testPalettedRasterRenderer(self): # create 10 color classes #classesString = '122 0 0 0 255 122\n123 1 1 1 255 123\n124 2 2 2 255 124\n125 3 3 3 255 125\n126 4 4 4 255 126\n127 5 5 5 255 127\n128 6 6 6 255 128\n129 7 7 7 255 129\n130 8 8 8 255 130' classesString = '' for index in range(10): classesString += '{0} {0} {0} {0} 255 {0}\n'.format(index) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries classesString = '' values = range(255) for index in range(255): classesString += '{0} {1} {1} {1} 255 {0}\n'.format(index, random.choice(values)) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertTrue(colorMap.hasAttribute('extended')) self.assertEqual(colorMap.attribute('extended'), 'true') def testMultiBandColorRenderer(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:RedChannel', '3') self.assertChannelBand(root, 'sld:GreenChannel', '1') self.assertChannelBand(root, 'sld:BlueChannel', '2') def testSingleBandGrayRenderer(self): # check with StretchToMinimumMaximum rasterRenderer = QgsSingleBandGrayRenderer(self.raster_layer.dataProvider(), 3) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) maximum = self.raster_layer.renderer().contrastEnhancement().maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement().minimumValue() self.assertEqual(minmum, 51) self.assertEqual(maximum, 172) # check default values dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'algorithm', 'StretchToMinimumMaximum') self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 2) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual(clorMap1.attributes().namedItem('quantity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual(clorMap2.attributes().namedItem('quantity').nodeValue(), '255') # check when StretchAndClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement().setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement().maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement().minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual(clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual(clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual(clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual(clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual(clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual(clorMap4.attributes().namedItem('opacity').nodeValue(), '0') # check when ClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement().setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement().maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement().minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual(clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual(clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual(clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual(clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual(clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual(clorMap4.attributes().namedItem('opacity').nodeValue(), '0') def testRasterRenderer(self): class fakerenderer(QgsRasterRenderer): def __init__(self, interface): QgsRasterRenderer.__init__(self, interface, '') rasterRenderer = fakerenderer(self.raster_layer.dataProvider()) self.raster_layer.setRenderer(rasterRenderer) # check opacity default value is not exported dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) # check if opacity is not the default value rasterRenderer.setOpacity(1.1) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertOpacity(root, '1.1') # check gamma properties from [-100:0] stretched to [0:1] # and (0:100] stretche dto (1:100] # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-100'}) # self.assertGamma(root, '0') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50'}) # self.assertGamma(root, '0.5') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '0'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '100'}) # self.assertGamma(root, '100') # # input contrast are always integer, btw the value is managed also if it's double # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.1'}) # self.assertGamma(root, '1.1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.6'}) # self.assertGamma(root, '1.6') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50.5'}) # self.assertGamma(root, '0.495') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-0.1'}) # self.assertGamma(root, '0.999') def testStretchingAlgorithm(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) # check StretchToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'StretchToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'StretchToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'StretchToMinimumMaximum', '133', '148') # check StretchAndClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToZero', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToZero', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToZero', '133', '148') # check ClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToMinimumMaximum', '133', '148') # check NoEnhancement stretching alg self.raster_layer.setContrastEnhancement(algorithm=QgsContrastEnhancement.NoEnhancement) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel') self.assertContrastEnhancement(root, 'sld:GreenChannel') self.assertContrastEnhancement(root, 'sld:BlueChannel') def assertVendorOption(self, root, name, expectedValue): """Set expectedValue=None to check that the vendor option is not present.""" vendorOptions = root.elementsByTagName('sld:VendorOption') found = False for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('sld:VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == name): found = True self.assertEqual(vendorOption.firstChild().nodeValue(), expectedValue) if (expectedValue is None) and found: self.fail("found VendorOption: {} where supposed not present".format(name)) if expectedValue and not found: self.fail("Not found VendorOption: {}".format(name)) def assertGamma(self, root, expectedValue, index=0): enhancement = root.elementsByTagName('sld:ContrastEnhancement').item(index) gamma = enhancement.firstChildElement('sld:GammaValue') self.assertEqual(expectedValue, gamma.firstChild().nodeValue()) def assertOpacity(self, root, expectedValue, index=0): opacity = root.elementsByTagName('sld:Opacity').item(index) self.assertEqual(expectedValue, opacity.firstChild().nodeValue()) def assertNoOpacity(self, root): opacities = root.elementsByTagName('sld:Opacity') self.assertEqual(opacities.size(), 0) def assertContrastEnhancement(self, root, bandTag, expectedAlg=None, expectedMin=None, expectedMax=None, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item(index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) # check if no enhancement alg is iset if (not expectedAlg): contrastEnhancementName = band.firstChildElement('sld:ContrastEnhancement') self.assertEqual('', contrastEnhancementName.firstChild().nodeName()) return # check if enhancement alg is set contrastEnhancementName = band.firstChildElement('sld:ContrastEnhancement') self.assertEqual('sld:Normalize', contrastEnhancementName.firstChild().nodeName()) normalize = contrastEnhancementName.firstChildElement('sld:Normalize') vendorOptions = normalize.elementsByTagName('VendorOption') for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == 'algorithm'): self.assertEqual(expectedAlg, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'minValue'): self.assertEqual(expectedMin, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'maxValue'): self.assertEqual(expectedMax, vendorOption.firstChild().nodeValue()) else: self.fail('Unrecognised vendorOption name {}'.format(vendorOption.attributes().namedItem('name').nodeValue())) def assertChannelBand(self, root, bandTag, expectedValue, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item(index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) sourceChannelName = band.firstChildElement('sld:SourceChannelName') self.assertEqual(expectedValue, sourceChannelName.firstChild().nodeValue()) def rendererToSld(self, renderer, properties={}): dom = QDomDocument() root = dom.createElement("FakeRoot") dom.appendChild(root) renderer.toSld(dom, root, properties) return dom, root
def openNdviFile(self, file_name): """ Open file with NDVI :param file_name: path to file with NDVI :type: unicode """ self.LOGGER.info("opening NDVI file: %s", file_name) try: self.validateInputFilePath(file_name) except CalculatorException as e: self.LOGGER.info(e.message) self.dlg.show_error_message(self.getTranslation(e.title), self.getTranslation(e.message)) return ndvi0_raster_layer = QgsRasterLayer(file_name, "NDVI - <0") layer_data_type = ndvi0_raster_layer.dataProvider().dataType(1) ndvi_thresholds = NdviThreshold().dataTypes.get(layer_data_type) if ndvi_thresholds is None: self.LOGGER.info("NDVI file - unknown data type") self.dlg.show_error_message(self.getTranslation("NDVI file open error"), self.getTranslation("Unknown data type")) ndvi_raster_layer = QgsRasterLayer(file_name, "NDVI") map_layer_registry = QgsMapLayerRegistry.instance() map_layer_registry.addMapLayer(ndvi_raster_layer) return ndvi025_raster_layer = QgsRasterLayer(file_name, "NDVI - 0-0.25") ndvi05_raster_layer = QgsRasterLayer(file_name, "NDVI - 0.25-0.5") ndvi075_raster_layer = QgsRasterLayer(file_name, "NDVI - 0.5-0.75") ndvi1_raster_layer = QgsRasterLayer(file_name, "NDVI - 0.75-1") algorithm = QgsContrastEnhancement.StretchToMinimumMaximum limits = QgsRaster.ContrastEnhancementMinMax ndvi0_raster_layer.setContrastEnhancement(algorithm, limits) ndvi025_raster_layer.setContrastEnhancement(algorithm, limits) ndvi05_raster_layer.setContrastEnhancement(algorithm, limits) ndvi075_raster_layer.setContrastEnhancement(algorithm, limits) ndvi1_raster_layer.setContrastEnhancement(algorithm, limits) colors_scheme = ColorsForNdviMap().getColorScheme(self.dlg.cbx_color_schemes.currentText()) ndvi0_raster_layer.setRenderer( self.getRenderer(ndvi0_raster_layer.dataProvider(), self.getColorMapForNdvi0(colors_scheme, ndvi_thresholds))) ndvi025_raster_layer.setRenderer( self.getRenderer(ndvi025_raster_layer.dataProvider(), self.getColorMapForNdvi025(colors_scheme, ndvi_thresholds))) ndvi05_raster_layer.setRenderer( self.getRenderer(ndvi05_raster_layer.dataProvider(), self.getColorMapForNdvi05(colors_scheme, ndvi_thresholds))) ndvi075_raster_layer.setRenderer( self.getRenderer(ndvi075_raster_layer.dataProvider(), self.getColorMapForNdvi075(colors_scheme, ndvi_thresholds))) ndvi1_raster_layer.setRenderer( self.getRenderer(ndvi1_raster_layer.dataProvider(), self.getColorMapForNdvi1(colors_scheme, ndvi_thresholds))) map_layer_registry = QgsMapLayerRegistry.instance() map_layer_registry.addMapLayer(ndvi0_raster_layer) map_layer_registry.addMapLayer(ndvi025_raster_layer) map_layer_registry.addMapLayer(ndvi05_raster_layer) map_layer_registry.addMapLayer(ndvi075_raster_layer) map_layer_registry.addMapLayer(ndvi1_raster_layer)
class TestQgsRasterRendererCreateSld(unittest.TestCase): """ This class tests the creation of SLD from QGis raster layers """ @classmethod def setUpClass(self): pass def setUp(self): pass def tearDown(self): pass def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) def testSingleBandPseudoColorRenderer_Interpolated(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'ramp') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Discrete(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'intervals') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Exact(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries # !NOTE! can't reuse previous shader => segmentation fault shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(255): items.append( QgsColorRampShader.ColorRampItem( index, QColor.fromHsv(index, 255, 255, 255), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) # self.raster_layer.setRenderer(rasterRenderer) # dom, root = self.rendererToSld(self.raster_layer.renderer()) # self.assertTrue( colorMap.hasAttribute( 'extendend' ) ) # self.assertEqual( colorMap.attribute( 'extendend' ), 'true' ) def testPalettedRasterRenderer(self): # create 10 color classes #classesString = '122 0 0 0 255 122\n123 1 1 1 255 123\n124 2 2 2 255 124\n125 3 3 3 255 125\n126 4 4 4 255 126\n127 5 5 5 255 127\n128 6 6 6 255 128\n129 7 7 7 255 129\n130 8 8 8 255 130' classesString = '' for index in range(10): classesString += '{0} {0} {0} {0} 255 {0}\n'.format(index) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries classesString = '' values = range(255) for index in range(255): classesString += '{0} {1} {1} {1} 255 {0}\n'.format( index, random.choice(values)) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertTrue(colorMap.hasAttribute('extended')) self.assertEqual(colorMap.attribute('extended'), 'true') def testMultiBandColorRenderer(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:RedChannel', '3') self.assertChannelBand(root, 'sld:GreenChannel', '1') self.assertChannelBand(root, 'sld:BlueChannel', '2') def testSingleBandGrayRenderer(self): # check with StretchToMinimumMaximum rasterRenderer = QgsSingleBandGrayRenderer( self.raster_layer.dataProvider(), 3) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 51) self.assertEqual(maximum, 172) # check default values dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'algorithm', 'StretchToMinimumMaximum') self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 2) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '255') # check when StretchAndClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement( ).setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual( clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual( clorMap4.attributes().namedItem('opacity').nodeValue(), '0') # check when ClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement( ).setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual( clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual( clorMap4.attributes().namedItem('opacity').nodeValue(), '0') def testRasterRenderer(self): class fakerenderer(QgsRasterRenderer): def __init__(self, interface): QgsRasterRenderer.__init__(self, interface, '') rasterRenderer = fakerenderer(self.raster_layer.dataProvider()) self.raster_layer.setRenderer(rasterRenderer) # check opacity default value is not exported dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) # check if opacity is not the default value rasterRenderer.setOpacity(1.1) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertOpacity(root, '1.1') # check gamma properties from [-100:0] streched to [0:1] # and (0:100] stretche dto (1:100] # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-100'}) # self.assertGamma(root, '0') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50'}) # self.assertGamma(root, '0.5') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '0'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '100'}) # self.assertGamma(root, '100') # # input contrast are always integer, btw the value is managed also if it's double # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.1'}) # self.assertGamma(root, '1.1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.6'}) # self.assertGamma(root, '1.6') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50.5'}) # self.assertGamma(root, '0.495') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-0.1'}) # self.assertGamma(root, '0.999') def testStretchingAlgorithm(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) # check StretchToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'StretchToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'StretchToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'StretchToMinimumMaximum', '133', '148') # check StretchAndClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToZero', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToZero', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToZero', '133', '148') # check ClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToMinimumMaximum', '133', '148') # check NoEnhancement stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.NoEnhancement) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel') self.assertContrastEnhancement(root, 'sld:GreenChannel') self.assertContrastEnhancement(root, 'sld:BlueChannel') def assertVendorOption(self, root, name, expectedValue): """Set expectedValue=None to check that the vendor option is not present.""" vendorOptions = root.elementsByTagName('sld:VendorOption') found = False for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('sld:VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == name ): found = True self.assertEqual(vendorOption.firstChild().nodeValue(), expectedValue) if (expectedValue is None) and found: self.fail( "found VendorOption: {} where supposed not present".format( name)) if expectedValue and not found: self.fail("Not found VendorOption: {}".format(name)) def assertGamma(self, root, expectedValue, index=0): enhancement = root.elementsByTagName('sld:ContrastEnhancement').item( index) gamma = enhancement.firstChildElement('sld:GammaValue') self.assertEqual(expectedValue, gamma.firstChild().nodeValue()) def assertOpacity(self, root, expectedValue, index=0): opacity = root.elementsByTagName('sld:Opacity').item(index) self.assertEqual(expectedValue, opacity.firstChild().nodeValue()) def assertNoOpacity(self, root): opacities = root.elementsByTagName('sld:Opacity') self.assertEqual(opacities.size(), 0) def assertContrastEnhancement(self, root, bandTag, expectedAlg=None, expectedMin=None, expectedMax=None, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item( index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) # check if no enhancement alg is iset if (not expectedAlg): contrastEnhancementName = band.firstChildElement( 'sld:ContrastEnhancement') self.assertEqual('', contrastEnhancementName.firstChild().nodeName()) return # check if enhancement alg is set contrastEnhancementName = band.firstChildElement( 'sld:ContrastEnhancement') self.assertEqual('sld:Normalize', contrastEnhancementName.firstChild().nodeName()) normalize = contrastEnhancementName.firstChildElement('sld:Normalize') vendorOptions = normalize.elementsByTagName('VendorOption') for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == 'algorithm'): self.assertEqual(expectedAlg, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'minValue'): self.assertEqual(expectedMin, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'maxValue'): self.assertEqual(expectedMax, vendorOption.firstChild().nodeValue()) else: self.fail('Unrecognised vendorOption name {}'.format( vendorOption.attributes().namedItem('name').nodeValue())) def assertChannelBand(self, root, bandTag, expectedValue, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item( index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) sourceChannelName = band.firstChildElement('sld:SourceChannelName') self.assertEqual(expectedValue, sourceChannelName.firstChild().nodeValue()) def rendererToSld(self, renderer, properties={}): dom = QDomDocument() root = dom.createElement("FakeRoot") dom.appendChild(root) renderer.toSld(dom, root, properties) return dom, root
def runAlgorithm(self): start = timeit.default_timer() self._id = str(np.random.randint(1, 5000)) logMessageFile = open( os.path.dirname(__file__) + "/logLCP" + self._id + ".txt", "w") logMessage = "LCPNetwork plugin init - loading points and base raster layers with id: " + self._id QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") origins, destinations = self.loadPoints() baseRaster = self.loadBaseRaster() logMessage = "computing " + str( origins.featureCount()) + " origin points towards " + str( destinations.featureCount()) + " destinations" QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") self.transform = baseRaster.GetGeoTransform() self.projection = baseRaster.GetProjection() nodata = baseRaster.GetRasterBand(1).GetNoDataValue() logMessage = "loading cost map with nodata value " + str(nodata) QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") topLeft = QgsPointXY(self.transform[0], self.transform[3]) pointsListO = [] for point in origins.getFeatures(): pointsListO.append(point.geometry().asPoint()) pointsListD = [] for point in destinations.getFeatures(): pointsListD.append(point.geometry().asPoint()) ## create the list of lcps lcps = [] numThreads = os.cpu_count() logMessage = "creating " + str(numThreads) + " threads" QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") pool = futures.ThreadPoolExecutor(numThreads) index = 0 results = [] for source in pointsListO: results.append( pool.submit(self.computeOnePath, source, index, start, baseRaster, pointsListD, lcps, logMessageFile)) index = index + 1 for future in futures.as_completed(results): logMessageFile.write(future.result() + "\n") logMessage = "all lcps computed at time: " + str( "%.2f" % (timeit.default_timer() - start)) QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") # same CRS than base raster cost map crs = QgsCoordinateReferenceSystem() crs.createFromString(baseRaster.GetProjection()) for i in range(index): outputName = os.path.dirname( __file__) + "/distances" + self._id + "_" + str(i) + ".tif" newRasterQGIS = QgsRasterLayer( outputName, "distances" + self._id + "_" + str(i)) newRasterQGIS.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum) newRasterQGIS.setCrs(crs) QgsProject.instance().addMapLayer(newRasterQGIS) # add the list of lcps to the network layer network = self.iface.addVectorLayer("LineString?crs=" + crs.authid(), "least cost path network", "memory") network.dataProvider().addFeatures(lcps) logMessage = "LCPNetwork plugin finished! time (sec.): " + str( "%.2f" % (timeit.default_timer() - start)) QgsMessageLog.logMessage(logMessage, tag="LCPNetwork", level=Qgis.Info) logMessageFile.write(logMessage + "\n") logMessageFile.close()
def addRasterLayers(project, server, schema): """ add postgis raster layers to qgis project """ groups = [] # get postgis raster table records = server.getTableNames(schema, match='^rast_[0-9]{8}_.*') print('processing {count} tables in schema {schema}'.format( count=len(records), schema=schema)) for record in records: # get gdal postgis raster connection string table = record[0] uri_config = { # database parameters 'dbname': server.getDatabase(), # The PostgreSQL database to connect to. 'host': server.getHost(), # The host IP address or localhost. 'port': server.getPort(), # The port to connect on. 'sslmode': QgsDataSourceUri. SslDisable, # SslAllow, SslPrefer, SslRequire, SslVerifyCa, SslVerifyFull # user and password are not needed if stored in the authcfg or service 'authcfg': None, # The QGIS athentication database ID holding connection details. 'service': None, # The PostgreSQL service to be used for connection to the database. 'username': '******', # The PostgreSQL user name. 'password': '******', # The PostgreSQL password for the user. # table and raster column details 'schema': schema, # The database schema that the table is located in. 'table': table, # The database table to be loaded. 'geometrycolumn': 'rast', # raster column in PostGIS table 'sql': None, # An SQL WHERE clause. It should be placed at the end of the string. 'key': None, # A key column from the table. 'srid': '27700', # A string designating the SRID of the coordinate reference system. 'estimatedmetadata': 'False', # A boolean value telling if the metadata is estimated. 'type': None, # A WKT string designating the WKB Type. 'selectatid': None, # Set to True to disable selection by feature ID. 'options': None, # other PostgreSQL connection options not in this list. 'enableTime': None, 'temporalDefaultTime': None, 'temporalFieldIndex': None, 'mode': '2', # GDAL 'mode' parameter, 2 unions raster tiles, 1 adds tiles separately (may require user input) } # remove any NULL parameters uri_config = { key: val for key, val in uri_config.items() if val is not None } # get metadata for raster provider and configure uri md = QgsProviderRegistry.instance().providerMetadata('postgresraster') uri = QgsDataSourceUri(md.encodeUri(uri_config)) # create layer layer = QgsRasterLayer(uri.uri(False), table, "postgresraster") if layer.isValid(): try: # add to project layer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum, QgsRasterMinMaxOrigin.CumulativeCut) QgsProject.instance().addMapLayer(layer) # extract date from table name dt = datetime.strptime( re.search('[0-9]{8}', table)[0], '%Y%m%d') sub_group = next( (item for item in groups if str(dt.year) == item['year']), None) if sub_group is None: groups.append({'year': str(dt.year), 'layers': []}) # add layer id to schema / year indexed lists sub_group = next( (item for item in groups if str(dt.year) == item['year']), None) sub_group['layers'].append({ 'id': layer.id(), 'dt': dt, 'name': table }) except Exception as e: print('ERROR: {conn} {msg}'.format(conn=uri.uri(False), msg=e)) # return layers in yearly slices in descending order return sorted(groups, key=lambda k: k['year'], reverse=True)