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
Example #2
0
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
Example #3
0
    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)
Example #4
0
    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
Example #5
0
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)
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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()))
Example #9
0
    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()))
Example #10
0
    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
Example #11
0
    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)
Example #13
0
    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
Example #14
0
    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
Example #15
0
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
Example #16
0
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
Example #17
0
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
Example #18
0
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_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
Example #20
0
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
Example #21
0
    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)
Example #22
0
    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)
Example #23
0
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
Example #24
0
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
Example #25
0
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
Example #26
0
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
Example #27
0
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
Example #28
0
    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
Example #29
0
    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
Example #30
0
    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
Example #31
0
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
Example #32
0
 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
Example #33
0
 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
Example #34
0
    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()