def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') rasterFileInfo = QFileInfo(myPath) mRasterLayer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( mRasterLayer.dataProvider(), 2, 3, 4) mRasterLayer.setRenderer(rasterRenderer) #pipe = mRasterLayer.pipe() #assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsMapLayerRegistry.instance().addMapLayers([mRasterLayer]) # create composition with composer map self.mMapRenderer = QgsMapRenderer() layerStringList = QStringList() layerStringList.append(mRasterLayer.id()) self.mMapRenderer.setLayerSet(layerStringList) self.mMapRenderer.setProjectionsEnabled(False) self.mComposition = QgsComposition(self.mMapRenderer) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposition.addComposerMap(self.mComposerMap)
def testShaderCrash(self): """Check if we assign a shader and then reassign it no crash occurs.""" 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 myRasterShader = QgsRasterShader() myColorRampShader = QgsColorRampShader() myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED) myItems = [] myItem = QgsColorRampShader.ColorRampItem(10, QtGui.QColor('#ffff00'), 'foo') myItems.append(myItem) myItem = QgsColorRampShader.ColorRampItem(100, QtGui.QColor('#ff00ff'), 'bar') myItems.append(myItem) myItem = QgsColorRampShader.ColorRampItem(1000, QtGui.QColor('#00ff00'), 'kazam') myItems.append(myItem) myColorRampShader.setColorRampItemList(myItems) myRasterShader.setRasterShaderFunction(myColorRampShader) myPseudoRenderer = QgsSingleBandPseudoColorRenderer( myRasterLayer.dataProvider(), 1, myRasterShader) myRasterLayer.setRenderer(myPseudoRenderer) return ######## works first time ############# myRasterShader = QgsRasterShader() myColorRampShader = QgsColorRampShader() myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED) myItems = [] myItem = QgsColorRampShader.ColorRampItem(10, QtGui.QColor('#ffff00'), 'foo') myItems.append(myItem) myItem = QgsColorRampShader.ColorRampItem(100, QtGui.QColor('#ff00ff'), 'bar') myItems.append(myItem) myItem = QgsColorRampShader.ColorRampItem(1000, QtGui.QColor('#00ff00'), 'kazam') myItems.append(myItem) myColorRampShader.setColorRampItemList(myItems) myRasterShader.setRasterShaderFunction(myColorRampShader) ######## crash on next line (fixed now)################## myPseudoRenderer = QgsSingleBandPseudoColorRenderer( myRasterLayer.dataProvider(), 1, myRasterShader) myRasterLayer.setRenderer(myPseudoRenderer)
def test_setRenderer(self): myPath = os.path.join(unitTestDataPath("raster"), "band1_float32_noct_epsg4326.tif") myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() layer = QgsRasterLayer(myPath, myBaseName) self.rendererChanged = False layer.rendererChanged.connect(self.onRendererChanged) rShader = QgsRasterShader() r = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, rShader) layer.setRenderer(r) assert self.rendererChanged assert layer.renderer() == r
def loadLabelImage(imagepath, labeldescriptor = None): """ Load a labeled single band raster in the canvas Keyword arguments: imagepath -- the path to the image labeldescriptor -- a dictionnary for label (int) to tuple (QColor, QString) conversion """ if imagepath is None: return name = os.path.splitext( os.path.basename(imagepath) )[0] qgslayer = QgsRasterLayer(imagepath, name) if not qgslayer.isValid(): QtGui.QMessageBox.critical(None, u"Erreur", u"Impossible de charger la couche %s" % unicode(imagepath)) QgsMapLayerRegistry.instance().addMapLayer(qgslayer) qgslayer.setDrawingStyle('SingleBandPseudoColor') colorlist = [] max_label = 0 for label in sorted(labeldescriptor.keys()): color = labeldescriptor[label][0] labeltxt = labeldescriptor[label][1] colorlist.append(QgsColorRampShader.ColorRampItem(label, color, labeltxt)) if labeltxt > max_label: max_label = labeltxt s = QgsRasterShader() c = QgsColorRampShader() c.setColorRampType(QgsColorRampShader.INTERPOLATED) c.setColorRampItemList(colorlist) s.setRasterShaderFunction(c) ps = QgsSingleBandPseudoColorRenderer(qgslayer.dataProvider(), 1, s) qgslayer.setRenderer(ps) for bandNo in range(1,qgslayer.dataProvider().bandCount()+1): qgslayer.dataProvider().setUseSrcNoDataValue( bandNo, False ) QGisLayers.iface.legendInterface().refreshLayerSymbology(qgslayer) if hasattr(qgslayer, "setCacheImage"): qgslayer.setCacheImage(None) qgslayer.triggerRepaint()
def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, "rgb256x256.png") rasterFileInfo = QFileInfo(myPath) mRasterLayer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer(mRasterLayer.dataProvider(), 1, 2, 3) mRasterLayer.setRenderer(rasterRenderer) # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsMapLayerRegistry.instance().addMapLayers([mRasterLayer]) # create composition with composer map self.mMapSettings = QgsMapSettings() self.mMapSettings.setLayers([mRasterLayer.id()]) self.mMapSettings.setCrsTransformEnabled(False) self.mComposition = QgsComposition(self.mMapSettings) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposition.addComposerMap(self.mComposerMap)
def testPalettedBand(self): """ test paletted raster render band""" path = os.path.join(unitTestDataPath(), 'landsat_4326.tif') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path)) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 2, [QgsPalettedRasterRenderer.Class(137, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(138, QColor(255, 0, 0), 'class 1'), QgsPalettedRasterRenderer.Class(139, QColor(0, 0, 255), 'class 1')]) layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer_band2") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer_band2"), "Paletted rendering test failed") renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 3, [QgsPalettedRasterRenderer.Class(120, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(123, QColor(255, 0, 0), 'class 1'), QgsPalettedRasterRenderer.Class(124, QColor(0, 0, 255), 'class 1')]) layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer_band3") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer_band3"), "Paletted rendering test failed")
def testClone(self): myPath = os.path.join(unitTestDataPath('raster'), 'band1_float32_noct_epsg4326.tif') myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() layer = QgsRasterLayer(myPath, myBaseName) renderer = layer.renderer().clone() renderer.setOpacity(33.3) layer.setRenderer(renderer) # clone layer clone = layer.clone() # generate xml from layer layer_doc = QDomDocument("doc") layer_elem = layer_doc.createElement("maplayer") layer.writeLayerXml(layer_elem, layer_doc, QgsReadWriteContext()) # generate xml from clone clone_doc = QDomDocument("doc") clone_elem = clone_doc.createElement("maplayer") clone.writeLayerXml(clone_elem, clone_doc, QgsReadWriteContext()) # replace id within xml of clone clone_id_elem = clone_elem.firstChildElement("id") clone_id_elem_patch = clone_doc.createElement("id") clone_id_elem_patch_value = clone_doc.createTextNode(layer.id()) clone_id_elem_patch.appendChild(clone_id_elem_patch_value) clone_elem.replaceChild(clone_id_elem_patch, clone_id_elem) # update doc clone_doc.appendChild(clone_elem) layer_doc.appendChild(layer_elem) # compare xml documents self.assertEqual(layer_doc.toString(), clone_doc.toString())
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.setContrastEnhancementAlgorithm( QgsContrastEnhancement.StretchToMinimumMaximum, QgsRasterLayer.ContrastEnhancementMinMax) 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) QgsMapLayerRegistry.instance().addMapLayers([ myRasterLayer, ]) myMapRenderer = QgsMapRenderer() myLayers = QStringList() myLayers.append(myRasterLayer.id()) myMapRenderer.setLayerSet(myLayers) myMapRenderer.setExtent(myRasterLayer.extent()) myChecker = QgsRenderChecker() myChecker.setControlName("expected_raster_transparency") myChecker.setMapRenderer(myMapRenderer) myResultFlag = myChecker.runTest("raster_transparency_python"); assert myResultFlag, "Raster transparency rendering test failed"
def testPaletted(self): """ test paletted raster renderer with raster with color table""" path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path)) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, [QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')]) self.assertEqual(renderer.nColors(), 2) self.assertEqual(renderer.usesBands(), [1]) # test labels self.assertEqual(renderer.label(1), 'class 2') self.assertEqual(renderer.label(3), 'class 1') self.assertFalse(renderer.label(101)) # test legend symbology - should be sorted by value legend = renderer.legendSymbologyItems() self.assertEqual(legend[0][0], 'class 2') self.assertEqual(legend[1][0], 'class 1') self.assertEqual(legend[0][1].name(), '#00ff00') self.assertEqual(legend[1][1].name(), '#ff0000') # test retrieving classes classes = renderer.classes() self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'class 1') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') # test set label # bad index renderer.setLabel(1212, 'bad') renderer.setLabel(3, 'new class') self.assertEqual(renderer.label(3), 'new class') # color ramp r = QgsLimitedRandomColorRamp(5) renderer.setSourceColorRamp(r) self.assertEqual(renderer.sourceColorRamp().type(), 'random') self.assertEqual(renderer.sourceColorRamp().count(), 5) # clone new_renderer = renderer.clone() classes = new_renderer.classes() self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'new class') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') self.assertEqual(new_renderer.sourceColorRamp().type(), 'random') self.assertEqual(new_renderer.sourceColorRamp().count(), 5) # write to xml and read doc = QDomDocument('testdoc') elem = doc.createElement('qgis') renderer.writeXml(doc, elem) restored = QgsPalettedRasterRenderer.create(elem.firstChild().toElement(), layer.dataProvider()) self.assertTrue(restored) self.assertEqual(restored.usesBands(), [1]) classes = restored.classes() self.assertTrue(classes) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'new class') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') self.assertEqual(restored.sourceColorRamp().type(), 'random') self.assertEqual(restored.sourceColorRamp().count(), 5) # render test layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer"), "Paletted rendering test failed")
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mMapRenderer = self.mCanvas.mapRenderer() self.mMapRenderer.setOutputSize(QSize(400, 400), 72) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = QStringList() myLayers.append(self.mPointLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mPointLayer.setBlendMode(QPainter.CompositionMode_Overlay) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_blendmodes"); myMessage = ('vector blending failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = QStringList() myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("raster_blendmodes"); myMessage = ('raster blending failed') assert myResult, myMessage
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 TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testAsMapLayer(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) layer = overviewMap.overview().asMapLayer() self.assertIsNotNone(layer) self.assertTrue(layer.isValid()) self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) # check that layer has correct renderer fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'}) overviewMap.overview().setFrameSymbol(fill_symbol) layer = overviewMap.overview().asMapLayer() self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer) self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255') self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255') # test layer blend mode self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear) layer = overviewMap.overview().asMapLayer() self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear) # should have no effect overviewMap.setMapRotation(45) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) map.setMapRotation(15) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))']) # with reprojection map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875')) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))']) map.setCrs(overviewMap.crs()) # with invert overviewMap.overview().setInverted(True) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))']) def test_StackingPosition(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer) overviewMap.overview().setStackingLayer(None) self.assertIsNone(overviewMap.overview().stackingLayer()) def test_ModifyMapLayerList(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) self.assertFalse(overviewMap.overviews().modifyMapLayerList([])) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(None) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) # two overviews overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap)) overviewMap.overviews().overview(1).setLinkedMap(map) overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) def testOverviewStacking(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setLayers([self.raster_layer]) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(-20, -276, 276, 20) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setInverted(True) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_belowmap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_abovemap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty( QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) def testPartialLabels(self): """ Test rendering map item with a show partial labels flag """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) # default should always be to hide partial labels self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels) # hiding partial labels (the default) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # showing partial labels map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) checker = QgsLayoutChecker('composermap_show_partial_labels', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) def testBlockingItems(self): """ Test rendering map item with blocking items """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) map.setId('map') layout.addLayoutItem(map) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(0, 5, 50, 80)) map2.setFrameEnabled(True) map2.setBackgroundEnabled(False) map2.setId('map2') layout.addLayoutItem(map2) map3 = QgsLayoutItemMap(layout) map3.attemptSetSceneRect(QRectF(150, 160, 50, 50)) map3.setFrameEnabled(True) map3.setBackgroundEnabled(False) map3.setId('map3') layout.addLayoutItem(map3) map.addLabelBlockingItem(map2) map.addLabelBlockingItem(map3) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_blockers', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) doc = QDomDocument("testdoc") elem = layout.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) map_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map' ][0] map2_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2' ][0] map3_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3' ][0] self.assertTrue(map_restore.isLabelBlockingItem(map2_restore)) self.assertTrue(map_restore.isLabelBlockingItem(map3_restore))
class TestQgsBlendModes(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.iface = get_iface() # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsProject.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints(QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 1, 2, 3) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 1, 2, 3) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mapSettings = QgsMapSettings() self.mapSettings.setLayers([self.mRasterLayer1, self.mRasterLayer2]) self.mapSettings.setBackgroundColor(QColor(152, 219, 249)) self.mapSettings.setOutputSize(QSize(400, 400)) self.mapSettings.setOutputDpi(96) self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783, -83.3333333333331581, 46.8719806763287536) def testVectorBlending(self): """Test that blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_blendmodes", 20) myMessage = ('vector blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_featureblendmodes", 20) myMessage = ('vector feature blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_layertransparency", 20) myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" # Add raster layers to map myLayers = [self.mRasterLayer1, self.mRasterLayer2] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) # Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) checker.setColorTolerance(1) myResult = checker.runTest("raster_blendmodes", 20) myMessage = ('raster blending failed') assert myResult, myMessage
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 run(self): """Run method that performs all the real work""" # Update combos allLayers = self.iface.legendInterface().layers() rasterLayers = [lyr for lyr in allLayers if lyr.type() == 1] rasterNames = [lyr.name() for lyr in rasterLayers] vectorLayers = [lyr for lyr in allLayers if lyr.type() == 0] tableLayers = [lyr for lyr in vectorLayers if lyr.geometryType() == 4] tableNames = [lyr.name() for lyr in tableLayers] self.dlg.updateCombo(self.dlg.rasterCombo, rasterNames) self.dlg.updateCombo(self.dlg.tableCombo, tableNames) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: d = self.dlg table = self.getLayerbyName(d.getTable()) fields = [unicode(d.getValue()), d.getDescription()] colorMode = d.colorMode if colorMode != "rnd": fields = fields + d.getColors() fieldData = readFieldData(table, fields) grid = self.getLayerbyName(d.getRaster()) # If random colors, create a color for each category if colorMode == "rnd": cat = list(set([x[1] for x in fieldData])) colors = rndColorRamp(len(cat)) fieldData = [x + colors[cat.index(x[1])] for x in fieldData] # Paint raster shader = createRasterShader(fieldData, colorMode, d.getScale) render = renderer(grid.dataProvider(), 1, shader) grid.setRenderer(render) grid.triggerRepaint() if d.getNewRaster(): dstFile = d.getNewRasterFile() # Reclassify and create a new raster newclass, cat = intClass(fieldData) newraster = reclassRaster(grid, newclass, dstFile) # Add new raster to TOC and display baseName = os.path.basename(dstFile) newLayer = QgsRasterLayer(dstFile, baseName) QgsMapLayerRegistry.instance().addMapLayer(newLayer) # Re-paint the new raster shader = createRasterShader(cat, colorMode, d.getScale) render = renderer(newLayer.dataProvider(), 1, shader) newLayer.setRenderer(render) newLayer.triggerRepaint()
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create composition with composer map self.mComposition = QgsComposition(QgsProject.instance()) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposerMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(self.mComposerMap) def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker('composermap_overview', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(True) checker = QgsCompositionChecker('composermap_overview_invert', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create composition with composer map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsComposerMap(composition, 20, 20, 200, 100) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setNewExtent(rectangle) map.setLayers([self.vector_layer]) composition.addComposerMap(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsCompositionChecker('composermap_crs3857', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsCompositionChecker('composermap_crs4326', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXml(documentElement, doc) self.mComposition.addItemsFromXml(documentElement, doc) # test if both composer maps have different ids newMap = QgsComposerMap(self.mComposition, 0, 0, 10, 10) mapList = self.mComposition.composerMapItems() for mapIt in mapList: if mapIt != self.mComposerMap: newMap = mapIt break oldId = self.mComposerMap.id() newId = newMap.id() self.mComposition.removeComposerItem(newMap) myMessage = 'old: %s new: %s' % (oldId, newId) assert oldId != newId, myMessage def testWorldFileGeneration(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.setMapRotation(30.0) self.mComposition.setGenerateWorldFile(True) self.mComposition.setReferenceMap(self.mComposerMap) p = self.mComposition.computeWorldFileParameters() pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146, 2.4136013686911886, -4.179969388427311, 3342408.5663611) ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
class TestQgsBlendModes(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.iface = get_iface() # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsProject.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 1, 2, 3) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 1, 2, 3) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mapSettings = QgsMapSettings() self.mapSettings.setLayers([self.mRasterLayer1, self.mRasterLayer2]) self.mapSettings.setBackgroundColor(QColor(152, 219, 249)) self.mapSettings.setOutputSize(QSize(400, 400)) self.mapSettings.setOutputDpi(96) self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783, -83.3333333333331581, 46.8719806763287536) def testVectorBlending(self): """Test that blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_blendmodes", 20) myMessage = ('vector blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_featureblendmodes", 20) myMessage = ('vector feature blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerOpacity(self): """Test that layer opacity works for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setOpacity(0.5) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_layertransparency", 20) myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" # Add raster layers to map myLayers = [self.mRasterLayer1, self.mRasterLayer2] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) # Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) checker.setColorTolerance(1) myResult = checker.runTest("raster_blendmodes", 20) myMessage = ('raster blending failed') assert myResult, myMessage
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mapSettings = self.mCanvas.mapSettings() self.mapSettings.setOutputSize(QSize(400, 400)) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_blendmodes", 20) myMessage = ('vector blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_featureblendmodes", 20) myMessage = ('vector feature blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_layertransparency", 20) myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = [] myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) checker.setColorTolerance(1) myResult = checker.runTest("raster_blendmodes", 20) myMessage = ('raster blending failed') assert myResult, myMessage
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create composition with composer map self.mComposition = QgsComposition(QgsProject.instance()) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposerMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(self.mComposerMap) def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker('composermap_overview', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(True) checker = QgsCompositionChecker('composermap_overview_invert', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create composition with composer map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsComposerMap(composition, 20, 20, 200, 100) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setNewExtent(rectangle) map.setLayers([self.vector_layer]) composition.addComposerMap(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsCompositionChecker('composermap_crs3857', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsCompositionChecker('composermap_crs4326', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXml(documentElement, doc) self.mComposition.addItemsFromXml(documentElement, doc) # test if both composer maps have different ids newMap = QgsComposerMap(self.mComposition, 0, 0, 10, 10) mapList = self.mComposition.composerMapItems() for mapIt in mapList: if mapIt != self.mComposerMap: newMap = mapIt break oldId = self.mComposerMap.id() newId = newMap.id() self.mComposition.removeComposerItem(newMap) myMessage = 'old: %s new: %s' % (oldId, newId) assert oldId != newId, myMessage def testWorldFileGeneration(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.setMapRotation(30.0) self.mComposition.setGenerateWorldFile(True) self.mComposition.setReferenceMap(self.mComposerMap) p = self.mComposition.computeWorldFileParameters() pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146, 2.4136013686911886, -4.179969388427311, 3342408.5663611) ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap cls.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" @classmethod def tearDownClass(cls): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(cls.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty( QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testPartialLabels(self): """ Test rendering map item with a show partial labels flag """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) # default should always be to hide partial labels self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels) # hiding partial labels (the default) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) # showing partial labels map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) checker = QgsLayoutChecker('composermap_show_partial_labels', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testBlockingItems(self): """ Test rendering map item with blocking items """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) map.setId('map') layout.addLayoutItem(map) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(0, 5, 50, 80)) map2.setFrameEnabled(True) map2.setBackgroundEnabled(False) map2.setId('map2') layout.addLayoutItem(map2) map3 = QgsLayoutItemMap(layout) map3.attemptSetSceneRect(QRectF(150, 160, 50, 50)) map3.setFrameEnabled(True) map3.setBackgroundEnabled(False) map3.setId('map3') layout.addLayoutItem(map3) map.addLabelBlockingItem(map2) map.addLabelBlockingItem(map3) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_blockers', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) doc = QDomDocument("testdoc") elem = layout.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) map_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map' ][0] map2_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2' ][0] map3_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3' ][0] self.assertTrue(map_restore.isLabelBlockingItem(map2_restore)) self.assertTrue(map_restore.isLabelBlockingItem(map3_restore)) def testTheme(self): layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.followVisibilityPreset()) self.assertFalse(map.followVisibilityPresetName()) spy = QSignalSpy(map.themeChanged) map.setFollowVisibilityPresetName('theme') self.assertFalse(map.followVisibilityPreset()) self.assertEqual(map.followVisibilityPresetName(), 'theme') # should not be emitted - followVisibilityPreset is False self.assertEqual(len(spy), 0) map.setFollowVisibilityPresetName('theme2') self.assertEqual(map.followVisibilityPresetName(), 'theme2') self.assertEqual(len(spy), 0) map.setFollowVisibilityPresetName('') map.setFollowVisibilityPreset(True) # should not be emitted - followVisibilityPresetName is empty self.assertEqual(len(spy), 0) self.assertFalse(map.followVisibilityPresetName()) self.assertTrue(map.followVisibilityPreset()) map.setFollowVisibilityPresetName('theme') self.assertEqual(len(spy), 1) self.assertEqual(spy[-1][0], 'theme') map.setFollowVisibilityPresetName('theme') self.assertEqual(len(spy), 1) map.setFollowVisibilityPresetName('theme2') self.assertEqual(len(spy), 2) self.assertEqual(spy[-1][0], 'theme2') map.setFollowVisibilityPreset(False) self.assertEqual(len(spy), 3) self.assertFalse(spy[-1][0]) map.setFollowVisibilityPreset(False) self.assertEqual(len(spy), 3) map.setFollowVisibilityPresetName('theme3') self.assertEqual(len(spy), 3) map.setFollowVisibilityPreset(True) self.assertEqual(len(spy), 4) self.assertEqual(spy[-1][0], 'theme3') map.setFollowVisibilityPreset(True) self.assertEqual(len(spy), 4) # data defined theme map.dataDefinedProperties().setProperty( QgsLayoutObject.MapStylePreset, QgsProperty.fromValue('theme4')) map.refresh() self.assertEqual(len(spy), 5) self.assertEqual(spy[-1][0], 'theme4') map.refresh() self.assertEqual(len(spy), 5) map.dataDefinedProperties().setProperty( QgsLayoutObject.MapStylePreset, QgsProperty.fromValue('theme6')) map.refresh() self.assertEqual(len(spy), 6) self.assertEqual(spy[-1][0], 'theme6') def testClipping(self): format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(30) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'XXXX'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(False) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) props = {"color": "0,0,0,0", 'outline_style': 'no'} fillSymbol = QgsFillSymbol.createSimple(props) shape.setSymbol(fillSymbol) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setForceLabelsInsideClipPath(False) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) checker = QgsLayoutChecker('composermap_itemclip', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testClippingForceLabelsInside(self): format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(30) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'XXXX'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(False) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) props = {"color": "0,0,0,0", 'outline_style': 'no'} fillSymbol = QgsFillSymbol.createSimple(props) shape.setSymbol(fillSymbol) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setForceLabelsInsideClipPath(True) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly) checker = QgsLayoutChecker('composermap_itemclip_force_labels_inside', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testClippingOverview(self): format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(30) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'XXXX'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) vl2 = vl.clone() vl2.setLabelsEnabled(False) p = QgsProject() p.addMapLayer(vl) p.addMapLayer(vl2) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(False) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(160, 150, 70, 70)) map2.setFrameEnabled(True) map2extent = vl.extent() map2extent.grow(3) map2.zoomToExtent(map2extent) map2.setLayers([vl2]) layout.addLayoutItem(map2) overview = QgsLayoutItemMapOverview("t", map2) overview.setLinkedMap(map) props = { "color": "0,0,0,0", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) overview.setFrameSymbol(fillSymbol) map2.overviews().addOverview(overview) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) props = {"color": "0,0,0,0", 'outline_style': 'no'} fillSymbol = QgsFillSymbol.createSimple(props) shape.setSymbol(fillSymbol) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setForceLabelsInsideClipPath(False) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) checker = QgsLayoutChecker('composermap_itemclip_overview', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testClippingHideClipSource(self): """ When an item is set to be the clip source, it shouldn't render anything itself """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(30) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'XXXX'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(False) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setForceLabelsInsideClipPath(False) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) checker = QgsLayoutChecker('composermap_itemclip_nodrawsource', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) def testClippingBackgroundFrame(self): """ Make sure frame/background are also clipped """ vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) p = QgsProject() p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.setFrameStrokeWidth( QgsLayoutMeasurement(2, QgsUnitTypes.LayoutMillimeters)) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(200, 255, 200)) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly) checker = QgsLayoutChecker('composermap_itemclip_background', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message)
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin(QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty(QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) def testPartialLabels(self): """ Test rendering map item with a show partial labels flag """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) # default should always be to hide partial labels self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels) # hiding partial labels (the default) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # showing partial labels map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) checker = QgsLayoutChecker('composermap_show_partial_labels', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) def testBlockingItems(self): """ Test rendering map item with blocking items """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) map.setId('map') layout.addLayoutItem(map) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(0, 5, 50, 80)) map2.setFrameEnabled(True) map2.setBackgroundEnabled(False) map2.setId('map2') layout.addLayoutItem(map2) map3 = QgsLayoutItemMap(layout) map3.attemptSetSceneRect(QRectF(150, 160, 50, 50)) map3.setFrameEnabled(True) map3.setBackgroundEnabled(False) map3.setId('map3') layout.addLayoutItem(map3) map.addLabelBlockingItem(map2) map.addLabelBlockingItem(map3) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_blockers', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) doc = QDomDocument("testdoc") elem = layout.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) map_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map'][0] map2_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2'][0] map3_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3'][0] self.assertTrue(map_restore.isLabelBlockingItem(map2_restore)) self.assertTrue(map_restore.isLabelBlockingItem(map3_restore))
def idw_interpolation(layer, parent_dialog): """Run interpolation using inverse distance weight algorithm :param layer: Vector layer with drivetimes :type layer: QgsVectorLayer :param parent_dialog: A dialog that called this function. :type parent_dialog: QProgressDialog :returns raster_layer: Interpolated raster layer with drivetimes :rtype raster_layer: QgsRasterLayer """ raster_layer = None try: Processing.initialize() Processing.updateAlgsList() output_raster = processing.runalg( 'gdalogr:gridinvdist', layer, 'minutes', 2, 0, 0, 0, 0, 0, 0, 0, 5, "[temporary file]") output_file = output_raster['OUTPUT'] file_info = QFileInfo(output_file) base_name = file_info.baseName() # retrieving the raster output , styling it and load it in Qgis raster_layer = QgsRasterLayer(output_file, base_name) except Exception as exception: # pylint: disable=broad-except # noinspection PyCallByClass,PyTypeChecker,PyArgumentList if parent_dialog: display_warning_message_box( parent_dialog, parent_dialog.tr( 'Error'), parent_dialog.tr('Error loading isochrone map,' 'please check if you have processing ' 'plugin installed ')) else: display_warning_message_box( parent_dialog, 'Error', 'Error loading isochrone map,' 'please check if you have processing ' 'plugin installed ') if raster_layer: if raster_layer.isValid(): color_shader = QgsColorRampShader() color_shader.setColorRampType(QgsColorRampShader.INTERPOLATED) colors = { 'deep_green': '#1a9641', 'light_green': '#a6d96a', 'pale_yellow': '#ffffc0', 'light_red': '#fdae61', 'red': '#d7191c' } provider = raster_layer.dataProvider() stats = provider.bandStatistics( 1, QgsRasterBandStats.All, raster_layer.extent(), 0) values = {} if stats: min = stats.minimumValue max = stats.maximumValue stat_range = max - min add = stat_range / 4 values[0] = min value = min for index in range(1, 4): value += add values[index] = value values[4] = max else: display_warning_message_box( parent_dialog, parent_dialog.tr( 'Error'), parent_dialog.tr('Error loading isochrone map' ' Problem indexing the isochrones map')) color_list = [ QgsColorRampShader.ColorRampItem( values[0], QColor(colors['deep_green'])), QgsColorRampShader.ColorRampItem( values[1], QColor(colors['light_green'])), QgsColorRampShader.ColorRampItem( values[2], QColor(colors['pale_yellow'])), QgsColorRampShader.ColorRampItem( values[3], QColor(colors['light_red'])), QgsColorRampShader.ColorRampItem( values[4], QColor(colors['red'])) ] color_shader.setColorRampItemList(color_list) raster_shader = QgsRasterShader() raster_shader.setRasterShaderFunction(color_shader) renderer = QgsSingleBandPseudoColorRenderer( raster_layer.dataProvider(), 1, raster_shader) raster_layer.setRenderer(renderer) else: if parent_dialog: display_warning_message_box( parent_dialog, parent_dialog.tr( 'Problem'), parent_dialog.tr('Problem styling the isochrone map')) else: display_warning_message_box( parent_dialog, 'Problem', 'Problem styling the isochrone map') QgsMapLayerRegistry.instance().addMapLayers([raster_layer]) else: if parent_dialog: display_warning_message_box( parent_dialog, parent_dialog.tr( 'Error'), parent_dialog.tr('Error loading isochrone map ' 'Could not load interpolated file!')) else: display_warning_message_box( parent_dialog, 'Error', 'Error loading isochrone map ' 'Could not load interpolated file!') return raster_layer
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
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
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() ; self.mSimplifyMethod.setSimplifyHints(QgsVectorSimplifyMethod.NoSimplification); # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mapSettings = self.mCanvas.mapSettings() self.mapSettings.setOutputSize(QSize(400, 400)) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) myResult = checker.runTest("vector_blendmodes"); myMessage = ('vector blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) myResult = checker.runTest("vector_featureblendmodes"); myMessage = ('vector feature blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setLayerTransparency( 50 ) checker = QgsRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) myResult = checker.runTest("vector_layertransparency"); myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = [] myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) myResult = checker.runTest("raster_blendmodes"); myMessage = ('raster blending failed') assert myResult, myMessage
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)