def vectorLayerRender(self, layer, outName): img = QImage(QSize(1600, 900), QImage.Format_ARGB32_Premultiplied) color = QColor(255, 255, 255) img.fill(color.rgb()) p = QPainter() p.begin(img) p.setRenderHint(QPainter.Antialiasing) render = QgsMapRenderer() lst = [layer.id()] # add ID of every layer render.setLayerSet(lst) # set extent rect = QgsRectangle(render.fullExtent()) rect.scale(1.1) render.setExtent(rect) # set output size render.setOutputSize(img.size(), img.logicalDpiX()) # do the rendering render.render(p) p.end() # save image path = os.path.join(self.workingFolder, outName + '.tiff') img.save(path, "tiff") return path
def test_load_template(self): """Test load_template function.""" self.mock_the_dialog(test_entire_mode=False) self.impact_merge_dialog.prepare_input() self.impact_merge_dialog.validate_all_layers() # Setup Map Renderer and set all the layer renderer = QgsMapRenderer() layer_set = [self.impact_merge_dialog.first_impact['layer'].id(), self.impact_merge_dialog.second_impact['layer'].id()] # If aggregated, append chosen aggregation layer if not self.impact_merge_dialog.entire_area_mode: layer_set.append( self.impact_merge_dialog.aggregation['layer'].id()) # Set Layer set to renderer renderer.setLayerSet(layer_set) # NORMAL CASE: It can find the template # Create composition composition = self.impact_merge_dialog.load_template(renderer) # The type of this composition must be QgsComposition self.assertEqual(type(composition), QgsComposition) #FALL CASE: It cannot find the template self.impact_merge_dialog.template_path = '/it/will/fail/tmp.qpt' expected_message = 'Error loading template %s' % \ self.impact_merge_dialog.template_path with self.assertRaises(ReportCreationError) as context: self.impact_merge_dialog.load_template(renderer) self.assertEqual(context.exception.message, expected_message)
def test_load_template(self): """Test load_template function.""" self.mock_the_dialog(test_entire_mode=False) self.impact_merge_dialog.prepare_input() self.impact_merge_dialog.validate_all_layers() # Setup Map Renderer and set all the layer renderer = QgsMapRenderer() layer_set = [ self.impact_merge_dialog.first_impact['layer'].id(), self.impact_merge_dialog.second_impact['layer'].id() ] # If aggregated, append chosen aggregation layer if not self.impact_merge_dialog.entire_area_mode: layer_set.append( self.impact_merge_dialog.aggregation['layer'].id()) # Set Layer set to renderer renderer.setLayerSet(layer_set) # NORMAL CASE: It can find the template # Create composition composition = self.impact_merge_dialog.load_template(renderer) # The type of this composition must be QgsComposition self.assertEqual(type(composition), QgsComposition) #FALL CASE: It cannot find the template self.impact_merge_dialog.template_path = '/it/will/fail/tmp.qpt' expected_message = 'Error loading template %s' % \ self.impact_merge_dialog.template_path with self.assertRaises(ReportCreationError) as context: self.impact_merge_dialog.load_template(renderer) self.assertEqual(context.exception.message, expected_message)
def preview(request, layer_slug): """Home page for layers. :param request: The web request. :param layer_slug: The layer """ layer = get_object_or_404(Layer, slug=layer_slug) layer_path = os.path.join( settings.MEDIA_ROOT, 'layers', layer.slug, 'raw') map_layer = QgsVectorLayer(layer_path, layer.name, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(map_layer) layer_uri = tempfile.NamedTemporaryFile( suffix='.png', prefix='inasafe-web-', dir='/tmp/').name # create image image = QImage(QSize(100, 100), QImage.Format_ARGB32_Premultiplied) # set image's background color color = QColor(255, 255, 255) image.fill(color.rgb()) # create painter p = QPainter() p.begin(image) p.setRenderHint(QPainter.Antialiasing) renderer = QgsMapRenderer() # set layer set layers = [map_layer.id()] # add ID of every layer renderer.setLayerSet(layers) # set extent rect = QgsRectangle(renderer.fullExtent()) rect.scale(1.1) renderer.setExtent(rect) # set output size renderer.setOutputSize(image.size(), image.logicalDpiX()) # do the rendering renderer.render(p) p.end() # clean up registry_list = qgis_layers() QgsMapLayerRegistry.instance().removeMapLayer(map_layer.id()) print registry_list # save image image.save(layer_uri, 'png') with open(layer_uri, 'rb') as f: response = HttpResponse(f.read(), content_type='png') os.remove(layer_uri) return response
def save_layer_as_image(layer, extent, path_to_file, max_resolution='1024', image_type = 'tif'): """ Select and save the currently visible extent to a .tif file :param width: image width :type width: int :param height: image height :type height: int :param name: name of the created file :type name: str :return: :rtype: """ # calculate the extents width and height width = extent.width() height = extent.height() # calculate the missing value (width or height) of the output file, based on the extent if width >= height: height_as_dec = max_resolution / width * height width = max_resolution height = int(height_as_dec) else: width_as_dec = max_resolution / height * width width = int(width_as_dec) height = max_resolution # append the resolution to the filename and call the save method filename=layer.name() if filename.startswith("WMS_"): filename=filename.replace("WMS_","") else: resolution_prefix = '{}_{}-'.format(width, height) filename = resolution_prefix + layer.name() img = QImage(QSize(width, height), QImage.Format_ARGB32_Premultiplied) color = QColor(187, 187, 187, 0) img.fill(color.rgba()) leonardo = QPainter() leonardo.begin(img) leonardo.setRenderHint(QPainter.Antialiasing) renderer = QgsMapRenderer() lst = [layer.id()] renderer.setLayerSet(lst) renderer.setExtent(extent) renderer.setOutputSize(img.size(), img.logicalDpiX()) renderer.render(leonardo) leonardo.end() filename += '.{}'.format(image_type) out_path = os.path.join(path_to_file, filename) if img.save(out_path, image_type): return out_path
def testPrintMapFromTemplate(self): """Test that we can get a map to render in the template.""" myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') myFileInfo = QFileInfo(myPath) myRasterLayer = QgsRasterLayer(myFileInfo.filePath(), myFileInfo.completeBaseName()) myRenderer = QgsMultiBandColorRenderer( myRasterLayer.dataProvider(), 2, 3, 4 ) #mRasterLayer.setRenderer( rasterRenderer ) myPipe = myRasterLayer.pipe() assert myPipe.set(myRenderer), "Cannot set pipe renderer" QgsMapLayerRegistry.instance().addMapLayers([myRasterLayer]) myMapRenderer = QgsMapRenderer() myLayerStringList = [] myLayerStringList.append(myRasterLayer.id()) myMapRenderer.setLayerSet(myLayerStringList) myMapRenderer.setProjectionsEnabled(False) myComposition = QgsComposition(myMapRenderer) myFile = os.path.join(TEST_DATA_DIR, 'template-for-substitution.qpt') myTemplateFile = file(myFile, 'rt') myTemplateContent = myTemplateFile.read() myTemplateFile.close() myDocument = QDomDocument() myDocument.setContent(myTemplateContent) myComposition.loadFromTemplate(myDocument) # now render the map, first zooming to the raster extents myMap = myComposition.getComposerMapById(0) myMessage = ('Map 0 could not be found in template %s', myFile) assert myMap is not None, myMessage myExtent = myRasterLayer.extent() myMap.setNewExtent(myExtent) myImagePath = os.path.join(str(QDir.tempPath()), 'template_map_render_python.png') myPageNumber = 0 myImage = myComposition.printPageAsRaster(myPageNumber) myImage.save(myImagePath) assert os.path.exists(myImagePath), 'Map render was not created.' # Not sure if this is a predictable way to test but its quicker than # rendering. myFileSize = QFileInfo(myImagePath).size() myExpectedFileSize = 100000 myMessage = ('Expected file size to be greater than %s, got %s' ' for %s' % (myExpectedFileSize, myFileSize, myImagePath)) assert myFileSize > myExpectedFileSize, myMessage
def testPrintMapFromTemplate(self): """Test that we can get a map to render in the template.""" myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') myFileInfo = QFileInfo(myPath) myRasterLayer = QgsRasterLayer(myFileInfo.filePath(), myFileInfo.completeBaseName()) myRenderer = QgsMultiBandColorRenderer( myRasterLayer.dataProvider(), 2, 3, 4 ) #mRasterLayer.setRenderer( rasterRenderer ) myPipe = myRasterLayer.pipe() assert myPipe.set( myRenderer ), "Cannot set pipe renderer" QgsMapLayerRegistry.instance().addMapLayers([myRasterLayer]) myMapRenderer = QgsMapRenderer() myLayerStringList = [] myLayerStringList.append(myRasterLayer.id()) myMapRenderer.setLayerSet(myLayerStringList) myMapRenderer.setProjectionsEnabled(False) myComposition = QgsComposition(myMapRenderer) myFile = os.path.join(TEST_DATA_DIR, 'template-for-substitution.qpt') myTemplateFile = file(myFile, 'rt') myTemplateContent = myTemplateFile.read() myTemplateFile.close() myDocument = QDomDocument() myDocument.setContent(myTemplateContent) myComposition.loadFromTemplate(myDocument) # now render the map, first zooming to the raster extents myMap = myComposition.getComposerMapById(0) myMessage = ('Map 0 could not be found in template %s', myFile) assert myMap is not None, myMessage myExtent = myRasterLayer.extent() myMap.setNewExtent(myExtent) myImagePath = os.path.join(str(QDir.tempPath()), 'template_map_render_python.png') myPageNumber = 0 myImage = myComposition.printPageAsRaster(myPageNumber) myImage.save(myImagePath) assert os.path.exists(myImagePath), 'Map render was not created.' # Not sure if this is a predictable way to test but its quicker than # rendering. myFileSize = QFileInfo(myImagePath).size() myExpectedFileSize = 100000 myMessage = ('Expected file size to be greater than %s, got %s' ' for %s' % (myExpectedFileSize, myFileSize, myImagePath)) assert myFileSize > myExpectedFileSize, myMessage
def printToPdf(self, params): self.check_required_params(params) with change_directory(self.project_root): crs = QgsCoordinateReferenceSystem() crs.createFromSrid(params.get('srs')) mapRenderer = QgsMapRenderer() mapUnits = crs.mapUnits() mapRenderer.setMapUnits(mapUnits) mapExtent = QgsRectangle(*params.get('bbox')) mapRenderer.setExtent(mapExtent) le = QgsPalLabeling() mapRenderer.setLabelingEngine(le) layers = params.get('layers') self.setTransparencies(layers, params.get('transparencies')) mapRenderer.setLayerSet(layers) composer = ( self.getLayoutbyName(params['layout']) .firstChildElement('Composition') ) comp = QgsComposition(mapRenderer) comp.setPlotStyle(QgsComposition.Print) comp.readXML(composer, self.doc) # read composition elements comp.addItemsFromXML(composer, self.doc) comp.setPrintResolution(90) # set bbox for the first Map in the layout comp_map = comp.getComposerMapById(0) comp_map.setNewExtent(QgsRectangle(*params.get('bbox'))) # comp_map.setNewScale(10000) # comp_map.setLayerSet(layers) # comp_map.setKeepLayerSet(True) # save the file comp.exportAsPDF(params['tmpFile'] + '.pdf')
def createimage(self, extent, crs, outputsize): render = QgsMapRenderer() render.setLayerSet(self.loadedlayers.values()) render.setProjectionsEnabled(True) render.setDestinationCrs(crs) render.setExtent(extent) img = QImage(outputsize, QImage.Format_ARGB32_Premultiplied) img.fill(Qt.transparent) #needed, apparently the QImage() is not empty painter = QPainter() painter.begin(img) painter.setRenderHint(QPainter.Antialiasing) render.setOutputSize(img.size(), img.logicalDpiX()) log("about to render") render.render(painter) log("just rendered") painter.end() return img
def renderLayers(size, layers, imageFileName): imgSize = QSize(size, size) # create image img = QImage(imgSize, QImage.Format_RGB32) # set image's background color color = QColor(255, 255, 255) img.fill(color.rgb()) # create painter p = QPainter() p.begin(img) p.setRenderHint(QPainter.Antialiasing) render = QgsMapRenderer() # set layer set render.setLayerSet(layers.keys()) # set extent rect = QgsRectangle(render.fullExtent()) render.setExtent(rect) # set output size render.setOutputSize(img.size(), img.logicalDpiX()) print "render()" # do the rendering render.render(p) p.end() print " ...Done" print "save(" + imageFileName + ")" # save image img.save(imageFileName) print " ...Done"
def testCase(self): TEST_DATA_DIR = unitTestDataPath() vectorFileInfo = QFileInfo( 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( False ) mComposition = QgsComposition( mMapRenderer ) mComposition.setPaperSize( 297, 210 ) mLabel = QgsComposerLabel( mComposition ) mComposition.addComposerLabel( mLabel ) self.evaluation_test( mComposition, mLabel ) self.feature_evaluation_test( mComposition, mLabel, mVectorLayer ) self.page_evaluation_test( mComposition, mLabel, mVectorLayer )
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialisation.""" 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.mMapRenderer = QgsMapRenderer() layerStringList = [] 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 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.setOverviewFrameMap(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewBlendMode(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(False) overviewMap.setOverviewCentered(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, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
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 updateDisplay(self): ''' Add map(s) of all QF components to the canvas based on what's selected in self.lstTimes''' timestamps = [ pd.datetime.strptime(newItem.text(), '%Y-%m-%d %H:%M') for newItem in self.lstTimes.selectedItems() ] for t in timestamps: outs = pd.read_csv(self.model.getFileList()[t], header=0, index_col=0) outLayer = self.outputLayer # Make sure the output file is properly appended (this gets evaluated for non-extra-disaggregated datasets) # because I didn't set an output shapefile path properly if os.path.split(self.outputLayer)[0] == '': outLayer = os.path.join(self.model.downscaledPath, os.path.split(self.outputLayer)[1]) fileToPopulate = self.outputLayer new_layer = populateShapefileFromTemplate( outs, self.featureIdField, outLayer, int(self.outputEPSG), title=t.strftime(' %Y-%m-%d %H:%M UTC')) # Set ranges suited to all the different QF types range_minima = [0, 0.000001, 0.1, 1, 10, 100] range_maxima = [0.000001, 0.1, 1, 10, 100, 1000] colours = [ '#CECECE', '#FEE6CE', '#FDAE6B', '#F16913', '#D94801', '#7F2704' ] opacity = 1 for component in self.componentTranslation.values(): layerName = component + t.strftime(' %Y-%m-%d %H:%M UTC') if component == self.componentTranslation.values()[0]: colourRanges(new_layer, component, opacity, range_minima, range_maxima, colours) new_layer.setLayerName(layerName) layerId = new_layer.id() QgsMapLayerRegistry.instance().addMapLayer(new_layer) proportion = new_layer.extent().height( ) / new_layer.extent().width() else: # Have to clone. Can't seem to duplicate a map layer... layer = duplicateVectorLayer(new_layer) layer.setLayerName(layerName) colourRanges(layer, component, opacity, range_minima, range_maxima, colours) layerId = layer.id() QgsMapLayerRegistry.instance().addMapLayer(layer) proportion = layer.extent().height() / layer.extent( ).width() maxSize = 2000 # Max size of output image if proportion > 1: hSize = maxSize / proportion vSize = maxSize else: hSize = maxSize vSize = maxSize * proportion # create image in proportion with layer img = QImage(QSize(hSize, vSize), QImage.Format_ARGB32_Premultiplied) # set image's background color color = QColor(255, 255, 255) img.fill(color.rgb()) # create painter p = QPainter() p.begin(img) p.setRenderHint(QPainter.Antialiasing) render = QgsMapRenderer() # set layer set lst = [layerId] # add ID of every layer render.setLayerSet(lst) # set extent rect = QgsRectangle(render.fullExtent()) rect.scale(1.1) render.setExtent(rect) # set output size render.setOutputSize(img.size(), img.logicalDpiX()) # do the rendering render.render(p) p.end() # save image img.save( os.path.join( self.model.renderPath, component + t.strftime('_%Y-%m-%d_%H-%M_UTC.png')), "png")
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 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 = [] 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.setGridPenColor(QColor(0,255,0)) 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) self.mComposerMap.setAnnotationFontColor(QColor(255,0,0,150)) self.mComposerMap.setGridBlendMode(QPainter.CompositionMode_Overlay) checker = QgsCompositionChecker('composermap_grid', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview_blending', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview_invert', self.mComposition) myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375+5000, 3341423.125, 789262.375+5000, 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(False) overviewMap.setOverviewCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) myTestResult, myMessage = checker.testComposition() 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) self.mComposerMap.setGridFrameWidth( 10 ) self.mComposerMap.setGridFramePenSize( 1 ) self.mComposerMap.setGridPenWidth( 0.5 ) self.mComposerMap.setGridFramePenColor( QColor( 255, 100, 0, 200 ) ) self.mComposerMap.setGridFrameFillColor1( QColor( 50, 90, 50, 100 ) ) self.mComposerMap.setGridFrameFillColor2( QColor( 200, 220, 100, 60 ) ) checker = QgsCompositionChecker('composermap_zebrastyle', self.mComposition) myTestResult, myMessage = checker.testComposition() assert myTestResult == True, 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, 1e+03) for i in range(0,6): assert abs(p[i]-pexpected[i]) < ptolerance[i]
def saveControlImage(self, tmpimg=''): # don't save control images for RenderVsOtherOutput (Vs) tests, since # those control images belong to a different test result if ('PAL_CONTROL_IMAGE' not in os.environ or 'Vs' in self._TestGroup): return imgpath = self.controlImagePath() # print "saveControlImage: {0}".format(imgpath) testdir = os.path.dirname(imgpath) if not os.path.exists(testdir): os.makedirs(testdir) imgbasepath = \ os.path.join(testdir, os.path.splitext(os.path.basename(imgpath))[0]) for f in glob.glob(imgbasepath + '.*'): if os.path.exists(f): os.remove(f) if tmpimg and os.path.exists(tmpimg): shutil.copyfile(tmpimg, imgpath) else: print '\nsaveControlImage.render(): entered' print '{0}.{1}'.format(self._TestGroup, self._TestFunction) ms = self._MapSettings # class settings """:type: QgsMapSettings""" if self._TestMapSettings is not None: ms = self._TestMapSettings # per test settings print 'self._MapSettings...' print 'ms.layers(): {0}'.format( [self._MapRegistry.mapLayer(i).name() for i in ms.layers()]) print 'ms.outputSize(): {0} x {1}'.format(ms.outputSize().width(), ms.outputSize().height()) print 'ms.outputDpi(): {0}'.format(ms.outputDpi()) print 'ms.mapUnits(): {0}'.format(ms.mapUnits()) print 'ms.extent(): {0}'.format(ms.extent().toString()) print 'ms.hasCrsTransformEnabled(): {0}'.format( ms.hasCrsTransformEnabled()) print 'ms.destinationCrs(): {0}'.format( ms.destinationCrs().authid()) # pal = QgsPalLabeling() pal = self._Pal.clone() # or custom settings are lost pal.init(ms) r = QgsMapRenderer() r.setLabelingEngine(pal) # this seems too redundant r.setOutputSize(ms.outputSize(), ms.outputDpi()) r.setMapUnits(ms.mapUnits()) r.setExtent(ms.extent()) r.setProjectionsEnabled(ms.hasCrsTransformEnabled()) r.setDestinationCrs(ms.destinationCrs()) r.setLayerSet(ms.layers()) ctx = r.rendererContext() ctx.setDrawEditingInformation( ms.testFlag(QgsMapSettings.DrawEditingInfo)) ctx.setForceVectorOutput( ms.testFlag(QgsMapSettings.ForceVectorOutput)) ctx.setUseAdvancedEffects( ms.testFlag(QgsMapSettings.UseAdvancedEffects)) image = QImage(ms.outputSize(), QImage.Format_ARGB32) image.fill(ms.backgroundColor().rgb()) image.setDotsPerMeterX(ms.outputDpi() / 25.4 * 1000) image.setDotsPerMeterY(ms.outputDpi() / 25.4 * 1000) p = QPainter(image) r.render(p) p.end() if not image.save(imgpath, 'png'): os.unlink(imgpath) # delete extraneous world file (always generated) # wrld_file = imgbasepath + '.PNGw' # if os.path.exists(wrld_file): # os.remove(wrld_file) if not os.path.exists(imgpath): raise OSError('Control image not created: {0}'.format(imgpath))
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 = [] 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.setGridPenColor(QColor(0, 255, 0)) 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) self.mComposerMap.setAnnotationFontColor(QColor(255, 0, 0, 150)) self.mComposerMap.setGridBlendMode(QPainter.CompositionMode_Overlay) checker = QgsCompositionChecker('composermap_grid', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview_blending', self.mComposition) myTestResult, myMessage = checker.testComposition() 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('composermap_overview_invert', self.mComposition) myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult == True, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(785462.375 + 5000, 3341423.125, 789262.375 + 5000, 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(False) overviewMap.setOverviewCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) myTestResult, myMessage = checker.testComposition() 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) self.mComposerMap.setGridFrameWidth(10) self.mComposerMap.setGridFramePenSize(1) self.mComposerMap.setGridPenWidth(0.5) self.mComposerMap.setGridFramePenColor(QColor(255, 100, 0, 200)) self.mComposerMap.setGridFrameFillColor1(QColor(50, 90, 50, 100)) self.mComposerMap.setGridFrameFillColor2(QColor(200, 220, 100, 60)) checker = QgsCompositionChecker('composermap_zebrastyle', self.mComposition) myTestResult, myMessage = checker.testComposition() assert myTestResult == True, 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, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
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.mMapRenderer = QgsMapRenderer() layerStringList = [] 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 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.setOverviewFrameMap(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewBlendMode(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(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.setOverviewFrameMap(self.mComposerMap.id()) overviewMap.setOverviewInverted(False) overviewMap.setOverviewCentered(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, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
def generate_reports(self): """Generate PDF reports for each aggregation unit using map composer. First the report template is loaded with the renderer from two impact layers. After it's loaded, if it is not aggregated then we just use composition to produce report. Since there are two impact maps here, we need to set a new extent for these impact maps by a simple calculation. If it is not aggregated then we use a powerful QGIS atlas generation on composition. Since we save each report table representing each aggregated area on self.html_report (which is a dictionary with the aggregation area name as a key and its path as a value), and we set the aggregation area name as current filename on atlas generation, we can match these two so that we have the right report table for each report. For those two cases, we use the same template. The report table is basically an HTML frame. Of course after the merging process is done, we delete each report table on self.html_reports physically on disk. """ # Set the layer set layer_set = [ self.first_impact['layer'].id(), self.second_impact['layer'].id() ] # If aggregated, append chosen aggregation layer if not self.entire_area_mode: layer_set.append(self.aggregation['layer'].id()) # Instantiate Map Settings for Composition if qgis_version() < 20400: map_settings = QgsMapRenderer() map_settings.setLayerSet(layer_set) else: map_settings = QgsMapSettings() map_settings.setLayers(layer_set) # Create composition composition = self.load_template(map_settings) # Get Map composer_map = composition.getComposerItemById('impact-map') # Get HTML Report Frame html_report_item = \ composition.getComposerItemById('merged-report-table') html_report_frame = composition.getComposerHtmlByItem(html_report_item) if self.entire_area_mode: # Get composer map size composer_map_width = composer_map.boundingRect().width() composer_map_height = composer_map.boundingRect().height() # Set the extent from two impact layers to fit into composer map composer_size_ratio = float(composer_map_height / composer_map_width) # The extent of two impact layers min_x = min(self.first_impact['layer'].extent().xMinimum(), self.second_impact['layer'].extent().xMinimum()) min_y = min(self.first_impact['layer'].extent().yMinimum(), self.second_impact['layer'].extent().yMinimum()) max_x = max(self.first_impact['layer'].extent().xMaximum(), self.second_impact['layer'].extent().xMaximum()) max_y = max(self.first_impact['layer'].extent().yMaximum(), self.second_impact['layer'].extent().yMaximum()) max_width = max_x - min_x max_height = max_y - min_y layers_size_ratio = float(max_height / max_width) center_x = min_x + float(max_width / 2.0) center_y = min_y + float(max_height / 2.0) # The extent should fit the composer map size new_width = max_width new_height = max_height # QgsComposerMap only overflows to height, so if it overflows, # the extent of the width should be widened if layers_size_ratio > composer_size_ratio: new_width = max_height / composer_size_ratio # Set new extent fit_min_x = center_x - (new_width / 2.0) fit_max_x = center_x + (new_width / 2.0) fit_min_y = center_y - (new_height / 2.0) fit_max_y = center_y + (new_height / 2.0) # Create the extent and set it to the map # noinspection PyCallingNonCallable map_extent = QgsRectangle(fit_min_x, fit_min_y, fit_max_x, fit_max_y) composer_map.setNewExtent(map_extent) # Add grid to composer map split_count = 5 x_interval = new_width / split_count composer_map.setGridIntervalX(x_interval) y_interval = new_height / split_count composer_map.setGridIntervalY(y_interval) # Self.html_reports must have only 1 key value pair # Rizky: If layer components were aggregated, html_reports will # have several key value pairs. So we get the last value because # it is for the total/entire area area_title = list(self.html_reports.keys())[-1] # Set Report Summary summary_report = composition.getComposerItemById('summary-report') summary_report.setText(self.summary_report[area_title]) # Set Aggregation Area Label area_label = composition.getComposerItemById('aggregation-area') area_label.setText(area_title.title()) # Set merged-report-table html_report_path = self.html_reports[area_title] # noinspection PyArgumentList html_frame_url = QUrl.fromLocalFile(html_report_path) html_report_frame.setUrl(html_frame_url) # Export composition to PDF file file_name = '_'.join(area_title.split()) file_path = '%s.pdf' % file_name path = os.path.join(self.out_dir, file_path) composition.exportAsPDF(path) else: # Create atlas composition: # noinspection PyCallingNonCallable atlas = QgsAtlasComposition(composition) # Set coverage layer # Map will be clipped by features from this layer: atlas.setCoverageLayer(self.aggregation['layer']) # Add grid to composer map from coverage layer split_count = 5 map_width = self.aggregation['layer'].extent().width() map_height = self.aggregation['layer'].extent().height() x_interval = map_width / split_count composer_map.setGridIntervalX(x_interval) y_interval = map_height / split_count composer_map.setGridIntervalY(y_interval) # Set composer map that will be used for printing atlas atlas.setComposerMap(composer_map) # set output filename pattern atlas.setFilenamePattern(self.aggregation['aggregation_attribute']) # Start rendering atlas.beginRender() # Iterate all aggregation unit in aggregation layer for i in range(0, atlas.numFeatures()): atlas.prepareForFeature(i) current_filename = atlas.currentFilename() file_name = '_'.join(current_filename.split()) file_path = '%s.pdf' % file_name path = os.path.join(self.out_dir, file_path) # Only print the area that has the report area_title = current_filename.lower() if area_title in self.summary_report: # Set Report Summary summary_report = composition.getComposerItemById( 'summary-report') summary_report.setText(self.summary_report[area_title]) # Set Aggregation Area Label area_label = composition.getComposerItemById( 'aggregation-area') area_label.setText(area_title.title()) # Set merged-report-table html_report_path = self.html_reports[area_title] # noinspection PyArgumentList html_frame_url = QUrl.fromLocalFile(html_report_path) html_report_frame.setUrl(html_frame_url) # Export composition to PDF file composition.exportAsPDF(path) # End of rendering atlas.endRender()
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, QgsRaster.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 = [] 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 saveControlImage(self, tmpimg=''): # don't save control images for RenderVsOtherOutput (Vs) tests, since # those control images belong to a different test result if ('PAL_CONTROL_IMAGE' not in os.environ or 'Vs' in self._TestGroup): return imgpath = self.controlImagePath() # print "saveControlImage: {0}".format(imgpath) testdir = os.path.dirname(imgpath) if not os.path.exists(testdir): os.makedirs(testdir) imgbasepath = \ os.path.join(testdir, os.path.splitext(os.path.basename(imgpath))[0]) for f in glob.glob(imgbasepath + '.*'): if os.path.exists(f): os.remove(f) if tmpimg and os.path.exists(tmpimg): shutil.copyfile(tmpimg, imgpath) else: print '\nsaveControlImage.render(): entered' print '{0}.{1}'.format(self._TestGroup, self._TestFunction) ms = self._MapSettings # class settings """:type: QgsMapSettings""" if self._TestMapSettings is not None: ms = self._TestMapSettings # per test settings print 'self._MapSettings...' print 'ms.layers(): {0}'.format( [self._MapRegistry.mapLayer(i).name() for i in ms.layers()] ) print 'ms.outputSize(): {0} x {1}'.format( ms.outputSize().width(), ms.outputSize().height()) print 'ms.outputDpi(): {0}'.format(ms.outputDpi()) print 'ms.mapUnits(): {0}'.format(ms.mapUnits()) print 'ms.extent(): {0}'.format(ms.extent().toString()) print 'ms.hasCrsTransformEnabled(): {0}'.format( ms.hasCrsTransformEnabled()) print 'ms.destinationCrs(): {0}'.format( ms.destinationCrs().authid()) # pal = QgsPalLabeling() pal = self._Pal.clone() # or custom settings are lost pal.init(ms) r = QgsMapRenderer() r.setLabelingEngine(pal) # this seems too redundant r.setOutputSize(ms.outputSize(), ms.outputDpi()) r.setMapUnits(ms.mapUnits()) r.setExtent(ms.extent()) r.setProjectionsEnabled(ms.hasCrsTransformEnabled()) r.setDestinationCrs(ms.destinationCrs()) r.setLayerSet(ms.layers()) ctx = r.rendererContext() ctx.setDrawEditingInformation( ms.testFlag(QgsMapSettings.DrawEditingInfo)) ctx.setForceVectorOutput( ms.testFlag(QgsMapSettings.ForceVectorOutput)) ctx.setUseAdvancedEffects( ms.testFlag(QgsMapSettings.UseAdvancedEffects)) image = QImage(ms.outputSize(), QImage.Format_ARGB32) image.fill(ms.backgroundColor().rgb()) image.setDotsPerMeterX(ms.outputDpi() / 25.4 * 1000) image.setDotsPerMeterY(ms.outputDpi() / 25.4 * 1000) p = QPainter(image) r.render(p) p.end() if not image.save(imgpath, 'png'): os.unlink(imgpath) # delete extraneous world file (always generated) # wrld_file = imgbasepath + '.PNGw' # if os.path.exists(wrld_file): # os.remove(wrld_file) if not os.path.exists(imgpath): raise OSError('Control image not created: {0}'.format(imgpath))
def generate_reports(self): """Generate PDF reports for each aggregation unit using map composer. First the report template is loaded with the renderer from two impact layers. After it's loaded, if it is not aggregated then we just use composition to produce report. Since there are two impact maps here, we need to set a new extent for these impact maps by a simple calculation. If it is not aggregated then we use a powerful QGIS atlas generation on composition. Since we save each report table representing each aggregated area on self.html_report (which is a dictionary with the aggregation area name as a key and its path as a value), and we set the aggregation area name as current filename on atlas generation, we can match these two so that we have the right report table for each report. For those two cases, we use the same template. The report table is basically an HTML frame. Of course after the merging process is done, we delete each report table on self.html_reports physically on disk. """ # Setup Map Renderer and set all the layer renderer = QgsMapRenderer() layer_set = [self.first_impact['layer'].id(), self.second_impact['layer'].id()] # If aggregated, append chosen aggregation layer if not self.entire_area_mode: layer_set.append(self.aggregation['layer'].id()) # Set Layer set to renderer renderer.setLayerSet(layer_set) # Create composition composition = self.load_template(renderer) # Get Map composer_map = composition.getComposerItemById('impact-map') # Get HTML Report Frame html_report_item = \ composition.getComposerItemById('merged-report-table') html_report_frame = composition.getComposerHtmlByItem(html_report_item) if self.entire_area_mode: # Get composer map size composer_map_width = composer_map.boundingRect().width() composer_map_height = composer_map.boundingRect().height() # Set the extent from two impact layers to fit into composer map composer_size_ratio = float( composer_map_height / composer_map_width) # The extent of two impact layers min_x = min(self.first_impact['layer'].extent().xMinimum(), self.second_impact['layer'].extent().xMinimum()) min_y = min(self.first_impact['layer'].extent().yMinimum(), self.second_impact['layer'].extent().yMinimum()) max_x = max(self.first_impact['layer'].extent().xMaximum(), self.second_impact['layer'].extent().xMaximum()) max_y = max(self.first_impact['layer'].extent().yMaximum(), self.second_impact['layer'].extent().yMaximum()) max_width = max_x - min_x max_height = max_y - min_y layers_size_ratio = float(max_height / max_width) center_x = min_x + float(max_width / 2.0) center_y = min_y + float(max_height / 2.0) # The extent should fit the composer map size new_width = max_width new_height = max_height # QgsComposerMap only overflows to height, so if it overflows, # the extent of the width should be widened if layers_size_ratio > composer_size_ratio: new_width = max_height / composer_size_ratio # Set new extent fit_min_x = center_x - (new_width / 2.0) fit_max_x = center_x + (new_width / 2.0) fit_min_y = center_y - (new_height / 2.0) fit_max_y = center_y + (new_height / 2.0) # Create the extent and set it to the map map_extent = QgsRectangle( fit_min_x, fit_min_y, fit_max_x, fit_max_y) composer_map.setNewExtent(map_extent) # Add grid to composer map split_count = 5 x_interval = new_width / split_count composer_map.setGridIntervalX(x_interval) y_interval = new_height / split_count composer_map.setGridIntervalY(y_interval) # Self.html_reports must have only 1 key value pair area_title = list(self.html_reports.keys())[0] # Set Report Summary summary_report = composition.getComposerItemById('summary-report') summary_report.setText(self.summary_report[area_title]) # Set Aggregation Area Label area_label = composition.getComposerItemById('aggregation-area') area_label.setText(area_title.title()) # Set merged-report-table html_report_path = self.html_reports[area_title] #noinspection PyArgumentList html_frame_url = QUrl.fromLocalFile(html_report_path) html_report_frame.setUrl(html_frame_url) # Export composition to PDF file file_name = '_'.join(area_title.split()) file_path = '%s.pdf' % file_name path = os.path.join(self.out_dir, file_path) composition.exportAsPDF(path) else: # Create atlas composition: atlas = QgsAtlasComposition(composition) # Set coverage layer # Map will be clipped by features from this layer: atlas.setCoverageLayer(self.aggregation['layer']) # Add grid to composer map from coverage layer split_count = 5 map_width = self.aggregation['layer'].extent().width() map_height = self.aggregation['layer'].extent().height() x_interval = map_width / split_count composer_map.setGridIntervalX(x_interval) y_interval = map_height / split_count composer_map.setGridIntervalY(y_interval) # Set composer map that will be used for printing atlas atlas.setComposerMap(composer_map) # set output filename pattern atlas.setFilenamePattern( self.aggregation['aggregation_attribute']) # Start rendering atlas.beginRender() # Iterate all aggregation unit in aggregation layer for i in range(0, atlas.numFeatures()): atlas.prepareForFeature(i) current_filename = atlas.currentFilename() file_name = '_'.join(current_filename.split()) file_path = '%s.pdf' % file_name path = os.path.join(self.out_dir, file_path) # Only print the area that has the report area_title = current_filename.lower() if area_title in self.summary_report: # Set Report Summary summary_report = composition.getComposerItemById( 'summary-report') summary_report.setText(self.summary_report[area_title]) # Set Aggregation Area Label area_label = composition.getComposerItemById( 'aggregation-area') area_label.setText(area_title.title()) # Set merged-report-table html_report_path = self.html_reports[area_title] #noinspection PyArgumentList html_frame_url = QUrl.fromLocalFile(html_report_path) html_report_frame.setUrl(html_frame_url) # Export composition to PDF file composition.exportAsPDF(path) # End of rendering atlas.endRender()
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 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() shutil.rmtree(tmppath, True)
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.setGridPenColor(QColor(0,255,0)) 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) self.mComposerMap.setAnnotationFontColor(QColor(255,0,0,150)) self.mComposerMap.setGridBlendMode(QPainter.CompositionMode_Overlay) 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
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().addMapLayer(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") testResult = checker.testComposition("Composer map grid", self.mComposition, myPath) self.mComposerMap.setGridEnabled(False) self.mComposerMap.setShowGridAnnotation(False) print testResult assert testResult[0] == True 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 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 zebraStyle(self): mComposerMap.setGridFrameStyle( QgsComposerMap.Zebra ) mComposerMap.setGridEnabled( True ) myPngPath = os.path.join(TEST_DATA_DIR, "control_images", "expected_composermap", "composermap_zebra_style.png") testResult = checker.testComposition("Composer map zebra", self.mComposition, myPngPath) assert testResult[0] == True
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
QgsApplication.setPrefixPath('/usr', True) QgsApplication.initQgis() layer = QgsVectorLayer(args.input, 'layer', 'ogr') extent = layer.extent() print("Layer extent: %s" % extent.toString()) QgsMapLayerRegistry.instance().removeAllMapLayers() QgsMapLayerRegistry.instance().addMapLayer(layer) crs = QgsCoordinateReferenceSystem(4326) layer.setCrs(crs) render = QgsMapRenderer() render.setLayerSet([layer.id()]) iwidth = args.width iheight = int(iwidth * (extent.height() / extent.width())) print("Image size: %dx%d" % (iwidth, iheight)) dpi = args.dpi img = QImage(iwidth, iheight, QImage.Format_RGB32) img.setDotsPerMeterX(dpi / 25.4 * 1000) img.setDotsPerMeterY(dpi / 25.4 * 1000) img.fill(qRgb(255, 255, 255)) dpi = img.logicalDpiX() print("Image DPI: %d" % dpi)