def testTrueNorth(self): """Test syncing picture to true north""" mapSettings = QgsMapSettings() composition = QgsComposition(mapSettings, QgsProject.instance()) composerMap = QgsComposerMap(composition) composerMap.setCrs(QgsCoordinateReferenceSystem.fromEpsgId(3575)) composerMap.setNewExtent(QgsRectangle(-2126029.962, -2200807.749, -119078.102, -757031.156)) composition.addComposerMap(composerMap) composerPicture = QgsComposerPicture(composition) composition.addComposerPicture(composerPicture) composerPicture.setRotationMap(composerMap.id()) self.assertTrue(composerPicture.rotationMap() >= 0) composerPicture.setNorthMode(QgsComposerPicture.TrueNorth) self.assertAlmostEqual(composerPicture.pictureRotation(), 37.20, 1) # shift map composerMap.setNewExtent(QgsRectangle(2120672.293, -3056394.691, 2481640.226, -2796718.780)) self.assertAlmostEqual(composerPicture.pictureRotation(), -38.18, 1) # rotate map composerMap.setMapRotation(45) self.assertAlmostEqual(composerPicture.pictureRotation(), -38.18 + 45, 1) # add an offset composerPicture.setNorthOffset(-10) self.assertAlmostEqual(composerPicture.pictureRotation(), -38.18 + 35, 1)
def _set_up_composition(self, width, height, dpi): # set up composition and add map self._c = QgsComposition(self._TestMapSettings, QgsProject.instance()) """:type: QgsComposition""" # self._c.setUseAdvancedEffects(False) self._c.setPrintResolution(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi self._c.setPaperSize(paperw, paperh) # NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10) """:type: QgsComposerMap""" self._cmap.setPreviewMode(QgsComposerMap.Render) self._cmap.setFrameEnabled(False) self._c.addComposerMap(self._cmap) # now expand map to fill page and set its extent self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setNewExtent(self.aoiExtent()) # self._cmap.updateCachedImage() self._c.setPlotStyle(QgsComposition.Print)
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 __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 testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) 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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage
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) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage
def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXML(documentElement, doc) self.mComposition.addItemsFromXML(documentElement, doc, 0, False) #test if both composer maps have different ids newMap = QgsComposerMap() 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 uniqueId(self, mComposerMap, mComposition): doc = QDomDocument() documentElement = doc.createElement( "ComposerItemClipboard" ) mComposerMap.writeXML( documentElement, doc ) mComposition.addItemsFromXML( documentElement, doc, 0, false ) #test if both composer maps have different ids newMap = QgsComposerMap() mapList = mComposition.composerMapItems() for mapIt in mapList: if mapIt != mComposerMap: newMap = mapIt break oldId = mComposerMap.id() newId = newMap.id() mComposition.removeComposerItem( newMap ); print "old: "+str(oldId) print "new "+str(newId) assert oldId != newId
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, "points.shp") point_layer = QgsVectorLayer(point_path, "points", "ogr") QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple( {"color": "#ff0000", "outline_style": "no", "size": "5", "size_unit": "MapUnit"} ) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) s.setCrsTransformEnabled(False) composition = QgsComposition(s, QgsProject.instance()) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameOutlineWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle("") composition.addComposerLegend(legend) legend.setComposerMap(composer_map) checker = QgsCompositionChecker("composer_legend_mapunits", composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsMapLayerRegistry.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbolV2.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'}) point_layer.setRendererV2(QgsSingleSymbolRendererV2(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer.id()]) s.setCrsTransformEnabled(False) composition = QgsComposition(s) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameOutlineWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') composition.addComposerLegend(legend) legend.setComposerMap(composer_map) checker = QgsCompositionChecker( 'composer_legend_mapunits', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsMapLayerRegistry.instance().removeMapLayers([point_layer.id()])
def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # create composition with composer map self.mMapSettings = QgsMapSettings() crs = QgsCoordinateReferenceSystem(32633) self.mMapSettings.setDestinationCrs(crs) 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.setBackgroundColor(QColor(150, 100, 100)) self.mComposition.addComposerMap(self.mComposerMap)
def testResizeDisabledCrop(self): """Test that if legend resizing is disabled, and legend is too small, then content is cropped""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composer_map.setLayers([point_layer]) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 20, 20)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) # disable auto resizing legend.setResizeToContents(False) composition.addComposerLegend(legend) legend.setComposerMap(composer_map) composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsCompositionChecker( 'composer_legend_noresize_crop', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(True) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_landsat_overview_invert.png') myTestResult, myMessage = checker.testComposition( 'Composer map overview inverted', self.mComposition, myPngPath) self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage
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 testResizeDisabled(self): """Test that test legend does not resize if auto size is disabled""" point_path = os.path.join(TEST_DATA_DIR, "points.shp") point_layer = QgsVectorLayer(point_path, "points", "ogr") QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) s.setCrsTransformEnabled(False) composition = QgsComposition(s, QgsProject.instance()) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameOutlineWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle("") legend.setLegendFilterByMapEnabled(True) # disable auto resizing legend.setResizeToContents(False) composition.addComposerLegend(legend) legend.setComposerMap(composer_map) composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsCompositionChecker("composer_legend_noresize", composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, "control_images", "expected_composermap", "composermap_landsat_overview.png") testResult = checker.testComposition("Composer map overview", self.mComposition, myPngPath) self.mComposition.removeComposerItem(overviewMap) assert testResult[0] == True
def testResizeWithMapContent(self): """Test test legend resizes to match map content""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) s.setCrsTransformEnabled(False) composition = QgsComposition(s) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameOutlineWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) composition.addComposerLegend(legend) legend.setComposerMap(composer_map) composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsCompositionChecker( 'composer_legend_size_content', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testGridNorth(self): """Test syncing picture to grid north""" composition = QgsComposition(QgsProject.instance()) composerMap = QgsComposerMap(composition) composerMap.setNewExtent(QgsRectangle(0, -256, 256, 0)) composition.addComposerMap(composerMap) composerPicture = QgsComposerPicture(composition) composition.addComposerPicture(composerPicture) composerPicture.setRotationMap(composerMap.id()) self.assertTrue(composerPicture.rotationMap() >= 0) composerPicture.setNorthMode(QgsComposerPicture.GridNorth) composerMap.setMapRotation(45) self.assertEqual(composerPicture.pictureRotation(), 45) # add an offset composerPicture.setNorthOffset(-10) self.assertEqual(composerPicture.pictureRotation(), 35)
class TestComposerBase(TestQgsPalLabeling): layer = None """:type: QgsVectorLayer""" @classmethod def setUpClass(cls): if not cls._BaseSetup: TestQgsPalLabeling.setUpClass() # the blue background (set via layer style) to match renderchecker's TestQgsPalLabeling.loadFeatureLayer('background', True) cls._TestKind = 0 # OutputKind.(Img|Svg|Pdf) @classmethod def tearDownClass(cls): """Run after all tests""" TestQgsPalLabeling.tearDownClass() cls.removeMapLayer(cls.layer) cls.layer = None def setUp(self): """Run before each test.""" super(TestComposerBase, self).setUp() self._TestImage = '' # ensure per test map settings stay encapsulated self._TestMapSettings = self.cloneMapSettings(self._MapSettings) self._Mismatch = 0 self._ColorTol = 0 self._Mismatches.clear() self._ColorTols.clear() def _set_up_composition(self, width, height, dpi): # set up composition and add map self._c = QgsComposition(self._TestMapSettings, QgsProject.instance()) """:type: QgsComposition""" # self._c.setUseAdvancedEffects(False) self._c.setPrintResolution(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi self._c.setPaperSize(paperw, paperh) # NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10) """:type: QgsComposerMap""" self._cmap.setPreviewMode(QgsComposerMap.Render) self._cmap.setFrameEnabled(False) self._c.addComposerMap(self._cmap) # now expand map to fill page and set its extent self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setNewExtent(self.aoiExtent()) # self._cmap.updateCachedImage() self._c.setPlotStyle(QgsComposition.Print) # noinspection PyUnusedLocal def _get_composer_image(self, width, height, dpi): image = QImage(QSize(width, height), self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) self._c.renderPage(p, 0) p.end() # image = self._c.printPageAsRaster(0) # """:type: QImage""" if image.isNull(): return False, '' filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' return res, filepath def _get_composer_svg_image(self, width, height, dpi): # from qgscomposer.cpp, QgsComposer::on_mActionExportAsSVG_triggered, # near end of function svgpath = getTempfilePath('svg') temp_size = os.path.getsize(svgpath) svg_g = QSvgGenerator() # noinspection PyArgumentList svg_g.setTitle(QgsProject.instance().title()) svg_g.setFileName(svgpath) svg_g.setSize(QSize(width, height)) svg_g.setViewBox(QRect(0, 0, width, height)) svg_g.setResolution(dpi) sp = QPainter(svg_g) self._c.renderPage(sp, 0) sp.end() if temp_size == os.path.getsize(svgpath): return False, '' image = QImage(width, height, self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) svgr = QSvgRenderer(svgpath) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) p.setRenderHint(QPainter.TextAntialiasing) svgr.render(p) p.end() filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' # TODO: remove .svg file as well? return res, filepath def _get_composer_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize(QSizeF(self._c.paperWidth(), self._c.paperHeight()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.printResolution()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) self._c.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0] ) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_composer_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_composer_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath def get_composer_output(self, kind): ms = self._TestMapSettings osize = ms.outputSize() width, height, dpi = osize.width(), osize.height(), ms.outputDpi() self._set_up_composition(width, height, dpi) if kind == OutputKind.Svg: return self._get_composer_svg_image(width, height, dpi) elif kind == OutputKind.Pdf: return self._get_composer_pdf_image(width, height, dpi) else: # OutputKind.Img return self._get_composer_image(width, height, dpi) # noinspection PyUnusedLocal def checkTest(self, **kwargs): self.lyr.writeToLayer(self.layer) ms = self._MapSettings # class settings settings_type = 'Class' if self._TestMapSettings is not None: ms = self._TestMapSettings # per test settings settings_type = 'Test' if 'PAL_VERBOSE' in os.environ: qDebug('MapSettings type: {0}'.format(settings_type)) qDebug(mapSettingsString(ms)) res_m, self._TestImage = self.get_composer_output(self._TestKind) self.assertTrue(res_m, 'Failed to retrieve/save output from composer') self.saveControlImage(self._TestImage) mismatch = 0 if 'PAL_NO_MISMATCH' not in os.environ: # some mismatch expected mismatch = self._Mismatch if self._Mismatch else 20 if self._TestGroup in self._Mismatches: mismatch = self._Mismatches[self._TestGroup] colortol = 0 if 'PAL_NO_COLORTOL' not in os.environ: colortol = self._ColorTol if self._ColorTol else 0 if self._TestGroup in self._ColorTols: colortol = self._ColorTols[self._TestGroup] self.assertTrue(*self.renderCheck(mismatch=mismatch, colortol=colortol, imgpath=self._TestImage))
def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() tmppath = tempfile.mkdtemp() for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')): shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath) vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp") mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr") QgsProject.instance().addMapLayers([mVectorLayer]) self.layers = [mVectorLayer] # create composition with composer map # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid(2154) QgsProject.instance().setCrs(crs) self.mComposition = QgsComposition(QgsProject.instance()) self.mComposition.setPaperSize(297, 210) # fix the renderer, fill with green props = {"color": "0,127,0"} fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) mVectorLayer.setRenderer(renderer) # the atlas map self.mAtlasMap = QgsComposerMap(self.mComposition, 20, 20, 130, 130) self.mAtlasMap.setFrameEnabled(True) self.mAtlasMap.setLayers([mVectorLayer]) self.mComposition.addComposerMap(self.mAtlasMap) # the atlas self.mAtlas = self.mComposition.atlasComposition() self.mAtlas.setCoverageLayer(mVectorLayer) self.mAtlas.setEnabled(True) self.mComposition.setAtlasMode(QgsComposition.ExportAtlas) # an overview self.mOverview = QgsComposerMap(self.mComposition, 180, 20, 50, 50) self.mOverview.setFrameEnabled(True) self.mOverview.overview().setFrameMap(self.mAtlasMap.id()) self.mOverview.setLayers([mVectorLayer]) self.mComposition.addComposerMap(self.mOverview) nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887) self.mOverview.setNewExtent(nextent) # set the fill symbol of the overview map props2 = {"color": "127,0,0,127"} fillSymbol2 = QgsFillSymbol.createSimple(props2) self.mOverview.overview().setFrameSymbol(fillSymbol2) # header label self.mLabel1 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel1) self.mLabel1.setText("[% \"NAME_1\" %] area") self.mLabel1.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel1.adjustSizeToText() self.mLabel1.setSceneRect(QRectF(150, 5, 60, 15)) qWarning( "header label font: %s exactMatch:%s" % (self.mLabel1.font().toString(), self.mLabel1.font().exactMatch())) # feature number label self.mLabel2 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel2) self.mLabel2.setText("# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]") self.mLabel2.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel2.adjustSizeToText() self.mLabel2.setSceneRect(QRectF(150, 200, 60, 15)) qWarning("feature number label font: %s exactMatch:%s" % ( self.mLabel2.font().toString(), self.mLabel2.font().exactMatch())) self.filename_test() self.autoscale_render_test() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test() self.legend_test() shutil.rmtree(tmppath, True)
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]
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())
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # create composition with composer map self.mMapSettings = QgsMapSettings() crs = QgsCoordinateReferenceSystem(32633) self.mMapSettings.setDestinationCrs(crs) 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.setBackgroundColor(QColor(150, 100, 100)) self.mComposition.addComposerMap(self.mComposerMap) def testGrid(self): """Test that we can create a grid for a map.""" myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setAnnotationEnabled(True) self.mComposerMap.grid().setGridLineColor(QColor(0, 255, 0)) self.mComposerMap.grid().setGridLineWidth(0.5) self.mComposerMap.grid().setAnnotationFont(QgsFontUtils.getStandardTestFont()) self.mComposerMap.grid().setAnnotationPrecision(0) self.mComposerMap.grid().setAnnotationDisplay(QgsComposerMapGrid.HideAll, QgsComposerMapGrid.Left) self.mComposerMap.grid().setAnnotationPosition(QgsComposerMapGrid.OutsideMapFrame, QgsComposerMapGrid.Right) self.mComposerMap.grid().setAnnotationDisplay(QgsComposerMapGrid.HideAll, QgsComposerMapGrid.Top) self.mComposerMap.grid().setAnnotationPosition(QgsComposerMapGrid.OutsideMapFrame, QgsComposerMapGrid.Bottom) self.mComposerMap.grid().setAnnotationDirection(QgsComposerMapGrid.Horizontal, QgsComposerMapGrid.Right) self.mComposerMap.grid().setAnnotationDirection(QgsComposerMapGrid.Horizontal, QgsComposerMapGrid.Bottom) self.mComposerMap.grid().setAnnotationFontColor(QColor(255, 0, 0, 150)) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_Overlay) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_grid', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition() self.mComposerMap.grid().setEnabled(False) self.mComposerMap.grid().setAnnotationEnabled(False) assert myTestResult, myMessage def testCrossGrid(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setStyle(QgsComposerMapGrid.Cross) self.mComposerMap.grid().setCrossLength(2.0) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setAnnotationEnabled(False) self.mComposerMap.grid().setGridLineColor(QColor(0, 255, 0)) self.mComposerMap.grid().setGridLineWidth(0.5) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_crossgrid', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition() self.mComposerMap.grid().setStyle(QgsComposerMapGrid.Solid) self.mComposerMap.grid().setEnabled(False) self.mComposerMap.grid().setAnnotationEnabled(False) assert myTestResult, myMessage def testMarkerGrid(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setStyle(QgsComposerMapGrid.Markers) self.mComposerMap.grid().setCrossLength(2.0) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setAnnotationEnabled(False) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_markergrid', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition() self.mComposerMap.grid().setStyle(QgsComposerMapGrid.Solid) self.mComposerMap.grid().setEnabled(False) self.mComposerMap.grid().setAnnotationEnabled(False) assert myTestResult, myMessage def testFrameOnly(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setStyle(QgsComposerMapGrid.FrameAnnotationsOnly) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setAnnotationEnabled(False) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) self.mComposerMap.grid().setFramePenSize(0.5) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_gridframeonly', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition() self.mComposerMap.grid().setStyle(QgsComposerMapGrid.Solid) self.mComposerMap.grid().setEnabled(False) self.mComposerMap.grid().setAnnotationEnabled(False) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.NoFrame) assert myTestResult, myMessage def testZebraStyle(self): self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setGridLineColor(QColor(0, 0, 0)) self.mComposerMap.grid().setAnnotationFontColor(QColor(0, 0, 0)) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) self.mComposerMap.grid().setFrameWidth(10) self.mComposerMap.grid().setFramePenSize(1) self.mComposerMap.grid().setGridLineWidth(0.5) self.mComposerMap.grid().setFramePenColor(QColor(255, 100, 0, 200)) self.mComposerMap.grid().setFrameFillColor1(QColor(50, 90, 50, 100)) self.mComposerMap.grid().setFrameFillColor2(QColor(200, 220, 100, 60)) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_zebrastyle', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition(0, 100) assert myTestResult, myMessage def testZebraStyleSides(self): self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setGridLineColor(QColor(0, 0, 0)) self.mComposerMap.grid().setAnnotationFontColor(QColor(0, 0, 0)) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) self.mComposerMap.grid().setFrameWidth(10) self.mComposerMap.grid().setFramePenSize(1) self.mComposerMap.grid().setGridLineWidth(0.5) self.mComposerMap.grid().setFramePenColor(QColor(0, 0, 0)) self.mComposerMap.grid().setFrameFillColor1(QColor(0, 0, 0)) self.mComposerMap.grid().setFrameFillColor2(QColor(255, 255, 255)) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameLeft, True) self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameRight, False) self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameTop, False) self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameBottom, False) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_zebrastyle_left', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition(0, 100) assert myTestResult, myMessage self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameTop, True) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_zebrastyle_lefttop', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition(0, 100) assert myTestResult, myMessage self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameRight, True) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_zebrastyle_lefttopright', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition(0, 100) assert myTestResult, myMessage self.mComposerMap.grid().setFrameSideFlag(QgsComposerMapGrid.FrameBottom, True) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.NoFrame) def testInteriorTicks(self): self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.Zebra) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.grid().setIntervalX(2000) self.mComposerMap.grid().setIntervalY(2000) self.mComposerMap.grid().setAnnotationFontColor(QColor(0, 0, 0)) self.mComposerMap.grid().setBlendMode(QPainter.CompositionMode_SourceOver) self.mComposerMap.grid().setFrameStyle(QgsComposerMapGrid.InteriorTicks) self.mComposerMap.grid().setFrameWidth(10) self.mComposerMap.grid().setFramePenSize(1) self.mComposerMap.grid().setFramePenColor(QColor(0, 0, 0)) self.mComposerMap.grid().setEnabled(True) self.mComposerMap.grid().setStyle(QgsComposerMapGrid.FrameAnnotationsOnly) self.mComposerMap.updateBoundingRect() checker = QgsCompositionChecker('composermap_interiorticks', self.mComposition) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testComposition(0, 100) assert myTestResult, myMessage
class TestQgsComposerMap(TestCase): 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 testGrid(self): """Test that we can create a grid for a map.""" myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.setGridEnabled(True) self.mComposerMap.setGridIntervalX(2000) self.mComposerMap.setGridIntervalY(2000) self.mComposerMap.setShowGridAnnotation(True) self.mComposerMap.setGridPenWidth(0.5) self.mComposerMap.setGridAnnotationPrecision(0) self.mComposerMap.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Left) self.mComposerMap.setGridAnnotationPosition( QgsComposerMap.OutsideMapFrame, QgsComposerMap.Right) self.mComposerMap.setGridAnnotationPosition(QgsComposerMap.Disabled, QgsComposerMap.Top) self.mComposerMap.setGridAnnotationPosition( QgsComposerMap.OutsideMapFrame, QgsComposerMap.Bottom) self.mComposerMap.setGridAnnotationDirection(QgsComposerMap.Horizontal, QgsComposerMap.Right) self.mComposerMap.setGridAnnotationDirection(QgsComposerMap.Horizontal, QgsComposerMap.Bottom) checker = QgsCompositionChecker() myPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_landsat_grid.png') myTestResult, myMessage = checker.testComposition('Composer map grid', self.mComposition, myPath) self.mComposerMap.setGridEnabled(False) self.mComposerMap.setShowGridAnnotation(False) assert myTestResult == True, myMessage def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_landsat_overview.png') myTestResult, myMessage = checker.testComposition( 'Composer map overview', self.mComposition, myPngPath) self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage def testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_landsat_overview_blend.png') myTestResult, myMessage = checker.testComposition( 'Composer map overview blending', self.mComposition, myPngPath) self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(781662.375, 3339523.125, 793062.375, 3350923.125) overviewMap.setNewExtent(myRectangle2) overviewMap.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(True) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_landsat_overview_invert.png') myTestResult, myMessage = checker.testComposition( 'Composer map overview inverted', self.mComposition, myPngPath) self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage # Fails because addItemsFromXML has been commented out in sip @expectedFailure def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXML(documentElement, doc) self.mComposition.addItemsFromXML(documentElement, doc, 0, False) #test if both composer maps have different ids newMap = QgsComposerMap() 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 testZebraStyle(self): self.mComposerMap.setGridFrameStyle(QgsComposerMap.Zebra) myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) self.mComposerMap.setNewExtent( myRectangle ) self.mComposerMap.setGridEnabled(True) self.mComposerMap.setGridIntervalX(2000) self.mComposerMap.setGridIntervalY(2000) checker = QgsCompositionChecker() myPngPath = os.path.join(TEST_DATA_DIR, 'control_images', 'expected_composermap', 'composermap_zebra_style.png') testResult, myMessage = checker.testComposition('Composer map zebra', self.mComposition, myPngPath) assert testResult == True, myMessage
def draw_map(self, top_offset): """Add a map to the composition and return the composer map instance. :param top_offset: Vertical offset at which the logo should be drawn. :type top_offset: int :returns: The composer map. :rtype: QgsComposerMap """ LOGGER.debug('InaSAFE Map drawMap called') myMapWidth = self.mapWidth myComposerMap = QgsComposerMap( self.composition, self.pageMargin, top_offset, myMapWidth, self.mapHeight) #myExtent = self.iface.mapCanvas().extent() # The dimensions of the map canvas and the print composer map may # differ. So we set the map composer extent using the canvas and # then defer to the map canvas's map extents thereafter # Update: disabled as it results in a rectangular rather than # square map #myComposerMap.setNewExtent(myExtent) myComposerExtent = myComposerMap.extent() # Recenter the composer map on the center of the canvas # Note that since the composer map is square and the canvas may be # arbitrarily shaped, we center based on the longest edge myCanvasExtent = self.iface.mapCanvas().extent() myWidth = myCanvasExtent.width() myHeight = myCanvasExtent.height() myLongestLength = myWidth if myWidth < myHeight: myLongestLength = myHeight myHalfLength = myLongestLength / 2 myCenter = myCanvasExtent.center() myMinX = myCenter.x() - myHalfLength myMaxX = myCenter.x() + myHalfLength myMinY = myCenter.y() - myHalfLength myMaxY = myCenter.y() + myHalfLength mySquareExtent = QgsRectangle(myMinX, myMinY, myMaxX, myMaxY) myComposerMap.setNewExtent(mySquareExtent) myComposerMap.setGridEnabled(True) myNumberOfSplits = 5 # .. todo:: Write logic to adjust precision so that adjacent tick marks # always have different displayed values myPrecision = 2 myXInterval = myComposerExtent.width() / myNumberOfSplits myComposerMap.setGridIntervalX(myXInterval) myYInterval = myComposerExtent.height() / myNumberOfSplits myComposerMap.setGridIntervalY(myYInterval) myComposerMap.setGridStyle(QgsComposerMap.Cross) myCrossLengthMM = 1 myComposerMap.setCrossLength(myCrossLengthMM) myComposerMap.setZValue(0) # To ensure it does not overlay logo myFontSize = 6 myFontWeight = QtGui.QFont.Normal myItalicsFlag = False myFont = QtGui.QFont( 'verdana', myFontSize, myFontWeight, myItalicsFlag) myComposerMap.setGridAnnotationFont(myFont) myComposerMap.setGridAnnotationPrecision(myPrecision) myComposerMap.setShowGridAnnotation(True) myComposerMap.setGridAnnotationDirection( QgsComposerMap.BoundaryDirection, QgsComposerMap.Top) self.composition.addItem(myComposerMap) self.draw_graticule_mask(top_offset) return myComposerMap
def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() vectorFileInfo = QFileInfo( self.TEST_DATA_DIR + "/france_parts.shp") mVectorLayer = QgsVectorLayer( vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr" ) QgsMapLayerRegistry.instance().addMapLayers( [mVectorLayer] ) # create composition with composer map mMapRenderer = QgsMapRenderer() layerStringList = [] layerStringList.append( mVectorLayer.id() ) mMapRenderer.setLayerSet( layerStringList ) mMapRenderer.setProjectionsEnabled( True ) mMapRenderer.setMapUnits( QGis.Meters ) # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid( 2154 ) mMapRenderer.setDestinationCrs( crs ) self.mComposition = QgsComposition( mMapRenderer ) self.mComposition.setPaperSize( 297, 210 ) # fix the renderer, fill with green props = { "color": "0,127,0" } fillSymbol = QgsFillSymbolV2.createSimple( props ) renderer = QgsSingleSymbolRendererV2( fillSymbol ) mVectorLayer.setRendererV2( renderer ) # the atlas map self.mAtlasMap = QgsComposerMap( self.mComposition, 20, 20, 130, 130 ) self.mAtlasMap.setFrameEnabled( True ) self.mComposition.addComposerMap( self.mAtlasMap ) # the atlas self.mAtlas = self.mComposition.atlasComposition() self.mAtlas.setCoverageLayer( mVectorLayer ) self.mAtlas.setEnabled( True ) self.mComposition.setAtlasMode( QgsComposition.ExportAtlas ) # an overview mOverview = QgsComposerMap( self.mComposition, 180, 20, 50, 50 ) mOverview.setFrameEnabled( True ) mOverview.setOverviewFrameMap( self.mAtlasMap.id() ) self.mComposition.addComposerMap( mOverview ) nextent = QgsRectangle( 49670.718, 6415139.086, 699672.519, 7065140.887 ) mOverview.setNewExtent( nextent ) # set the fill symbol of the overview map props2 = { "color": "127,0,0,127" } fillSymbol2 = QgsFillSymbolV2.createSimple( props2 ) mOverview.setOverviewFrameMapSymbol( fillSymbol2 ) # header label self.mLabel1 = QgsComposerLabel( self.mComposition ) self.mComposition.addComposerLabel( self.mLabel1 ) self.mLabel1.setText( "[% \"NAME_1\" %] area" ) self.mLabel1.setFont( QgsFontUtils.getStandardTestFont() ) self.mLabel1.adjustSizeToText() self.mLabel1.setSceneRect( QRectF( 150, 5, 60, 15 ) ) qWarning( "header label font: %s exactMatch:%s" % ( self.mLabel1.font().toString(), self.mLabel1.font().exactMatch() ) ) # feature number label self.mLabel2 = QgsComposerLabel( self.mComposition ) self.mComposition.addComposerLabel( self.mLabel2 ) self.mLabel2.setText( "# [%$feature || ' / ' || $numfeatures%]" ) self.mLabel2.setFont( QgsFontUtils.getStandardTestFont() ) self.mLabel2.adjustSizeToText() self.mLabel2.setSceneRect( QRectF( 150, 200, 60, 15 ) ) qWarning( "feature number label font: %s exactMatch:%s" % ( self.mLabel2.font().toString(), self.mLabel2.font().exactMatch() ) ) self.filename_test() self.autoscale_render_test() self.autoscale_render_test_old_api() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test()
class TestQgsAtlasComposition(unittest.TestCase): def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() tmppath = tempfile.mkdtemp() for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')): shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath) vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp") mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr") QgsMapLayerRegistry.instance().addMapLayers([mVectorLayer]) # create composition with composer map self.mapSettings = QgsMapSettings() layerStringList = [] layerStringList.append(mVectorLayer.id()) self.mapSettings.setLayers(layerStringList) self.mapSettings.setCrsTransformEnabled(True) self.mapSettings.setMapUnits(QGis.Meters) # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid(2154) self.mapSettings.setDestinationCrs(crs) self.mComposition = QgsComposition(self.mapSettings) self.mComposition.setPaperSize(297, 210) # fix the renderer, fill with green props = {"color": "0,127,0"} fillSymbol = QgsFillSymbolV2.createSimple(props) renderer = QgsSingleSymbolRendererV2(fillSymbol) mVectorLayer.setRendererV2(renderer) # the atlas map self.mAtlasMap = QgsComposerMap(self.mComposition, 20, 20, 130, 130) self.mAtlasMap.setFrameEnabled(True) self.mComposition.addComposerMap(self.mAtlasMap) # the atlas self.mAtlas = self.mComposition.atlasComposition() self.mAtlas.setCoverageLayer(mVectorLayer) self.mAtlas.setEnabled(True) self.mComposition.setAtlasMode(QgsComposition.ExportAtlas) # an overview mOverview = QgsComposerMap(self.mComposition, 180, 20, 50, 50) mOverview.setFrameEnabled(True) mOverview.setOverviewFrameMap(self.mAtlasMap.id()) self.mComposition.addComposerMap(mOverview) nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887) mOverview.setNewExtent(nextent) # set the fill symbol of the overview map props2 = {"color": "127,0,0,127"} fillSymbol2 = QgsFillSymbolV2.createSimple(props2) mOverview.setOverviewFrameMapSymbol(fillSymbol2) # header label self.mLabel1 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel1) self.mLabel1.setText("[% \"NAME_1\" %] area") self.mLabel1.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel1.adjustSizeToText() self.mLabel1.setSceneRect(QRectF(150, 5, 60, 15)) qWarning( "header label font: %s exactMatch:%s" % (self.mLabel1.font().toString(), self.mLabel1.font().exactMatch())) # feature number label self.mLabel2 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel2) self.mLabel2.setText("# [%$feature || ' / ' || $numfeatures%]") self.mLabel2.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel2.adjustSizeToText() self.mLabel2.setSceneRect(QRectF(150, 200, 60, 15)) qWarning("feature number label font: %s exactMatch:%s" % ( self.mLabel2.font().toString(), self.mLabel2.font().exactMatch())) self.filename_test() self.autoscale_render_test() self.autoscale_render_test_old_api() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test() self.legend_test() shutil.rmtree(tmppath, True) def filename_test(self): self.mAtlas.setFilenamePattern("'output_' || $feature") self.mAtlas.beginRender() for i in range(0, self.mAtlas.numFeatures()): self.mAtlas.prepareForFeature(i) expected = "output_%d" % (i + 1) assert self.mAtlas.currentFilename() == expected self.mAtlas.endRender() def autoscale_render_test(self): self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Auto) self.mAtlasMap.setAtlasMargin(0.10) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_autoscale%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() self.mAtlasMap.setAtlasDriven(False) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Fixed) self.mAtlasMap.setAtlasMargin(0) def autoscale_render_test_old_api(self): self.mAtlas.setComposerMap(self.mAtlasMap) self.mAtlas.setFixedScale(False) self.mAtlas.setMargin(0.10) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_autoscale_old_api%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() self.mAtlas.setFixedScale(True) self.mAtlas.setMargin(0) self.mAtlas.setComposerMap(None) self.mAtlasMap.setAtlasDriven(False) def fixedscale_render_test(self): self.mAtlasMap.setNewExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620)) self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Fixed) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_fixedscale%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def predefinedscales_render_test(self): self.mAtlasMap.setNewExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620)) self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Predefined) scales = [1800000, 5000000] self.mAtlas.setPredefinedScales(scales) for i, s in enumerate(self.mAtlas.predefinedScales()): assert s == scales[i] self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_predefinedscales%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def hidden_render_test(self): self.mAtlasMap.setNewExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620)) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Fixed) self.mAtlas.setHideCoverage(True) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_hiding%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() self.mAtlas.setHideCoverage(False) def sorting_render_test(self): self.mAtlasMap.setNewExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620)) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Fixed) self.mAtlas.setHideCoverage(False) self.mAtlas.setSortFeatures(True) self.mAtlas.setSortKeyAttributeIndex(4) # departement name self.mAtlas.setSortAscending(False) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_sorting%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def filtering_render_test(self): self.mAtlasMap.setNewExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620)) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Fixed) self.mAtlas.setHideCoverage(False) self.mAtlas.setSortFeatures(False) self.mAtlas.setFilterFeatures(True) self.mAtlas.setFeatureFilter("substr(NAME_1,1,1)='P'") # select only 'Pays de la loire' self.mAtlas.beginRender() for i in range(0, 1): self.mAtlas.prepareForFeature(i) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_filtering%d' % (i + 1), self.mComposition) checker.setControlPathPrefix("atlas") myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def legend_test(self): self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Auto) self.mAtlasMap.setAtlasMargin(0.10) # add a point layer ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory") pr = ptLayer.dataProvider() f1 = QgsFeature(1) f1.initAttributes(2) f1.setAttribute(0, 1) f1.setAttribute(1, "Test label 1") f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(-0.638, 48.954))) f2 = QgsFeature(2) f2.initAttributes(2) f2.setAttribute(0, 2) f2.setAttribute(1, "Test label 2") f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(-1.682, 48.550))) pr.addFeatures([f1, f2]) # categorized symbology r = QgsCategorizedSymbolRendererV2("attr", [QgsRendererCategoryV2(1, QgsMarkerSymbolV2.createSimple({"color": "255,0,0"}), "red"), QgsRendererCategoryV2(2, QgsMarkerSymbolV2.createSimple({"color": "0,0,255"}), "blue")]) ptLayer.setRendererV2(r) QgsMapLayerRegistry.instance().addMapLayer(ptLayer) # add the point layer to the map settings layers = self.mapSettings.layers() layers = [ptLayer.id()] + layers self.mapSettings.setLayers(layers) # add a legend legend = QgsComposerLegend(self.mComposition) legend.moveBy(200, 100) # sets the legend filter parameter legend.setComposerMap(self.mAtlasMap) legend.setLegendFilterOutAtlas(True) self.mComposition.addComposerLegend(legend) self.mAtlas.beginRender() self.mAtlas.prepareForFeature(0) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_legend', self.mComposition) myTestResult, myMessage = checker.testComposition() assert myTestResult self.mAtlas.endRender() # restore state self.mapSettings.setLayers([layers[1]]) self.mComposition.removeComposerItem(legend) QgsMapLayerRegistry.instance().removeMapLayer(ptLayer.id())
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) 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 testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) 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) 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) 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) 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 # Fails because addItemsFromXml has been commented out in sip @unittest.expectedFailure def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement("ComposerItemClipboard") self.mComposition.writeXml(documentElement, doc) self.mComposition.addItemsFromXml(documentElement, doc, 0, False) # test if both composer maps have different ids newMap = QgsComposerMap() 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.setWorldFileMap(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, 1e03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
class TestQgsAtlasComposition(unittest.TestCase): def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() vectorFileInfo = QFileInfo( self.TEST_DATA_DIR + "/france_parts.shp") mVectorLayer = QgsVectorLayer( vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr" ) QgsMapLayerRegistry.instance().addMapLayers( [mVectorLayer] ) # create composition with composer map mMapRenderer = QgsMapRenderer() layerStringList = [] layerStringList.append( mVectorLayer.id() ) mMapRenderer.setLayerSet( layerStringList ) mMapRenderer.setProjectionsEnabled( True ) mMapRenderer.setMapUnits( QGis.Meters ) # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid( 2154 ) mMapRenderer.setDestinationCrs( crs ) self.mComposition = QgsComposition( mMapRenderer ) self.mComposition.setPaperSize( 297, 210 ) # fix the renderer, fill with green props = { "color": "0,127,0" } fillSymbol = QgsFillSymbolV2.createSimple( props ) renderer = QgsSingleSymbolRendererV2( fillSymbol ) mVectorLayer.setRendererV2( renderer ) # the atlas map self.mAtlasMap = QgsComposerMap( self.mComposition, 20, 20, 130, 130 ) self.mAtlasMap.setFrameEnabled( True ) self.mComposition.addComposerMap( self.mAtlasMap ) # the atlas self.mAtlas = self.mComposition.atlasComposition() self.mAtlas.setCoverageLayer( mVectorLayer ) self.mAtlas.setEnabled( True ) self.mComposition.setAtlasMode( QgsComposition.ExportAtlas ) # an overview mOverview = QgsComposerMap( self.mComposition, 180, 20, 50, 50 ) mOverview.setFrameEnabled( True ) mOverview.setOverviewFrameMap( self.mAtlasMap.id() ) self.mComposition.addComposerMap( mOverview ) nextent = QgsRectangle( 49670.718, 6415139.086, 699672.519, 7065140.887 ) mOverview.setNewExtent( nextent ) # set the fill symbol of the overview map props2 = { "color": "127,0,0,127" } fillSymbol2 = QgsFillSymbolV2.createSimple( props2 ) mOverview.setOverviewFrameMapSymbol( fillSymbol2 ) # header label self.mLabel1 = QgsComposerLabel( self.mComposition ) self.mComposition.addComposerLabel( self.mLabel1 ) self.mLabel1.setText( "[% \"NAME_1\" %] area" ) self.mLabel1.setFont( QgsFontUtils.getStandardTestFont() ) self.mLabel1.adjustSizeToText() self.mLabel1.setSceneRect( QRectF( 150, 5, 60, 15 ) ) qWarning( "header label font: %s exactMatch:%s" % ( self.mLabel1.font().toString(), self.mLabel1.font().exactMatch() ) ) # feature number label self.mLabel2 = QgsComposerLabel( self.mComposition ) self.mComposition.addComposerLabel( self.mLabel2 ) self.mLabel2.setText( "# [%$feature || ' / ' || $numfeatures%]" ) self.mLabel2.setFont( QgsFontUtils.getStandardTestFont() ) self.mLabel2.adjustSizeToText() self.mLabel2.setSceneRect( QRectF( 150, 200, 60, 15 ) ) qWarning( "feature number label font: %s exactMatch:%s" % ( self.mLabel2.font().toString(), self.mLabel2.font().exactMatch() ) ) self.filename_test() self.autoscale_render_test() self.autoscale_render_test_old_api() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test() def filename_test( self ): self.mAtlas.setFilenamePattern( "'output_' || $feature" ) self.mAtlas.beginRender() for i in range(0, self.mAtlas.numFeatures()): self.mAtlas.prepareForFeature( i ) expected = "output_%d" % (i+1) assert self.mAtlas.currentFilename() == expected self.mAtlas.endRender() def autoscale_render_test( self ): self.mAtlasMap.setAtlasDriven( True ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Auto ) self.mAtlasMap.setAtlasMargin( 0.10 ) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_autoscale%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() self.mAtlasMap.setAtlasDriven( False ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Fixed ) self.mAtlasMap.setAtlasMargin( 0 ) def autoscale_render_test_old_api( self ): self.mAtlas.setComposerMap( self.mAtlasMap ) self.mAtlas.setFixedScale( False ) self.mAtlas.setMargin( 0.10 ) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_autoscale_old_api%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() self.mAtlas.setFixedScale( True ) self.mAtlas.setMargin( 0 ) self.mAtlas.setComposerMap( None ) self.mAtlasMap.setAtlasDriven( False ) def fixedscale_render_test( self ): self.mAtlasMap.setAtlasDriven( True ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Fixed ) self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_fixedscale%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def predefinedscales_render_test( self ): self.mAtlasMap.setAtlasDriven( True ) self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Predefined ) scales = [1800000, 5000000] self.mAtlas.setPredefinedScales( scales ) for i, s in enumerate(self.mAtlas.predefinedScales()): assert s == scales[i] self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_predefinedscales%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def hidden_render_test( self ): self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Fixed ) self.mAtlas.setHideCoverage( True ) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_hiding%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def sorting_render_test( self ): self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Fixed ) self.mAtlas.setHideCoverage( False ) self.mAtlas.setSortFeatures( True ) self.mAtlas.setSortKeyAttributeIndex( 4 ) # departement name self.mAtlas.setSortAscending( False ) self.mAtlas.beginRender() for i in range(0, 2): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_sorting%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender() def filtering_render_test( self ): self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ) self.mAtlasMap.setAtlasScalingMode( QgsComposerMap.Fixed ) self.mAtlas.setHideCoverage( False ) self.mAtlas.setSortFeatures( False ) self.mAtlas.setFilterFeatures( True ) self.mAtlas.setFeatureFilter( "substr(NAME_1,1,1)='P'" ) # select only 'Pays de la loire' self.mAtlas.beginRender() for i in range(0, 1): self.mAtlas.prepareForFeature( i ) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_filtering%d' % (i + 1), self.mComposition) myTestResult, myMessage = checker.testComposition(0, 200) assert myTestResult self.mAtlas.endRender()
class TestComposerBase(TestQgsPalLabeling): layer = None """:type: QgsVectorLayer""" @classmethod def setUpClass(cls): if not cls._BaseSetup: TestQgsPalLabeling.setUpClass() # the blue background (set via layer style) to match renderchecker's TestQgsPalLabeling.loadFeatureLayer('background', True) cls._TestKind = 0 # OutputKind.(Img|Svg|Pdf) @classmethod def tearDownClass(cls): """Run after all tests""" TestQgsPalLabeling.tearDownClass() cls.removeMapLayer(cls.layer) cls.layer = None def setUp(self): """Run before each test.""" super(TestComposerBase, self).setUp() self._TestImage = '' # ensure per test map settings stay encapsulated self._TestMapSettings = self.cloneMapSettings(self._MapSettings) self._Mismatch = 0 self._ColorTol = 0 self._Mismatches.clear() self._ColorTols.clear() def _set_up_composition(self, width, height, dpi): # set up composition and add map self._c = QgsComposition(QgsProject.instance()) """:type: QgsComposition""" # self._c.setUseAdvancedEffects(False) self._c.setPrintResolution(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi self._c.setPaperSize(paperw, paperh) # NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10) """:type: QgsComposerMap""" self._cmap.setPreviewMode(QgsComposerMap.Render) self._cmap.setFrameEnabled(False) self._cmap.setLayers(self._TestMapSettings.layers()) self._c.addComposerMap(self._cmap) # now expand map to fill page and set its extent self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setNewExtent(self.aoiExtent()) # self._cmap.updateCachedImage() self._c.setPlotStyle(QgsComposition.Print) # noinspection PyUnusedLocal def _get_composer_image(self, width, height, dpi): image = QImage(QSize(width, height), self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing)) self._c.renderPage(p, 0) p.end() # image = self._c.printPageAsRaster(0) # """:type: QImage""" if image.isNull(): return False, '' filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' return res, filepath def _get_composer_svg_image(self, width, height, dpi): # from qgscomposer.cpp, QgsComposer::on_mActionExportAsSVG_triggered, # near end of function svgpath = getTempfilePath('svg') temp_size = os.path.getsize(svgpath) svg_g = QSvgGenerator() # noinspection PyArgumentList svg_g.setTitle(QgsProject.instance().title()) svg_g.setFileName(svgpath) svg_g.setSize(QSize(width, height)) svg_g.setViewBox(QRect(0, 0, width, height)) svg_g.setResolution(dpi) sp = QPainter(svg_g) self._c.renderPage(sp, 0) sp.end() if temp_size == os.path.getsize(svgpath): return False, '' image = QImage(width, height, self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) svgr = QSvgRenderer(svgpath) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing)) p.setRenderHint(QPainter.TextAntialiasing) svgr.render(p) p.end() filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' # TODO: remove .svg file as well? return res, filepath def _get_composer_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize(QSizeF(self._c.paperWidth(), self._c.paperHeight()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.printResolution()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) self._c.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0]) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_composer_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_composer_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath def get_composer_output(self, kind): ms = self._TestMapSettings osize = ms.outputSize() width, height, dpi = osize.width(), osize.height(), ms.outputDpi() self._set_up_composition(width, height, dpi) if kind == OutputKind.Svg: return self._get_composer_svg_image(width, height, dpi) elif kind == OutputKind.Pdf: return self._get_composer_pdf_image(width, height, dpi) else: # OutputKind.Img return self._get_composer_image(width, height, dpi) # noinspection PyUnusedLocal def checkTest(self, **kwargs): self.lyr.writeToLayer(self.layer) ms = self._MapSettings # class settings settings_type = 'Class' if self._TestMapSettings is not None: ms = self._TestMapSettings # per test settings settings_type = 'Test' if 'PAL_VERBOSE' in os.environ: qDebug('MapSettings type: {0}'.format(settings_type)) qDebug(mapSettingsString(ms)) res_m, self._TestImage = self.get_composer_output(self._TestKind) self.assertTrue(res_m, 'Failed to retrieve/save output from composer') self.saveControlImage(self._TestImage) mismatch = 0 if 'PAL_NO_MISMATCH' not in os.environ: # some mismatch expected mismatch = self._Mismatch if self._Mismatch else 20 if self._TestGroup in self._Mismatches: mismatch = self._Mismatches[self._TestGroup] colortol = 0 if 'PAL_NO_COLORTOL' not in os.environ: colortol = self._ColorTol if self._ColorTol else 0 if self._TestGroup in self._ColorTols: colortol = self._ColorTols[self._TestGroup] self.assertTrue(*self.renderCheck( mismatch=mismatch, colortol=colortol, imgpath=self._TestImage))