def setUp(self): self.keywordIO = KeywordIO() myUri = QgsDataSourceURI() myUri.setDatabase(os.path.join(TESTDATA, 'jk.sqlite')) myUri.setDataSource('', 'osm_buildings', 'Geometry') self.sqliteLayer = QgsVectorLayer(myUri.uri(), 'OSM Buildings', 'spatialite') myHazardPath = os.path.join(HAZDATA, 'Shakemap_Padang_2009.asc') self.fileRasterLayer, myType = loadLayer(myHazardPath, theDirectory=None) del myType self.fileVectorLayer, myType = loadLayer('Padang_WGS84.shp') del myType self.expectedSqliteKeywords = {'category': 'exposure', 'datatype': 'OSM', 'subcategory': 'building'} self.expectedVectorKeywords = {'category': 'exposure', 'datatype': 'itb', 'subcategory': 'structure'} self.expectedRasterKeywords = {'category': 'hazard', 'source': 'USGS', 'subcategory': 'earthquake', 'unit': 'MMI', 'title': ('An earthquake in Padang ' 'like in 2009')}
def setUp(self): self.keywordIO = KeywordIO() myUri = QgsDataSourceURI() myUri.setDatabase(os.path.join(TESTDATA, 'jk.sqlite')) myUri.setDataSource('', 'osm_buildings', 'Geometry') self.sqliteLayer = QgsVectorLayer(myUri.uri(), 'OSM Buildings', 'spatialite') myHazardPath = os.path.join(HAZDATA, 'Shakemap_Padang_2009.asc') self.fileRasterLayer, myType = loadLayer(myHazardPath, theDirectory=None) del myType self.fileVectorLayer, myType = loadLayer('Padang_WGS84.shp') del myType self.expectedSqliteKeywords = { 'category': 'exposure', 'datatype': 'OSM', 'subcategory': 'building' } self.expectedVectorKeywords = { 'category': 'exposure', 'datatype': 'itb', 'subcategory': 'structure' } self.expectedRasterKeywords = { 'category': 'hazard', 'source': 'USGS', 'subcategory': 'earthquake', 'unit': 'MMI', 'title': ('An earthquake in Padang ' 'like in 2009') }
def test_getVectorLegend(self): """Getting a legend for a vector layer works.""" myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend( myLayer, theLegendNotes='Thousand separator represented by \'.\'', theLegendUnits='(people per cell)') myImage = myMapLegend.getVectorLegend() myPath = unique_filename(prefix='getVectorLegend', suffix='.png', dir=temp_dir('test')) myImage.save(myPath, 'PNG') print myMapLegend.legendUnits print myMapLegend.legendNotes print myPath LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages( 'getVectorLegend.png', myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control ' 'image.') assert myFlag, myMessage
def test_getLegend(self): """Getting a legend for a generic layer works.""" LOGGER.debug('test_getLegend called') myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend(myLayer) assert myMapLegend.layer is not None myLegend = myMapLegend.getLegend() myPath = unique_filename(prefix='getLegend', suffix='.png', dir=temp_dir('test')) myLegend.save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages('getLegend.png', myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control ' 'image.') assert myFlag, myMessage LOGGER.debug('test_getLegend done')
def test_addClassToLegend(self): """Test we can add a class to the map legend.""" myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend(myLayer) myColour = QtGui.QColor(12, 34, 126) myMapLegend.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='bar') myMapLegend.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='foo') myPath = unique_filename(prefix='addClassToLegend', suffix='.png', dir=temp_dir('test')) myMapLegend.getLegend().save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so place any other possible # variants in the safe_qgis/test_data/test_images/ dir e.g. # addClassToLegend-variantUbuntu13.04.png myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages('addClassToLegend.png', myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control ' 'image.') assert myFlag, myMessage
def test_addSymbolToLegend(self): """Test we can add a symbol to the legend.""" myLayer, _ = loadLayer('test_floodimpact.tif') myMapLegend = MapLegend(myLayer) mySymbol = QgsSymbol() mySymbol.setColor(QtGui.QColor(12, 34, 56)) myMapLegend.addSymbolToLegend(mySymbol, theMin=0, # expect 2.0303 in legend theMax=2.02030, theCategory=None, theLabel='Foo') myPath = unique_filename(prefix='addSymbolToLegend', suffix='.png', dir=temp_dir('test')) myMapLegend.getLegend().save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages('addSymbolToLegend.png', myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control ' 'image.') assert myFlag, myMessage
def loadLayers(theLayerList, theClearFlag=True, theDataDirectory=TESTDATA): """Helper function to load layers as defined in a python list.""" # First unload any layers that may already be loaded if theClearFlag: for myLayer in QgsMapLayerRegistry.instance().mapLayers(): QgsMapLayerRegistry.instance().removeMapLayer(myLayer) # Now go ahead and load our layers myExposureLayerCount = 0 myHazardLayerCount = 0 myCanvasLayers = [] # Now create our new layers for myFile in theLayerList: myLayer, myType = loadLayer(myFile, theDataDirectory) if myType == 'hazard': myHazardLayerCount += 1 elif myType == 'exposure': myExposureLayerCount += 1 # Add layer to the registry (that QGis knows about) QgsMapLayerRegistry.instance().addMapLayer(myLayer) # Create Map Canvas Layer Instance and add to list myCanvasLayers.append(QgsMapCanvasLayer(myLayer)) # Quickly add any existing CANVAS layers to our list first for myLayer in CANVAS.layers(): myCanvasLayers.append(QgsMapCanvasLayer(myLayer)) # now load all these layers in the CANVAS CANVAS.setLayerSet(myCanvasLayers) DOCK.getLayers() # Add MCL's to the CANVAS return myHazardLayerCount, myExposureLayerCount
def test_getVectorLegend(self): """Getting a legend for a vector layer works.""" myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend( myLayer, theLegendNotes='Thousand separator represented by \'.\'', theLegendUnits='(people per cell)') myImage = myMapLegend.getVectorLegend() myPath = unique_filename(prefix='getVectorLegend', suffix='.png', dir=temp_dir('test')) myImage.save(myPath, 'PNG') print myMapLegend.legendUnits print myMapLegend.legendNotes print myPath LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myControlImages = ['getVectorLegend.png', 'getVectorLegend-variantWindowsVistaSP2-32.png', 'getVectorLegend-variantWindowsXPSP3-32.png', 'getVectorLegend-variantOSXml.png', 'getVectorLegend-variantUB12.04-64.png', 'getVectorLegend-variantUB11.04-64.png', 'getVectorLegend-variantLinuxMint-14-x86_64.png', 'getVectorLegend-variantWindows7-SP1-AMD64.png', 'getVectorLegend-variantJenkins.png'] myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages(myControlImages, myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control ' 'image.') assert myFlag, myMessage
def test_addClassToLegend(self): """Test we can add a class to the map legend.""" myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend(myLayer) myColour = QtGui.QColor(12, 34, 126) myMapLegend.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='bar') myMapLegend.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='foo') myPath = unique_filename(prefix='addClassToLegend', suffix='.png', dir=temp_dir('test')) myMapLegend.getLegend().save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myControlImages = ['getClassToLegend.png', 'getClassToLegend-variantWindosVistaSP2-32.png', 'getClassToLegend-variantUB12.04-64.png', 'getClassToLegend-variantUB11.04-64.png', 'getClassToLegend-variantJenkins.png'] myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages(myControlImages, myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control image.') assert myFlag, myMessage
def test_printImpactTable(self): """Test that we can render html from impact table keywords.""" LOGGER.debug('InaSAFE HtmlRenderer testing printImpactTable') myFilename = 'test_floodimpact.tif' myLayer, _ = loadLayer(myFilename) myMessage = 'Layer is not valid: %s' % myFilename assert myLayer.isValid(), myMessage myPageDpi = 300 myHtmlRenderer = HtmlRenderer(myPageDpi) myPath = unique_filename(prefix='impactTable', suffix='.pdf', dir=temp_dir('test')) myKeywordIO = KeywordIO() myKeywords = myKeywordIO.readKeywords(myLayer) myPath = myHtmlRenderer.printImpactTable(myKeywords, theFilename=myPath) myMessage = 'Rendered output does not exist: %s' % myPath assert os.path.exists(myPath), myMessage # pdf rendering is non deterministic so we can't do a hash check # test_renderComposition renders just the image instead of pdf # so we hash check there and here we just do a basic minimum file # size check. mySize = os.stat(myPath).st_size myExpectedSize = 20936 # as rendered on linux ub 12.04 64 myMessage = ('Expected rendered table pdf to be at least %s, got %s' % (myExpectedSize, mySize)) assert mySize >= myExpectedSize, myMessage
def test_printToPdf(self): """Test making a pdf of the map - this is the most typical use of map. """ LOGGER.info('Testing printToPdf') myLayer, _ = loadLayer('test_shakeimpact.shp') myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myRect = QgsRectangle(106.7894, -6.2308, 106.8004, -6.2264) CANVAS.setExtent(myRect) CANVAS.refresh() myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.composeMap() myPath = unique_filename(prefix='mapPdfTest', suffix='.pdf', dir=temp_dir('test')) myMap.printToPdf(myPath) LOGGER.debug(myPath) myMessage = 'Rendered output does not exist: %s' % myPath assert os.path.exists(myPath), myMessage # pdf rendering is non deterministic so we can't do a hash check # test_renderComposition renders just the image instead of pdf # so we hash check there and here we just do a basic minimum file # size check. mySize = os.stat(myPath).st_size myExpectedSize = 352798 # as rendered on linux ub 12.04 64 myMessage = 'Expected rendered map pdf to be at least %s, got %s' % ( myExpectedSize, mySize) assert mySize >= myExpectedSize, myMessage
def Xtest_renderTable(self): """Test that html renders nicely. Commented out for now until we work out how to get webkit to do offscreen rendering nicely.""" myFilename = 'test_floodimpact.tif' myLayer, myType = loadLayer(myFilename) CANVAS.refresh() del myType myMessage = 'Layer is not valid: %s' % myFilename assert myLayer.isValid(), myMessage myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myPixmap = myMap.renderImpactTable() assert myPixmap is not None myExpectedWidth = 500 myExpectedHeight = 300 myMessage = 'Invalid width - got %s expected %s' % ( myPixmap.width(), myExpectedWidth) assert myPixmap.width() == myExpectedWidth, myMessage myMessage = 'Invalid height - got %s expected %s' % ( myPixmap.height(), myExpectedHeight) assert myPixmap.height() == myExpectedHeight myPath = os.path.join(temp_dir(), 'renderImpactTable.png') myPixmap.save(myPath, 'PNG') myExpectedHash = 'c9164d5c2bb85c6081905456ab827f3e' assertHashForFile(myExpectedHash, myPath)
def test_addClassToLegend(self): """Test we can add a class to the map legend.""" myLayer, myType = loadLayer('test_shakeimpact.shp') del myType myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.legend = None myColour = QtGui.QColor(12, 34, 126) myMap.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='bar') myMap.addClassToLegend(myColour, theMin=None, theMax=None, theCategory=None, theLabel='foo') myPath = os.path.join(temp_dir(), 'addClassToLegend.png') myMap.legend.save(myPath, 'PNG') # As we have discovered, different versions of Qt and # OS platforms cause different output, so hashes are a list # of 'known good' renders. myExpectedHashes = ['', # win '67c0f45792318298664dd02cc0ac94c3', # ub12.04xiner 'ea0702782c2ed5d950c427fbe1743858', # ub11.04-64 '53e0ba1144e071ad41756595d29bf444', # ub12.04 '0681c3587305074bc9272f456fb4dd09', # ub12.04 xvfb 'a37443d70604bdc8c279576b424a158c', # ub12.04-64 # ub11.04-64 laptop '944cee3eb9d916816b60ef41e8069683', # binary read 'de3ceb6547ffc6c557d031c0b7ee9e75', # wVistaSP2-32 '', ] assertHashesForFile(myExpectedHashes, myPath)
def test_addSymbolToLegend(self): """Test we can add a symbol to the legend.""" myLayer, _ = loadLayer('test_floodimpact.tif') myMapLegend = MapLegend(myLayer) mySymbol = QgsSymbol() mySymbol.setColor(QtGui.QColor(12, 34, 56)) myMapLegend.addSymbolToLegend(mySymbol, theMin=0, theMax=2, theCategory=None, theLabel='Foo') myPath = unique_filename(prefix='addSymblToLegend', suffix='.png', dir=temp_dir('test')) myMapLegend.getLegend().save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myControlImages = [ 'addSymbolToLegend.png', 'addSymbolToLegend-variantWindosVistaSP2-32.png', 'addSymbolToLegend-variantUB12.04-64.png', 'addSymbolToLegend-variantUB11.04-64.png', 'addSymbolToLegend-variantJenkins.png' ] myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages(myControlImages, myPath, myTolerance) myMessage += ( '\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control image.') assert myFlag, myMessage
def test_getVectorLegend(self): """Getting a legend for a vector layer works.""" myLayer, _ = loadLayer('test_shakeimpact.shp') myMapLegend = MapLegend(myLayer) myImage = myMapLegend.getVectorLegend() myPath = unique_filename(prefix='getVectorLegend', suffix='.png', dir=temp_dir('test')) myImage.save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myControlImages = ['getVectorLegend.png', 'getVectorLegend-variantWindosVistaSP2-32.png', 'getVectorLegend-variantUB12.04-64.png', 'getVectorLegend-variantUB11.04-64.png', 'getVectorLegend-variantJenkins.png'] myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages(myControlImages, myPath, myTolerance) myMessage += ('\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control image.') assert myFlag, myMessage
def test_getRasterLegend(self): """Getting a legend for a raster layer works.""" myLayer, _ = loadLayer('test_floodimpact.tif') myMapLegend = MapLegend(myLayer) myImage = myMapLegend.getRasterLegend() myPath = unique_filename(prefix='getRasterLegend', suffix='.png', dir=temp_dir('test')) myImage.save(myPath, 'PNG') LOGGER.debug(myPath) # As we have discovered, different versions of Qt and # OS platforms cause different output, so myControlImages is a list # of 'known good' renders. myControlImages = [ 'getRasterLegend.png', 'getRasterLegend-variantWindosVistaSP2-32.png', 'getRasterLegend-variantUB12.04-64.png', 'getRasterLegend-variantUB11.04-64.png', 'getRasterLegend-variantJenkins.png' ] myTolerance = 0 # to allow for version number changes in disclaimer myFlag, myMessage = checkImages(myControlImages, myPath, myTolerance) myMessage += ( '\nWe want these images to match, if they do already ' 'copy the test image generated to create a new control image.') assert myFlag, myMessage
def test_printToPdf(self): """Test making a pdf of the map - this is the most typical use of map. """ LOGGER.info('Testing printToPdf') myLayer, _ = loadLayer('test_shakeimpact.shp') myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myRect = QgsRectangle(106.7894, -6.2308, 106.8004, -6.2264) CANVAS.setExtent(myRect) CANVAS.refresh() myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.composeMap() myPath = unique_filename(prefix='mapPdfTest', suffix='.pdf', dir=temp_dir('test')) myMap.printToPdf(myPath) LOGGER.debug(myPath) myMessage = 'Rendered output does not exist: %s' % myPath assert os.path.exists(myPath), myMessage # pdf rendering is non deterministic so we can't do a hash check # test_renderComposition renders just the image instead of pdf # so we hash check there and here we just do a basic minimum file # size check. mySize = os.stat(myPath).st_size myExpectedSizes = [ 441541, # as rendered on ub 13.04 post 17 May 2013 447217, # Nadia Linux Mint 14 0, # as rendered on Jenkins post 24 April 2013 447138, # Windows 7 SP1 AMD64 ] myMessage = 'Expected rendered map pdf to be in %s, got %s' % ( myExpectedSizes, mySize) self.assertIn(mySize, myExpectedSizes, myMessage)
def test_getMapTitle(self): """Getting the map title from the keywords""" myLayer, _ = loadLayer('test_floodimpact.tif') myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myTitle = myMap.getMapTitle() myExpectedTitle = 'Penduduk yang Mungkin dievakuasi' myMessage = 'Expected: %s\nGot:\n %s' % (myExpectedTitle, myTitle) assert myTitle == myExpectedTitle, myMessage
def test_issue121(self): """Test that point symbol size can be set from style (issue 121). .. seealso:: https://github.com/AIFDR/inasafe/issues/121 """ myLayer, myType = loadLayer('kecamatan_jakarta_osm_centroids.shp') del myType # Note the float quantity values below myStyleInfo = { 'target_field': 'KEPADATAN', 'style_classes': [{ 'opacity': 1, 'max': 200, 'colour': '#fecc5c', 'min': 45, 'label': 'Low', 'size': 1 }, { 'opacity': 1, 'max': 350, 'colour': '#fd8d3c', 'min': 201, 'label': 'Medium', 'size': 2 }, { 'opacity': 1, 'max': 539, 'colour': '#f31a1c', 'min': 351, 'label': 'High', 'size': 3 }] } myMessage = ('Setting style with point sizes should work.') try: setVectorStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the size values were set as expected if myLayer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class myRenderer = myLayer.rendererV2() myType = myRenderer.type() assert myType == 'graduatedSymbol' mySize = 1 for myRange in myRenderer.ranges(): mySymbol = myRange.symbol() mySymbolLayer = mySymbol.symbolLayer(0) myActualSize = mySymbolLayer.size() myMessage = (('Expected symbol layer 0 for range %s to have' ' a size of %s, got %s') % (mySize, mySize, myActualSize)) assert mySize == myActualSize, myMessage mySize += 1
def test_handleMissingMapTitle(self): """Missing map title from the keywords fails gracefully""" # TODO running OSM Buildngs with Pendudk Jakarta # wasthrowing an error when requesting map title # that this test wasnt replicating well myLayer, _ = loadLayer('population_padang_1.asc') myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myTitle = myMap.getMapTitle() myExpectedTitle = None myMessage = 'Expected: %s\nGot:\n %s' % (myExpectedTitle, myTitle) assert myTitle == myExpectedTitle, myMessage
def test_renderComposition(self): """Test making an image of the map only.""" LOGGER.info('Testing renderComposition') myLayer, _ = loadLayer('test_shakeimpact.shp') myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myRect = QgsRectangle(106.7894, -6.2308, 106.8004, -6.2264) CANVAS.setExtent(myRect) CANVAS.refresh() myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.composeMap() myImagePath, myControlImage, myTargetArea = myMap.renderComposition() LOGGER.debug(myImagePath) assert myControlImage is not None myDimensions = [myTargetArea.left(), myTargetArea.top(), myTargetArea.bottom(), myTargetArea.right()] myExpectedDimensions = [0.0, 0.0, 3507.0, 2480.0] myMessage = 'Expected target area to be %s, got %s' % ( str(myExpectedDimensions), str(myDimensions)) assert myExpectedDimensions == myDimensions, myMessage myMessage = 'Rendered output does not exist' assert os.path.exists(myImagePath), myMessage myAcceptableImages = [ 'renderComposition.png', 'renderComposition-variantUB12.04.png', 'renderComposition-variantUB12.10.png', 'renderComposition-variantOSXml.png', 'renderComposition-variantWindowsVistaSP2-32.png', 'renderComposition-variantJenkins.png', 'renderComposition-variantUB11.10-64.png', 'renderComposition-variantLinuxMint-14-x86_64.png', 'renderComposition-variantWindows7-SP1-AMD64.png', 'renderComposition-variantUB11.04-64.png'] # Beta version and version changes can introduce a few extra chars # into the metadata section so we set a reasonable tolerance to cope # with this. myTolerance = 8000 print myImagePath print myAcceptableImages myFlag, myMessage = checkImages(myAcceptableImages, myImagePath, myTolerance) assert myFlag, myMessage
def Xtest_renderTemplate(self): """Test that load template works""" # Use the template from our resources bundle myInPath = ":/plugins/inasafe/basic.qpt" myLayer, _ = loadLayer("test_shakeimpact.shp") myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myMap = Map(IFACE) setJakartaGeoExtent() myMap.setImpactLayer(myLayer) myPath = unique_filename(prefix="outTemplate", suffix=".pdf", dir=temp_dir("test")) LOGGER.debug(myPath) myMap.renderTemplate(myInPath, myPath) assert os.path.exists(myPath)
def Xtest_renderTemplate(self): """Test that load template works""" #Use the template from our resources bundle myInPath = ':/plugins/inasafe/basic.qpt' myLayer, _ = loadLayer('test_shakeimpact.shp') myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myMap = Map(IFACE) setJakartaGeoExtent() myMap.setImpactLayer(myLayer) myPath = unique_filename(prefix='outTemplate', suffix='.pdf', dir=temp_dir('test')) LOGGER.debug(myPath) myMap.renderTemplate(myInPath, myPath) assert os.path.exists(myPath)
def test_renderTemplate(self): """Test that load template works""" #Use the template from our resources bundle myInPath = ':/plugins/inasafe/basic.qpt' myLayer, myType = loadLayer('test_shakeimpact.shp') del myType myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myMap = Map(IFACE) setJakartaGeoExtent() myMap.setImpactLayer(myLayer) myOutPath = os.path.join(temp_dir(), 'outTemplate.pdf') if os.path.exists(myOutPath): os.remove(myOutPath) myMap.renderTemplate(myInPath, myOutPath) assert os.path.exists(myOutPath)
def test_renderComposition(self): """Test making an image of the map only.""" LOGGER.info('Testing renderComposition') myLayer, _ = loadLayer('test_shakeimpact.shp') myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myRect = QgsRectangle(106.7894, -6.2308, 106.8004, -6.2264) CANVAS.setExtent(myRect) CANVAS.refresh() myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.composeMap() myImagePath, myControlImage, myTargetArea = myMap.renderComposition() LOGGER.debug(myImagePath) assert myControlImage is not None myDimensions = [ myTargetArea.left(), myTargetArea.top(), myTargetArea.bottom(), myTargetArea.right() ] myExpectedDimensions = [0.0, 0.0, 3507.0, 2480.0] myMessage = 'Expected target area to be %s, got %s' % ( str(myExpectedDimensions), str(myDimensions)) assert myExpectedDimensions == myDimensions, myMessage myMessage = 'Rendered output does not exist' assert os.path.exists(myImagePath), myMessage myAcceptableImages = [ 'renderComposition.png', 'renderComposition-variantUB12.04.png', 'renderComposition-variantWindosVistaSP2-32.png', 'renderComposition-variantJenkins.png', 'renderComposition-variantUB11.10-64.png', 'renderComposition-variantUB11.04-64.png' ] # Beta version and version changes can introduce a few extra chars # into the metadata section so we set a reasonable tolerance to cope # with this. myTolerance = 8000 myFlag, myMessage = checkImages(myAcceptableImages, myImagePath, myTolerance) assert myFlag, myMessage
def test_layerChanged(self): """Test the metadata is updated as the user highlights different QGIS layers. For inasafe outputs, the table of results should be shown See also https://github.com/AIFDR/inasafe/issues/58 """ myLayer, myType = loadLayer('issue58.tif') myMessage = ('Unexpected category for issue58.tif.\nGot:' ' %s\nExpected: undefined' % myType) assert myType == 'undefined', myMessage DOCK.layerChanged(myLayer) DOCK.saveState() myHtml = DOCK.state['report'] myExpectedString = '4229' myMessage = "%s\nDoes not contain:\n%s" % (myHtml, myExpectedString) assert myExpectedString in myHtml, myMessage
def test_inasafeMap(self): """Test making a pdf using the Map class.""" myLayer, myType = loadLayer('test_shakeimpact.shp') del myType myCanvasLayer = QgsMapCanvasLayer(myLayer) CANVAS.setLayerSet([myCanvasLayer]) myMap = Map(IFACE) myRect = QgsRectangle(106.7894, -6.2308, 106.8004, -6.2264) CANVAS.setExtent(myRect) CANVAS.refresh() myMap.setImpactLayer(myLayer) myPath = os.path.join(temp_dir(), 'outCustom.pdf') if os.path.exists(myPath): os.remove(myPath) myMap.makePdf(myPath) assert os.path.exists(myPath) # ,, note:: Template writing is experimental myMap.writeTemplate(os.path.join(temp_dir(), 'template.qpt'))
def addSymbolToLegend(self): """Test we can add a symbol to the legend.""" myLayer, myType = loadLayer('test_floodimpact.tif') del myType myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.legend = None mySymbol = QgsSymbol() mySymbol.setColor(QtGui.QColor(12, 34, 56)) myMap.addSymbolToLegend(mySymbol, theMin=0, theMax=2, theCategory=None, theLabel='Foo') myPath = os.path.join(temp_dir(), 'addSymbolToLegend.png') myMap.legend.save(myPath, 'PNG') myExpectedHash = '1234' assertHashForFile(myExpectedHash, myPath)
def test_layerChanged(self): """Test the metadata is updated as the user highlights different QGIS layers. For inasafe outputs, the table of results should be shown See also https://github.com/AIFDR/inasafe/issues/58 """ myLayer, myType = loadLayer('issue58.tif') myMessage = ('Unexpected category for issue58.tif.\nGot:' ' %s\nExpected: undefined' % myType) assert myType == 'undefined', myMessage DOCK.layerChanged(myLayer) DOCK.saveState() myHtml = DOCK.state['report'] myExpectedString = '4229' myMessage = "%s\nDoes not contain:\n%s" % ( myHtml, myExpectedString) assert myExpectedString in myHtml, myMessage
def test_getLegend(self): """Getting a legend for a generic layer works.""" myLayer, myType = loadLayer('test_shakeimpact.shp') del myType myMap = Map(IFACE) myMap.setImpactLayer(myLayer) assert myMap.layer is not None myLegend = myMap.getLegend() myPath = os.path.join(temp_dir(), 'getLegend.png') myLegend.save(myPath, 'PNG') # As we have discovered, different versions of Qt and # OS platforms cause different output, so hashes are a list # of 'known good' renders. myExpectedHashes = ['', # win 'd0c3071c4babe7db4f9762b311d61184', # ub12.04xiner 'b94cfd8a10d709ff28466ada425f24c8', # ub11.04-64 '00dc58aa50867de9b617ccfab0d13f21', # ub12.04 'e65853e217a4c9b0c2f303dd2aadb373', # ub12.04 xvfb 'e4273364b33a943e1108f519dbe8e06c', # ub12.04-64 '91177a81bee4400be4e85789e3be1e91', # binary read '57da6f81b4a55507e1bed0b73423244b', # wVistaSP2-32 ''] assertHashesForFile(myExpectedHashes, myPath)
def test_transparency_of_minimum_value(self): """Test that transparency of minimum value works when set to 100% """ # This dataset has all cells with value 1.3 myLayer, _ = loadLayer('issue126.tif') # Note the float quantity values below myStyleInfo = {} myStyleInfo['style_classes'] = [ {'colour': '#FFFFFF', 'transparency': 100, 'quantity': 0.0}, {'colour': '#38A800', 'quantity': 0.038362596547925065, 'transparency': 0, 'label': u'Rendah [0 orang/sel]'}, {'colour': '#79C900', 'transparency': 0, 'quantity': 0.07672519309585013}, {'colour': '#CEED00', 'transparency': 0, 'quantity': 0.1150877896437752}, {'colour': '#FFCC00', 'quantity': 0.15345038619170026, 'transparency': 0, 'label': u'Sedang [0 orang/sel]'}, {'colour': '#FF6600', 'transparency': 0, 'quantity': 0.19181298273962533}, {'colour': '#FF0000', 'transparency': 0, 'quantity': 0.23017557928755039}, {'colour': '#7A0000', 'quantity': 0.26853817583547546, 'transparency': 0, 'label': u'Tinggi [0 orang/sel]'}] myMessage = 'Could not create raster style' try: setRasterStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) myMessage = ('Should get a single transparency class for first style ' 'class') myTransparencyList = (myLayer.rasterTransparency(). transparentSingleValuePixelList()) self.assertEqual(len(myTransparencyList), 1)
def test_issue121(self): """Test that point symbol size can be set from style (issue 121). .. seealso:: https://github.com/AIFDR/inasafe/issues/121 """ myLayer, myType = loadLayer('kecamatan_jakarta_osm_centroids.shp') del myType # Note the float quantity values below myStyleInfo = {'target_field': 'KEPADATAN', 'style_classes': [{'opacity': 1, 'max': 200, 'colour': '#fecc5c', 'min': 45, 'label': 'Low', 'size': 1}, {'opacity': 1, 'max': 350, 'colour': '#fd8d3c', 'min': 201, 'label': 'Medium', 'size': 2}, {'opacity': 1, 'max': 539, 'colour': '#f31a1c', 'min': 351, 'label': 'High', 'size': 3}]} myMessage = ('Setting style with point sizes should work.') try: setVectorStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the size values were set as expected if myLayer.isUsingRendererV2(): # new symbology - subclass of QgsFeatureRendererV2 class myRenderer = myLayer.rendererV2() myType = myRenderer.type() assert myType == 'graduatedSymbol' mySize = 1 for myRange in myRenderer.ranges(): mySymbol = myRange.symbol() mySymbolLayer = mySymbol.symbolLayer(0) myActualSize = mySymbolLayer.size() myMessage = (('Expected symbol layer 0 for range %s to have' ' a size of %s, got %s') % (mySize, mySize, myActualSize)) assert mySize == myActualSize, myMessage mySize += 1
def test_getRasterLegend(self): """Getting a legend for a raster layer works.""" myLayer, myType = loadLayer('test_floodimpact.tif') del myType myMap = Map(IFACE) myMap.setImpactLayer(myLayer) myMap.getRasterLegend() myPath = os.path.join(temp_dir(), 'getRasterLegend.png') myMap.legend.save(myPath, 'PNG') # As we have discovered, different versions of Qt and # OS platforms cause different output, so hashes are a list # of 'known good' renders. myExpectedHashes = ['', # win '9ead6ce0ac789adc65a6f00bd2d1f709', # ub12.04xiner '84bc3d518e3a0504f8dc36dfd620394e', # ub11.04-64 'b68ccc328de852f0c66b8abe43eab3da', # ub12.04 'cd5fb96f6c5926085d251400dd3b4928', # ub12.04 xvfb 'a654d0dcb6b6d14b0a7a62cd979c16b9', # ub12.04-64 # ub11.04-64 laptop '9692ba8dbf909b8fe3ed27a8f4924b78', # binary read '5f4ef033bb1d6f36af4c08db55ca63be', # wVistaSP2-32 '', ] assertHashesForFile(myExpectedHashes, myPath)
def test_issue126(self): """Test that non integer transparency ranges fail gracefully. .. seealso:: https://github.com/AIFDR/inasafe/issues/126 """ # This dataset has all cells with value 1.3 myLayer, _ = loadLayer('issue126.tif') # Note the float quantity values below myStyleInfo = {} myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=1.1, transparency=100), dict(colour='#38A800', quantity=1.4, transparency=0), dict(colour='#79C900', quantity=10.1, transparency=0)] myMessage = ('Setting style info with float based ranges should fail ' 'gracefully.') try: setRasterStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the transparency values were set to 255 because # they are floats and we cant specify pixel ranges to floats # Note we don't test on the exact interval because 464c6171dd55 myValue1 = myLayer.rasterTransparency().alphaValue(1.2) myValue2 = myLayer.rasterTransparency().alphaValue(1.5) myMessage = ('Transparency should be ignored when style class' ' quantities are floats') assert myValue1 == myValue2 == 255, myMessage # Now run the same test again for int intervals myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=2, transparency=100), dict(colour='#38A800', quantity=4, transparency=0), dict(colour='#79C900', quantity=10, transparency=0)] myMessage = ('Setting style info with generate valid transparent ' 'pixel entries.') try: setRasterStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the transparency values were set to 255 because # they are floats and we cant specify pixel ranges to floats myValue1 = myLayer.rasterTransparency().alphaValue(1) myValue2 = myLayer.rasterTransparency().alphaValue(3) myMessage1 = myMessage + 'Expected 0 got %i' % myValue1 myMessage2 = myMessage + 'Expected 255 got %i' % myValue2 assert myValue1 == 0, myMessage1 assert myValue2 == 255, myMessage2 # Verify that setRasterStyle doesn't break when floats coincide with # integers # See https://github.com/AIFDR/inasafe/issues/126#issuecomment-5978416 myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=2.0, transparency=100), dict(colour='#38A800', quantity=4.0, transparency=0), dict(colour='#79C900', quantity=10.0, transparency=0)] myMessage = ('Broken: Setting style info with generate valid ' 'transparent ' 'floating point pixel entries such as 2.0, 3.0') try: setRasterStyle(myLayer, myStyleInfo) except Exception, e: raise Exception(myMessage + ': ' + str(e))
def test_issue230(self): """Verify that we give informative errors when style is not correct .. seealso:: https://github.com/AIFDR/inasafe/issues/230 """ myPath = unitTestDataPath('impact') myVectorLayer, myType = loadLayer('polygons_for_styling.shp', myPath) del myType myStyle = { 'legend_title': u'Population Count', 'target_field': 'population', 'style_classes': [ { 'transparency': 0, 'min': [0], # <-- intentionally broken list not number! 'max': 139904.08186340332, 'colour': '#FFFFFF', 'size': 1, 'label': u'Nil' }, { 'transparency': 0, 'min': 139904.08186340332, 'max': 279808.16372680664, 'colour': '#38A800', 'size': 1, 'label': u'Low' }, { 'transparency': 0, 'min': 279808.16372680664, 'max': 419712.24559020996, 'colour': '#79C900', 'size': 1, 'label': u'Low' }, { 'transparency': 0, 'min': 419712.24559020996, 'max': 559616.32745361328, 'colour': '#CEED00', 'size': 1, 'label': u'Low' }, { 'transparency': 0, 'min': 559616.32745361328, 'max': 699520.4093170166, 'colour': '#FFCC00', 'size': 1, 'label': u'Medium' }, { 'transparency': 0, 'min': 699520.4093170166, 'max': 839424.49118041992, 'colour': '#FF6600', 'size': 1, 'label': u'Medium' }, { 'transparency': 0, 'min': 839424.49118041992, 'max': 979328.57304382324, 'colour': '#FF0000', 'size': 1, 'label': u'Medium' }, { 'transparency': 0, 'min': 979328.57304382324, 'max': 1119232.6549072266, 'colour': '#7A0000', 'size': 1, 'label': u'High' } ] } try: setVectorStyle(myVectorLayer, myStyle) except StyleError: # Exactly what should have happened return except Exception, e: print str(e)
def test_issue230(self): """Verify that we give informative errors when style is not correct .. seealso:: https://github.com/AIFDR/inasafe/issues/230 """ myPath = unitTestDataPath('impact') myVectorLayer, myType = loadLayer('polygons_for_styling.shp', myPath) del myType myStyle = {'legend_title': u'Population Count', 'target_field': 'population', 'style_classes': [{'transparency': 0, 'min': [0], # <-- intentionally broken list not number! 'max': 139904.08186340332, 'colour': '#FFFFFF', 'size': 1, 'label': u'Nil'}, {'transparency': 0, 'min': 139904.08186340332, 'max': 279808.16372680664, 'colour': '#38A800', 'size': 1, 'label': u'Low'}, {'transparency': 0, 'min': 279808.16372680664, 'max': 419712.24559020996, 'colour': '#79C900', 'size': 1, 'label': u'Low'}, {'transparency': 0, 'min': 419712.24559020996, 'max': 559616.32745361328, 'colour': '#CEED00', 'size': 1, 'label': u'Low'}, {'transparency': 0, 'min': 559616.32745361328, 'max': 699520.4093170166, 'colour': '#FFCC00', 'size': 1, 'label': u'Medium'}, {'transparency': 0, 'min': 699520.4093170166, 'max': 839424.49118041992, 'colour': '#FF6600', 'size': 1, 'label': u'Medium'}, {'transparency': 0, 'min': 839424.49118041992, 'max': 979328.57304382324, 'colour': '#FF0000', 'size': 1, 'label': u'Medium'}, {'transparency': 0, 'min': 979328.57304382324, 'max': 1119232.6549072266, 'colour': '#7A0000', 'size': 1, 'label': u'High'}]} try: setVectorStyle(myVectorLayer, myStyle) except StyleError: # Exactly what should have happened return except Exception, e: print str(e)
def test_issue126(self): """Test that non integer transparency ranges fail gracefully. .. seealso:: https://github.com/AIFDR/inasafe/issues/126 """ # This dataset has all cells with value 1.3 myLayer, myType = loadLayer('issue126.tif') del myType # Note the float quantity values below myStyleInfo = {} myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=1.1, transparency=100), dict(colour='#38A800', quantity=1.4, transparency=0), dict(colour='#79C900', quantity=10.1, transparency=0) ] myMessage = ('Setting style info with float based ranges should fail ' 'gracefully.') try: setRasterStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the transparency values were set to 255 because # they are floats and we cant specify pixel ranges to floats myValue1 = myLayer.rasterTransparency().alphaValue(1.1) myValue2 = myLayer.rasterTransparency().alphaValue(1.4) myMessage = ('Transparency should be ignored when style class' ' quantities are floats') assert myValue1 == myValue2 == 255, myMessage # Now run the same test again myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=2, transparency=100), dict(colour='#38A800', quantity=4, transparency=0), dict(colour='#79C900', quantity=10, transparency=0) ] myMessage = ('Setting style info with generate valid transparent ' 'pixel entries.') try: setRasterStyle(myLayer, myStyleInfo) except: raise Exception(myMessage) # Now validate the transparency values were set to 255 because # they are floats and we cant specify pixel ranges to floats myValue1 = myLayer.rasterTransparency().alphaValue(1) myValue2 = myLayer.rasterTransparency().alphaValue(3) myMessage1 = myMessage + 'Expected 0 got %i' % myValue1 myMessage2 = myMessage + 'Expected 255 got %i' % myValue2 assert myValue1 == 0, myMessage1 assert myValue2 == 255, myMessage2 # Verify that setRasterStyle doesn't break when floats coincide with # integers # See https://github.com/AIFDR/inasafe/issues/126#issuecomment-5978416 myStyleInfo['style_classes'] = [ dict(colour='#38A800', quantity=2.0, transparency=100), dict(colour='#38A800', quantity=4.0, transparency=0), dict(colour='#79C900', quantity=10.0, transparency=0) ] myMessage = ('Broken: Setting style info with generate valid ' 'transparent ' 'floating point pixel entries such as 2.0, 3.0') try: setRasterStyle(myLayer, myStyleInfo) except Exception, e: raise Exception(myMessage + ': ' + str(e))