def load_layers( layer_list, clear_flag=True, data_directory=TESTDATA, dock=None): """Helper function to load layers as defined in a python list. :param dock: A valid dock instance. :type dock: Dock :param data_directory: Path to where data should be loaded from. Defaults to TESTDATA directory. :type data_directory: str :param clear_flag: Whether to clear currently loaded layers before loading the new layers. :type clear_flag: bool :param layer_list: A list of layers to load. :type layer_list: list(str) """ # First unload any layers that may already be loaded if clear_flag: # noinspection PyArgumentList QgsMapLayerRegistry.instance().removeAllMapLayers() # Now go ahead and load our layers myExposureLayerCount = 0 myHazardLayerCount = 0 map_layer_list = [] # Now create our new layers for myFile in layer_list: myLayer, myType = load_layer(myFile, data_directory) if myType == 'hazard': myHazardLayerCount += 1 elif myType == 'exposure': myExposureLayerCount += 1 # Add layer to the registry (that QGis knows about) a slot # in qgis_interface will also ensure it gets added to the canvas if qgis_version() >= 10800: # 1.8 or newer, defer loading # noinspection PyArgumentList map_layer_list.append(myLayer) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) # Save time by loading all layers in one operation if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers(map_layer_list) if dock is not None: dock.get_layers() # Add MCL's to the CANVAS return myHazardLayerCount, myExposureLayerCount
def load_layers(layer_list, clear_flag=True, data_directory=TESTDATA, dock=None): """Helper function to load layers as defined in a python list. :param dock: A valid dock instance. :type dock: Dock :param data_directory: Path to where data should be loaded from. Defaults to TESTDATA directory. :type data_directory: str :param clear_flag: Whether to clear currently loaded layers before loading the new layers. :type clear_flag: bool :param layer_list: A list of layers to load. :type layer_list: list(str) """ # First unload any layers that may already be loaded if clear_flag: # noinspection PyArgumentList QgsMapLayerRegistry.instance().removeAllMapLayers() # Now go ahead and load our layers myExposureLayerCount = 0 myHazardLayerCount = 0 map_layer_list = [] # Now create our new layers for myFile in layer_list: myLayer, myType = load_layer(myFile, data_directory) if myType == 'hazard': myHazardLayerCount += 1 elif myType == 'exposure': myExposureLayerCount += 1 # Add layer to the registry (that QGis knows about) a slot # in qgis_interface will also ensure it gets added to the canvas if qgis_version() >= 10800: # 1.8 or newer, defer loading # noinspection PyArgumentList map_layer_list.append(myLayer) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) # Save time by loading all layers in one operation if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers(map_layer_list) if dock is not None: dock.get_layers() # Add MCL's to the CANVAS return myHazardLayerCount, myExposureLayerCount
def test_issue71(self): """Test issue #71 in github - cbo changes should update ok button.""" # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button print 'Using QGIS: %s' % qgis_version() self.tearDown() button = DOCK.pbnRunStop # First part of scenario should have enabled run file_list = [ join(HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc'), join(TESTDATA, 'Population_Jakarta_geographic.asc')] hazard_layer_count, exposure_layer_count = load_layers( file_list, data_directory=None) message = ( 'Incorrect number of Hazard layers: expected 1 got %s' % hazard_layer_count) self.assertTrue(hazard_layer_count == 1, message) message = ( 'Incorrect number of Exposure layers: expected 1 got %s' % exposure_layer_count) self.assertTrue(exposure_layer_count == 1, message) message = 'Run button was not enabled' self.assertTrue(button.isEnabled(), message) # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled file_list = ['issue71.tif'] # This layer has incorrect keywords clear_flag = False _, _ = load_layers(file_list, clear_flag) # set exposure to : Population Density Estimate (5kmx5km) # by moving one down DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() + 1) actual_dict = get_ui_state(DOCK) expected_dict = { 'Run Button Enabled': False, 'Impact Function Id': '', 'Impact Function Title': '', 'Hazard': 'A flood in Jakarta like in 2007', 'Exposure': 'Population density (5kmx5km)'} message = (( 'Run button was not disabled when exposure set to \n%s' '\nUI State: \n%s\nExpected State:\n%s\n%s') % ( DOCK.cboExposure.currentText(), actual_dict, expected_dict, combos_to_string(DOCK))) self.assertTrue(expected_dict == actual_dict, message) # Now select again a valid layer and the run button # should be enabled DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() - 1) message = ( 'Run button was not enabled when exposure set to \n%s' % DOCK.cboExposure.currentText()) self.assertTrue(button.isEnabled(), message)
def raster_legend(self): """Get the legend for a raster layer as an image. :returns: An image representing the layer's legend. self.legend is also populated. :rtype: QImage :Raises: InvalidLegendLayer will be raised if a legend cannot be created from the layer. """ LOGGER.debug('InaSAFE Map Legend getRasterLegend called') # test if QGIS 1.8.0 or older # see issue #259 if qgis_version() <= 10800: myShader = self.layer.rasterShader().rasterShaderFunction() myRampItems = myShader.colorRampItemList() myLastValue = 0 # Making an assumption here... LOGGER.debug('Source: %s' % self.layer.source()) for myItem in myRampItems: myValue = myItem.value myLabel = myItem.label myColor = myItem.color self.add_class(myColor, minimum=myLastValue, maximum=myValue, label=myLabel, class_type='rasterStyle') myLastValue = myValue else: #TODO implement QGIS2.0 variant #In master branch, use QgsRasterRenderer::rasterRenderer() to # get/set how a raster is displayed. pass self.add_notes() return self.legendImage
def setRasterStyle(raster_layer, style): """Set QGIS raster style based on InaSAFE style dictionary. This function will set both the colour map and the transparency for the passed in layer. :param raster_layer: A QGIS raster layer that will be styled. :type raster_layer: QgsVectorLayer :param style: Dictionary of the form as in the example below. :type style: dict Example: style_classes = [dict(colour='#38A800', quantity=2, transparency=0), dict(colour='#38A800', quantity=5, transparency=50), dict(colour='#79C900', quantity=10, transparency=50), dict(colour='#CEED00', quantity=20, transparency=50), dict(colour='#FFCC00', quantity=50, transparency=34), dict(colour='#FF6600', quantity=100, transparency=77), dict(colour='#FF0000', quantity=200, transparency=24), dict(colour='#7A0000', quantity=300, transparency=22)] :returns: A two tuple containing a range list and a transparency list. :rtype: (list, list) """ myNewStyles = add_extrema_to_style(style['style_classes']) # test if QGIS 1.8.0 or older # see issue #259 if qgis_version() <= 10800: LOGGER.debug('Rendering raster using <= 1.8 styling') return set_legacy_raster_style(raster_layer, myNewStyles) else: LOGGER.debug('Rendering raster using 2+ styling') return set_new_raster_style(raster_layer, myNewStyles)
def test_issue71(self): """Test issue #71 in github - cbo changes should update ok button.""" # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button print 'Using QGIS: %s' % qgis_version() self.tearDown() myButton = DOCK.pbnRunStop # First part of scenario should have enabled run myFileList = [ join(HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc'), join(TESTDATA, 'Population_Jakarta_geographic.asc') ] myHazardLayerCount, myExposureLayerCount = load_layers( myFileList, data_directory=None) myMessage = ('Incorrect number of Hazard layers: expected 1 got %s' % myHazardLayerCount) assert myHazardLayerCount == 1, myMessage myMessage = ('Incorrect number of Exposure layers: expected 1 got %s' % myExposureLayerCount) assert myExposureLayerCount == 1, myMessage myMessage = 'Run button was not enabled' assert myButton.isEnabled(), myMessage # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled myFileList = ['issue71.tif'] # This layer has incorrect keywords myClearFlag = False _, _ = load_layers(myFileList, myClearFlag) # set exposure to : Population Density Estimate (5kmx5km) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Down) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Enter) myDict = get_ui_state(DOCK) myExpectedDict = { 'Run Button Enabled': False, 'Impact Function Id': '', 'Impact Function Title': '', 'Hazard': 'A flood in Jakarta like in 2007', 'Exposure': 'Population density (5kmx5km)' } myMessage = (('Run button was not disabled when exposure set to \n%s' '\nUI State: \n%s\nExpected State:\n%s\n%s') % (DOCK.cboExposure.currentText(), myDict, myExpectedDict, combos_to_string(DOCK))) assert myExpectedDict == myDict, myMessage # Now select again a valid layer and the run button # should be enabled # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Up) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Enter) myMessage = ('Run button was not enabled when exposure set to \n%s' % DOCK.cboExposure.currentText()) assert myButton.isEnabled(), myMessage
def test_issue71(self): """Test issue #71 in github - cbo changes should update ok button.""" # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button print 'Using QGIS: %s' % qgis_version() self.tearDown() myButton = DOCK.pbnRunStop # First part of scenario should have enabled run myFileList = [join(HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc'), join(TESTDATA, 'Population_Jakarta_geographic.asc')] myHazardLayerCount, myExposureLayerCount = load_layers( myFileList, data_directory=None) myMessage = ('Incorrect number of Hazard layers: expected 1 got %s' % myHazardLayerCount) assert myHazardLayerCount == 1, myMessage myMessage = ('Incorrect number of Exposure layers: expected 1 got %s' % myExposureLayerCount) assert myExposureLayerCount == 1, myMessage myMessage = 'Run button was not enabled' assert myButton.isEnabled(), myMessage # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled myFileList = ['issue71.tif'] # This layer has incorrect keywords myClearFlag = False _, _ = load_layers(myFileList, myClearFlag) # set exposure to : Population Density Estimate (5kmx5km) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Down) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Enter) myDict = get_ui_state(DOCK) myExpectedDict = {'Run Button Enabled': False, 'Impact Function Id': '', 'Impact Function Title': '', 'Hazard': 'A flood in Jakarta like in 2007', 'Exposure': 'Population density (5kmx5km)'} myMessage = (('Run button was not disabled when exposure set to \n%s' '\nUI State: \n%s\nExpected State:\n%s\n%s') % (DOCK.cboExposure.currentText(), myDict, myExpectedDict, combos_to_string(DOCK))) assert myExpectedDict == myDict, myMessage # Now select again a valid layer and the run button # should be enabled # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Up) # noinspection PyCallByClass,PyTypeChecker QTest.keyClick(DOCK.cboExposure, QtCore.Qt.Key_Enter) myMessage = ('Run button was not enabled when exposure set to \n%s' % DOCK.cboExposure.currentText()) assert myButton.isEnabled(), myMessage
def test_clipGeometry(self): """Test that we can clip a geometry using another geometry.""" myGeometry = QgsGeometry.fromPolyline([ QgsPoint(10, 10), QgsPoint(20, 20), QgsPoint(30, 30), QgsPoint(40, 40) ]) myClipPolygon = QgsGeometry.fromPolygon([[ QgsPoint(20, 20), QgsPoint(20, 30), QgsPoint(30, 30), QgsPoint(30, 20), QgsPoint(20, 20) ]]) myResult = clip_geometry(myClipPolygon, myGeometry) myExpectedWkt = 'LINESTRING(20.0 20.0, 30.0 30.0)' # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(myExpectedWkt, str(myResult.exportToWkt())) # Now poly on poly clip test myClipPolygon = QgsGeometry.fromWkt( 'POLYGON((106.8218 -6.1842,106.8232 -6.1842,' '106.82304963 -6.18317148,106.82179736 -6.18314774,' '106.8218 -6.1842))') myGeometry = QgsGeometry.fromWkt( 'POLYGON((106.8216869 -6.1852067,106.8213233 -6.1843051,' '106.8212891 -6.1835559,106.8222566 -6.1835184,' '106.8227557 -6.1835076,106.8228588 -6.1851204,' '106.8216869 -6.1852067))') myResult = clip_geometry(myClipPolygon, myGeometry) myExpectedWkt = ( 'POLYGON((106.82179833 -6.18353616,106.8222566 -6.1835184,' '106.8227557 -6.1835076,106.82279996 -6.1842,' '106.8218 -6.1842,106.82179833 -6.18353616))') # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(myExpectedWkt, str(myResult.exportToWkt())) # Now point on poly test clip myGeometry = QgsGeometry.fromWkt('POINT(106.82241 -6.18369)') myResult = clip_geometry(myClipPolygon, myGeometry) if qgis_version() > 10800: myExpectedWkt = 'POINT(106.82241 -6.18369)' else: myExpectedWkt = 'POINT(106.822410 -6.183690)' # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(myExpectedWkt, str(myResult.exportToWkt()))
def test_clip_geometry(self): """Test that we can clip a geometry using another geometry.""" geometry = QgsGeometry.fromPolyline([ QgsPoint(10, 10), QgsPoint(20, 20), QgsPoint(30, 30), QgsPoint(40, 40)] ) clip_polygon = QgsGeometry.fromPolygon([ [QgsPoint(20, 20), QgsPoint(20, 30), QgsPoint(30, 30), QgsPoint(30, 20), QgsPoint(20, 20)]] ) result = clip_geometry(clip_polygon, geometry) expected_wkt = 'LINESTRING(20.0 20.0, 30.0 30.0)' # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(expected_wkt, str(result.exportToWkt())) # Now poly on poly clip test clip_polygon = QgsGeometry.fromWkt( 'POLYGON((106.8218 -6.1842,106.8232 -6.1842,' '106.82304963 -6.18317148,106.82179736 -6.18314774,' '106.8218 -6.1842))') geometry = QgsGeometry.fromWkt( 'POLYGON((106.8216869 -6.1852067,106.8213233 -6.1843051,' '106.8212891 -6.1835559,106.8222566 -6.1835184,' '106.8227557 -6.1835076,106.8228588 -6.1851204,' '106.8216869 -6.1852067))') result = clip_geometry(clip_polygon, geometry) expected_wkt = ( 'POLYGON((106.82179833 -6.18353616,106.8222566 -6.1835184,' '106.8227557 -6.1835076,106.82279996 -6.1842,' '106.8218 -6.1842,106.82179833 -6.18353616))') # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(expected_wkt, str(result.exportToWkt())) # Now point on poly test clip geometry = QgsGeometry.fromWkt('POINT(106.82241 -6.18369)') result = clip_geometry(clip_polygon, geometry) if qgis_version() > 10800: expected_wkt = 'POINT(106.82241 -6.18369)' else: expected_wkt = 'POINT(106.822410 -6.183690)' # There should only be one feature that intersects this clip # poly so this assertion should work. assert compare_wkt(expected_wkt, str(result.exportToWkt()))
def test_windowsDrawingArtifacts(self): """Test that windows rendering does not make artifacts""" # sometimes spurious lines are drawn on the layout LOGGER.info('Testing windowsDrawingArtifacts') myPath = unique_filename( prefix='artifacts', suffix='.pdf', dir=temp_dir('test')) myMap = Map(IFACE) setup_printer(myPath) myMap.setup_composition() myImage = QtGui.QImage(10, 10, QtGui.QImage.Format_RGB32) myImage.setDotsPerMeterX(dpi_to_meters(300)) myImage.setDotsPerMeterY(dpi_to_meters(300)) #myImage.fill(QtGui.QColor(250, 250, 250)) # Look at the output, you will see antialiasing issues around some # of the boxes drawn... # myImage.fill(QtGui.QColor(200, 200, 200)) myImage.fill(200 + 200 * 256 + 200 * 256 * 256) myFilename = os.path.join(temp_dir(), 'greyBox') myImage.save(myFilename, 'PNG') for i in range(10, 190, 10): myPicture = QgsComposerPicture(myMap.composition) myPicture.setPictureFile(myFilename) if qgis_version() >= 10800: # 1.8 or newer myPicture.setFrameEnabled(False) else: myPicture.setFrame(False) myPicture.setItemPosition(i, # x i, # y 10, # width 10) # height myMap.composition.addItem(myPicture) # Same drawing drawn directly as a pixmap # noinspection PyCallByClass,PyTypeChecker,PyArgumentList myPixmapItem = myMap.composition.addPixmap( QtGui.QPixmap.fromImage(myImage)) myPixmapItem.setOffset(i, i + 20) # Same drawing using our drawImage Helper myWidthMM = 1 myMap.draw_image(myImage, myWidthMM, i, i + 40) myImagePath, _, _ = myMap.render() # when this test no longer matches our broken render hash # we know the issue is fixed myTolerance = 0 myFlag, myMessage = check_images( 'windowsArtifacts', myImagePath, myTolerance) myMessage += ('\nWe want these images to match, if they do not ' 'there may be rendering artifacts in windows.\n') assert myFlag, myMessage
def test_save_scenario(self): """Test saving Current scenario.""" result, message = setup_scenario( DOCK, hazard='Flood in Jakarta', exposure='Penduduk Jakarta', function='Be impacted', function_id='Categorised Hazard Population Impact Function') self.assertTrue(result, message) # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) set_jakarta_extent() # create unique file scenario_file = unique_filename( prefix='scenarioTest', suffix='.txt', dir=temp_dir('test')) self.save_scenario_dialog.save_scenario( scenario_file_path=scenario_file) with open(scenario_file) as f: data = f.readlines() title = data[0][:-1] exposure = data[1][:-1] hazard = data[2][:-1] function = data[3][:-1] extent = data[4][:-1] self.assertTrue( os.path.exists(scenario_file), 'File %s does not exist' % scenario_file) self.assertTrue(title == '[Flood in Jakarta]', 'Title is not the same') self.assertTrue( exposure.startswith('exposure =') and exposure.endswith( 'Population_Jakarta_geographic.asc'), 'Exposure is not the same') self.assertTrue( hazard.startswith('hazard =') and hazard.endswith( 'jakarta_flood_category_123.asc'), 'Hazard is not the same') self.assertTrue( function == ( 'function = Categorised Hazard Population Impact Function'), 'Impact function is not same') # TODO: figure out why this changed between releases if qgis_version() < 20400: # For QGIS 2.0 expected_extent = ( 'extent = 106.313333, -6.380000, 107.346667, -6.070000') self.assertEqual(expected_extent, extent) else: # for QGIS 2.4 expected_extent = ( 'extent = 106.287500, -6.380000, 107.372500, -6.070000') self.assertEqual(expected_extent, expected_extent)
def test_save_scenario(self): """Test saving Current scenario.""" result, message = setup_scenario( DOCK, hazard='Flood in Jakarta', exposure='Penduduk Jakarta', function='Be impacted', function_id='Categorised Hazard Population Impact Function') self.assertTrue(result, message) # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) set_jakarta_extent(dock=DOCK) # create unique file scenario_file = unique_filename( prefix='scenarioTest', suffix='.txt', dir=temp_dir('test')) self.save_scenario_dialog.save_scenario( scenario_file_path=scenario_file) with open(scenario_file) as f: data = f.readlines() title = data[0][:-1] exposure = data[1][:-1] hazard = data[2][:-1] function = data[3][:-1] extent = data[4][:-1] self.assertTrue( os.path.exists(scenario_file), 'File %s does not exist' % scenario_file) self.assertTrue(title == '[Flood in Jakarta]', 'Title is not the same') self.assertTrue( exposure.startswith('exposure =') and exposure.endswith( 'Population_Jakarta_geographic.asc'), 'Exposure is not the same') self.assertTrue( hazard.startswith('hazard =') and hazard.endswith( 'jakarta_flood_category_123.asc'), 'Hazard is not the same') self.assertTrue( function == ( 'function = Categorised Hazard Population Impact Function'), 'Impact function is not same') # TODO: figure out why this changed between releases if qgis_version() < 20400: # For QGIS 2.0 expected_extent = ( 'extent = 106.313333, -6.380000, 107.346667, -6.070000') self.assertEqual(expected_extent, extent) else: # for QGIS 2.4 expected_extent = ( 'extent = 106.287500, -6.380000, 107.372500, -6.070000') self.assertEqual(expected_extent, expected_extent)
def test_issue160(self): """Test that multipart features can be used in a scenario - issue #160 """ myExposure = os.path.join(UNITDATA, 'exposure', 'buildings_osm_4326.shp') myHazard = os.path.join(UNITDATA, 'hazard', 'multipart_polygons_osm_4326.shp') # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button print 'Using QGIS: %s' % qgis_version() self.tearDown() myButton = DOCK.pbnRunStop # First part of scenario should have enabled run myFileList = [myHazard, myExposure] myHazardLayerCount, myExposureLayerCount = load_layers(myFileList) myMessage = ('Incorrect number of Hazard layers: expected 1 got %s' % myHazardLayerCount) assert myHazardLayerCount == 1, myMessage myMessage = ('Incorrect number of Exposure layers: expected 1 got %s' % myExposureLayerCount) assert myExposureLayerCount == 1, myMessage myMessage = 'Run button was not enabled' assert myButton.isEnabled(), myMessage # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled myFileList = ['issue71.tif'] # This layer has incorrect keywords myClearFlag = False _, _ = load_layers(myFileList, myClearFlag) myResult, myMessage = setup_scenario( DOCK, hazard='multipart_polygons_osm_4326', exposure='buildings_osm_4326', function='Be flooded', function_id='Flood Building Impact Function') assert myResult, myMessage # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) IFACE.mapCanvas().setExtent( QgsRectangle(106.788, -6.193, 106.853, -6.167)) # Press RUN # noinspection PyCallByClass,PyCallByClass,PyTypeChecker DOCK.accept() myResult = DOCK.wvResults.page_to_text() myMessage = 'Result not as expected: %s' % myResult assert format_int(68) in myResult, myMessage
def make_keywordless_layer(): """Helper function that returns a single predefined keywordless layer.""" path = 'keywordless_layer.tif' base_path = test_data_path('hazard') full_path = os.path.abspath(os.path.join(base_path, path)) title = 'Keywordless Layer' layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def make_keywordless_layer(): """Helper function that returns a single predefined keywordless layer""" myFile = 'keywordless_layer.tif' myBasePath = test_data_path('hazard') myPath = os.path.abspath(os.path.join(myBasePath, myFile)) myTitle = 'Keywordless Layer' myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_padang_layer(): """Helper function that returns a single predefined layer.""" path = 'Shakemap_Padang_2009.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') # title = 'An earthquake in Padang like in 2009' layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def makePadangLayer(): """Helper function that returns a single predefined layer""" myFile = 'Shakemap_Padang_2009.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = readKeywordsFromFile(myPath, 'title') # myTitle = 'An earthquake in Padang like in 2009' myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_keywordless_layer(): """Helper function that returns a single predefined keywordless layer.""" path = 'keywordless_layer.tif' base_path = test_data_path('hazard') full_path = os.path.abspath(os.path.join(base_path, path)) title = 'Keywordless Layer' layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer
def draw_logo(self, top_offset): """Add a picture containing the logo to the map top left corner :param top_offset: Vertical offset at which the logo should be drawn. :type top_offset: int """ myLogo = QgsComposerPicture(self.composition) myLogo.setPictureFile(':/plugins/inasafe/bnpb_logo.png') myLogo.setItemPosition(self.pageMargin, top_offset, 10, 10) if qgis_version() >= 10800: # 1.8 or newer myLogo.setFrameEnabled(self.showFramesFlag) else: myLogo.setFrame(self.showFramesFlag) myLogo.setZValue(1) # To ensure it overlays graticule markers self.composition.addItem(myLogo)
def make_polygon_layer(): """Helper function that returns a single predefined layer.""" path = 'kabupaten_jakarta_singlepart_3_good_attr.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def makePolygonLayer(): """Helper function that returns a single predefined layer""" myFile = 'kabupaten_jakarta_singlepart_3_good_attr.shp' myPath = os.path.join(TESTDATA, myFile) try: myTitle = readKeywordsFromFile(myPath, 'title') except KeywordNotFoundError: myTitle = 'kabupaten_jakarta_singlepart_3_good_attr' myLayer = QgsVectorLayer(myPath, myTitle, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_polygon_layer(): """Helper function that returns a single predefined layer.""" path = 'kabupaten_jakarta_singlepart_3_good_attr.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer
def makePadangLayerClone(): """Helper function that copies padang keyword for testing and return it.""" mySourceFileName = 'Shakemap_Padang_2009' myExts = ['.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld'] myFileName = unique_filename() # copy to temp file for ext in myExts: mySourcePath = os.path.join(HAZDATA, mySourceFileName + ext) myDestPath = os.path.join(HAZDATA, myFileName + ext) shutil.copy2(mySourcePath, myDestPath) # return a single predefined layer myFile = myFileName + '.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = readKeywordsFromFile(myPath, 'title') myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer, myFileName
def clone_padang_layer(): """Helper function that copies padang keyword for testing and return it.""" path = 'Shakemap_Padang_2009' extensions = [ '.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld'] temp_path = unique_filename() # copy to temp file for ext in extensions: source_path = os.path.join(HAZDATA, path + ext) dest_path = os.path.join(HAZDATA, temp_path + ext) shutil.copy2(source_path, dest_path) # return a single predefined layer path = temp_path + '.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer, temp_path
def getRasterLegend(self): """Get the legend for a raster layer as an image. Args: None Returns: An image representing the layer's legend. self.legend is also populated Raises: An InvalidLegendLayer will be raised if a legend cannot be created from the layer. """ LOGGER.debug('InaSAFE Map Legend getRasterLegend called') # test if QGIS 1.8.0 or older # see issue #259 if qgis_version() <= 10800: myShader = self.layer.rasterShader().rasterShaderFunction() myRampItems = myShader.colorRampItemList() myLastValue = 0 # Making an assumption here... LOGGER.debug('Source: %s' % self.layer.source()) for myItem in myRampItems: myValue = myItem.value myLabel = myItem.label myColor = myItem.color self.addClassToLegend(myColor, theMin=myLastValue, theMax=myValue, theLabel=myLabel, theType='rasterStyle') myLastValue = myValue else: #TODO implement QGIS2.0 variant #In master branch, use QgsRasterRenderer::rasterRenderer() to # get/set how a raster is displayed. pass self.addLegendNotes() return self.legendImage
def are_keywords_file_based(self, layer): """Check if keywords should be read/written to file or our keywords db. :param layer: The layer which want to know how the keywords are stored. :type layer: QgsMapLayer :returns: True if keywords are stored in a file next to the dataset, else False if the dataset is remove e.g. a database. :rtype: bool """ # determine which keyword lookup system to use (file base or cache db) # based on the layer's provider type. True indicates we should use the # datasource as a file and look for a keywords file, false and we look # in the keywords db. myProviderType = None myVersion = qgis_version() # check for old raster api with qgis < 1.8 # ..todo:: Add test for plugin layers too if (myVersion < 10800 and layer.type() == QgsMapLayer.RasterLayer): myProviderType = str(layer.providerKey()) else: myProviderType = str(layer.providerType()) myProviderDict = { 'ogr': True, 'gdal': True, 'gpx': False, 'wms': False, 'spatialite': False, 'delimitedtext': True, 'postgres': False } myFileBasedKeywords = False if myProviderType in myProviderDict: myFileBasedKeywords = myProviderDict[myProviderType] return myFileBasedKeywords
def are_keywords_file_based(self, layer): """Check if keywords should be read/written to file or our keywords db. :param layer: The layer which want to know how the keywords are stored. :type layer: QgsMapLayer :returns: True if keywords are stored in a file next to the dataset, else False if the dataset is remove e.g. a database. :rtype: bool """ # determine which keyword lookup system to use (file base or cache db) # based on the layer's provider type. True indicates we should use the # datasource as a file and look for a keywords file, false and we look # in the keywords db. myProviderType = None myVersion = qgis_version() # check for old raster api with qgis < 1.8 # ..todo:: Add test for plugin layers too if (myVersion < 10800 and layer.type() == QgsMapLayer.RasterLayer): myProviderType = str(layer.providerKey()) else: myProviderType = str(layer.providerType()) myProviderDict = {'ogr': True, 'gdal': True, 'gpx': False, 'wms': False, 'spatialite': False, 'delimitedtext': True, 'postgres': False} myFileBasedKeywords = False if myProviderType in myProviderDict: myFileBasedKeywords = myProviderDict[myProviderType] return myFileBasedKeywords
def clone_padang_layer(): """Helper function that copies padang keyword for testing and return it.""" path = 'Shakemap_Padang_2009' extensions = [ '.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld' ] temp_path = unique_filename() # copy to temp file for ext in extensions: source_path = os.path.join(HAZDATA, path + ext) dest_path = os.path.join(HAZDATA, temp_path + ext) shutil.copy2(source_path, dest_path) # return a single predefined layer path = temp_path + '.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer, temp_path
def test_getQgisVersion(self): """Test we can get the version of QGIS""" myVersion = qgis_version() myMessage = 'Got version %s of QGIS, but at least 107000 is needed' assert myVersion > 10700, myMessage
def load_template(self): """Load a QgsComposer map from a template. :raises: TemplateElementMissingError - when template elements are missing """ template_file = QtCore.QFile(self.template) template_file.open(QtCore.QIODevice.ReadOnly | QtCore.QIODevice.Text) template_content = template_file.readAll() template_file.close() document = QtXml.QDomDocument() document.setContent(template_content) # get information for substitutions # date, time and plugin version date_time = self.keyword_io.read_keywords(self.layer, 'time_stamp') if date_time is None: date = '' time = '' else: tokens = date_time.split('_') date = tokens[0] time = tokens[1] long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) title = self.map_title() if not title: title = '' substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, 'disclaimer': self.disclaimer } LOGGER.debug(substitution_map) load_ok = self.composition.loadFromTemplate(document, substitution_map) if not load_ok: raise ReportCreationError( self.tr('Error loading template %s') % self.template) self.page_width = self.composition.paperWidth() self.page_height = self.composition.paperHeight() # set InaSAFE logo image = self.composition.getComposerItemById('safe-logo') if image is not None: image.setPictureFile(self.safe_logo) # set north arrow image = self.composition.getComposerItemById('north-arrow') if image is not None: image.setPictureFile(self.north_arrow) # set organisation logo image = self.composition.getComposerItemById('organisation-logo') if image is not None: image.setPictureFile(self.org_logo) # set impact report table table = self.composition.getComposerItemById('impact-report') if table is not None: text = self.keyword_io.read_keywords(self.layer, 'impact_summary') if text is None: text = '' table.setText(text) table.setHtmlState(1) # Get the main map canvas on the composition and set # its extents to the event. composer_map = self.composition.getComposerItemById('impact-map') if composer_map is not None: # Recenter the composer map on the center of the extent # Note that since the composer map is square and the canvas may be # arbitrarily shaped, we center based on the longest edge canvas_extent = self.extent width = canvas_extent.width() height = canvas_extent.height() longest_width = width if width < height: longest_width = height half_length = longest_width / 2 center = canvas_extent.center() min_x = center.x() - half_length max_x = center.x() + half_length min_y = center.y() - half_length max_y = center.y() + half_length square_extent = QgsRectangle(min_x, min_y, max_x, max_y) composer_map.setNewExtent(square_extent) # calculate intervals for grid split_count = 5 x_interval = square_extent.width() / split_count composer_map.setGridIntervalX(x_interval) y_interval = square_extent.height() / split_count composer_map.setGridIntervalY(y_interval) legend = self.composition.getComposerItemById('impact-legend') if legend is not None: legend_attributes = self.map_legend_attributes() LOGGER.debug(legend_attributes) # legend_notes = mapLegendAttributes.get('legend_notes', None) # legend_units = mapLegendAttributes.get('legend_units', None) legend_title = legend_attributes.get('legend_title', None) symbol_count = 1 if self.layer.type() == QgsMapLayer.VectorLayer: renderer = self.layer.rendererV2() if renderer.type() in ['', '']: symbol_count = len(self.layer.legendSymbologyItems()) else: renderer = self.layer.renderer() if renderer.type() in ['']: symbol_count = len(self.layer.legendSymbologyItems()) if symbol_count <= 5: legend.setColumnCount(1) else: legend.setColumnCount(symbol_count / 5 + 1) if legend_title is None: legend_title = "" legend.setTitle(legend_title) legend.updateLegend() # Set Legend # From QGIS 2.6, legend.model() is obsolete if qgis_version() < 20600: legend.model().setLayerSet([self.layer.id()]) legend.synchronizeWithModel() else: root_group = legend.modelV2().rootGroup() root_group.addLayer(self.layer) legend.synchronizeWithModel()