Esempio n. 1
0
    def init_analysis(self):
        """Setup analysis to make it ready to work.

        .. note:: Copied or adapted from the dock
        """
        self.analysis = Analysis()

        # Impact Function
        impact_function = self.impact_function_manager.get(
            self.parent.selected_function()['id'])
        impact_function.parameters = self.parent.if_params
        self.analysis.impact_function = impact_function

        # Layers
        self.analysis.hazard = self.parent.hazard_layer
        self.analysis.exposure = self.parent.exposure_layer
        self.analysis.aggregation = self.parent.aggregation_layer
        # TODO test if the implement aggregation layer works!

        # Variables
        self.analysis.clip_hard = self.clip_hard
        self.analysis.show_intermediate_layers = self.show_intermediate_layers
        viewport = viewport_geo_array(self.iface.mapCanvas())
        self.analysis.viewport_extent = viewport

        # Extent
        if self.analysis.user_extent:
            self.analysis.user_extent = self.extent.user_extent
            self.analysis.user_extent_crs = self.extent.user_extent_crs
Esempio n. 2
0
    def init_analysis(self):
        """Setup analysis to make it ready to work.

        .. note:: Copied or adapted from the dock
        """
        self.analysis = Analysis()
        # Layers
        self.analysis.hazard_layer = self.parent.hazard_layer
        self.analysis.exposure_layer = self.parent.exposure_layer
        self.analysis.aggregation_layer = self.parent.aggregation_layer
        # TODO test if the implement aggregation layer works!

        # noinspection PyTypeChecker
        self.analysis.hazard_keyword = self.keyword_io.read_keywords(
            self.parent.hazard_layer)
        self.analysis.exposure_keyword = self.keyword_io.read_keywords(
            self.parent.exposure_layer)
        # Need to check since aggregation layer is not mandatory
        if self.analysis.aggregation_layer:
            self.analysis.aggregation_keyword = self.keyword_io.read_keywords(
                self.parent.aggregation_layer)

        # Impact Function
        impact_function = self.impact_function_manager.get(
            self.parent.selected_function()['id'])
        impact_function.parameters = self.parent.if_params
        self.analysis.impact_function = impact_function

        # Variables
        self.analysis.clip_hard = self.clip_hard
        self.analysis.show_intermediate_layers = self.show_intermediate_layers
        self.analysis.run_in_thread_flag = self.run_in_thread_flag
        self.analysis.map_canvas = self.iface.mapCanvas()

        # Extent
        if self.parent.rbExtentUser.isChecked():
            self.analysis.user_extent = self.extent.user_extent
        else:
            self.analysis.user_extent = None
        self.analysis.user_extent_crs = self.extent.user_extent_crs
        self.analysis.clip_to_viewport = self.parent.rbExtentScreen.isChecked()
    def init_analysis(self):
        """Setup analysis to make it ready to work.

        .. note:: Copied or adapted from the dock
        """
        self.analysis = Analysis()
        # Layers
        self.analysis.hazard_layer = self.parent.hazard_layer
        self.analysis.exposure_layer = self.parent.exposure_layer
        self.analysis.aggregation_layer = self.parent.aggregation_layer
        # TODO test if the implement aggregation layer works!

        # noinspection PyTypeChecker
        self.analysis.hazard_keyword = self.keyword_io.read_keywords(
            self.parent.hazard_layer)
        self.analysis.exposure_keyword = self.keyword_io.read_keywords(
            self.parent.exposure_layer)
        # Need to check since aggregation layer is not mandatory
        if self.analysis.aggregation_layer:
            self.analysis.aggregation_keyword = self.keyword_io.read_keywords(
                self.parent.aggregation_layer)

        # Impact Function
        impact_function = self.impact_function_manager.get(
            self.parent.selected_function()['id'])
        impact_function.parameters = self.parent.if_params
        self.analysis.impact_function = impact_function

        # Variables
        self.analysis.clip_hard = self.clip_hard
        self.analysis.show_intermediate_layers = self.show_intermediate_layers
        self.analysis.run_in_thread_flag = self.run_in_thread_flag
        self.analysis.map_canvas = self.iface.mapCanvas()

        # Extent
        if self.parent.rbExtentUser.isChecked():
            self.analysis.user_extent = self.extent.user_extent
        else:
            self.analysis.user_extent = None
        self.analysis.user_extent_crs = self.extent.user_extent_crs
        self.analysis.clip_to_viewport = self.parent.rbExtentScreen.isChecked()
class AnalysisHandler(QObject):

    """Analysis handler for the dock and the wizard."""

    analysisDone = pyqtSignal(bool)

    # noinspection PyUnresolvedReferences
    def __init__(self, parent):
        """Constructor for the class.

        :param parent: Parent widget i.e. the wizard dialog.
        :type parent: QWidget
        """

        QtCore.QObject.__init__(self)
        self.parent = parent
        # Do not delete this
        self.iface = parent.iface
        self.keyword_io = KeywordIO()
        self.impact_function_manager = ImpactFunctionManager()
        self.extent = Extent(self.iface)
        self.analysis = None

        # Values for settings these get set in read_settings.
        self.run_in_thread_flag = None
        self.zoom_to_impact_flag = None
        self.hide_exposure_flag = None
        self.clip_hard = None
        self.show_intermediate_layers = None
        self.show_rubber_bands = False

        self.last_analysis_rubberband = None
        # This is a rubber band to show what the AOI of the
        # next analysis will be. Also added in 2.1.0
        self.next_analysis_rubberband = None

        self.read_settings()

    def enable_signal_receiver(self):
        """Setup dispatcher for all available signal from Analysis.

        .. note:: Adapted from the dock
        """
        dispatcher.connect(
            self.show_busy,
            signal=BUSY_SIGNAL)

        dispatcher.connect(
            self.hide_busy,
            signal=NOT_BUSY_SIGNAL)

        dispatcher.connect(
            self.completed,
            signal=ANALYSIS_DONE_SIGNAL)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(
            self.show_dynamic_message,
            signal=DYNAMIC_MESSAGE_SIGNAL)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(
            self.parent.wvResults.static_message_event,
            signal=STATIC_MESSAGE_SIGNAL,
            sender=dispatcher.Any)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(
            self.parent.wvResults.error_message_event,
            signal=ERROR_MESSAGE_SIGNAL,
            sender=dispatcher.Any)

    def disable_signal_receiver(self):
        """Remove dispatcher for all available signal from Analysis.

        .. note:: Adapted from the dock
        """
        dispatcher.disconnect(
            self.show_busy,
            signal=BUSY_SIGNAL)

        dispatcher.disconnect(
            self.hide_busy,
            signal=NOT_BUSY_SIGNAL)

        dispatcher.disconnect(
            self.completed,
            signal=ANALYSIS_DONE_SIGNAL)

        dispatcher.disconnect(
            self.show_dynamic_message,
            signal=DYNAMIC_MESSAGE_SIGNAL)

    def show_static_message(self, message):
        """Send a static message to the message viewer.

        Static messages cause any previous content in the MessageViewer to be
        replaced with new content.

        .. note:: Copied from the dock

        :param message: An instance of our rich message class.
        :type message: Message

        """
        dispatcher.send(
            signal=STATIC_MESSAGE_SIGNAL,
            sender=self,
            message=message)

    def show_dynamic_message(self, sender, message):
        """Send a dynamic message to the message viewer.

        Dynamic messages are appended to any existing content in the
        MessageViewer.

        .. note:: Modified from the dock

        :param sender: The object that sent the message.
        :type sender: Object, None

        :param message: An instance of our rich message class.
        :type message: Message

        """
        # TODO Hardcoded step - may overflow, if number of messages increase
        self.parent.pbProgress.setValue(self.parent.pbProgress.value() + 15)
        self.parent.wvResults.dynamic_message_event(sender, message)

    def show_error_message(self, error_message):
        """Send an error message to the message viewer.

        Error messages cause any previous content in the MessageViewer to be
        replaced with new content.

        .. note:: Copied from the dock

        :param error_message: An instance of our rich error message class.
        :type error_message: ErrorMessage
        """
        dispatcher.send(
            signal=ERROR_MESSAGE_SIGNAL,
            sender=self,
            message=error_message)
        self.hide_busy()

    def read_settings(self):
        """Restore settings from QSettings.

        Do this on init and after changing options in the options dialog.
        """

        settings = QSettings()

        flag = bool(settings.value(
            'inasafe/showRubberBands', False, type=bool))
        self.extent.show_rubber_bands = flag
        try:
            extent = settings.value('inasafe/analysis_extent', '', type=str)
            crs = settings.value('inasafe/analysis_extent_crs', '', type=str)
        except TypeError:
            # Any bogus stuff in settings and we just clear them
            extent = ''
            crs = ''

        if extent != '' and crs != '':
            extent = extent_string_to_array(extent)
            try:
                self.extent.user_extent = QgsRectangle(*extent)
                self.extent.user_extent_crs = QgsCoordinateReferenceSystem(crs)
                self.extent.show_user_analysis_extent()
            except TypeError:
                self.extent.user_extent = None
                self.extent.user_extent_crs = None

        flag = settings.value(
            'inasafe/useThreadingFlag', False, type=bool)
        self.run_in_thread_flag = flag

        flag = settings.value(
            'inasafe/setZoomToImpactFlag', True, type=bool)
        self.zoom_to_impact_flag = flag

        # whether exposure layer should be hidden after model completes
        flag = settings.value(
            'inasafe/setHideExposureFlag', False, type=bool)
        self.hide_exposure_flag = flag

        # whether to 'hard clip' layers (e.g. cut buildings in half if they
        # lie partially in the AOI
        self.clip_hard = settings.value('inasafe/clip_hard', False, type=bool)

        # whether to show or not postprocessing generated layers
        self.show_intermediate_layers = settings.value(
            'inasafe/show_intermediate_layers', False, type=bool)

        # whether to show or not dev only options
        self.developer_mode = settings.value(
            'inasafe/developer_mode', False, type=bool)

        # whether to show or not a custom Logo
        self.organisation_logo_path = settings.value(
            'inasafe/organisation_logo_path',
            default_organisation_logo_path(),
            type=str)
        flag = bool(settings.value(
            'inasafe/showOrganisationLogoInDockFlag', True, type=bool))

    def show_busy(self):
        """Lock buttons and enable the busy cursor."""
        self.parent.pbnNext.setEnabled(False)
        self.parent.pbnBack.setEnabled(False)
        self.parent.pbnCancel.setEnabled(False)
        QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
        self.parent.repaint()
        QtGui.qApp.processEvents()

    def hide_busy(self):
        """Unlock buttons A helper function to indicate processing is done."""
        self.parent.pbnNext.setEnabled(True)
        self.parent.pbnBack.setEnabled(True)
        self.parent.pbnCancel.setEnabled(True)
        self.parent.repaint()
        QtGui.qApp.restoreOverrideCursor()

    def analysis_error(self, exception, message):
        """A helper to spawn an error and halt processing.

        An exception will be logged, busy status removed and a message
        displayed.

        .. note:: Copied from the dock

        :param message: an ErrorMessage to display
        :type message: ErrorMessage, Message

        :param exception: An exception that was raised
        :type exception: Exception
        """
        self.hide_busy()
        LOGGER.exception(message)
        message = get_error_message(exception, context=message)
        self.show_error_message(message)
        self.analysisDone.emit(False)

    def setup_and_run_analysis(self):
        """Setup and execute the analysis"""
        self.enable_signal_receiver()

        self.show_busy()
        self.init_analysis()
        try:
            self.analysis.setup_analysis()
        except InsufficientOverlapError as e:
            raise e

        self.extent.show_last_analysis_extent(
            self.analysis.clip_parameters[1])

        # Start the analysis
        self.analysis.run_analysis()

        self.disable_signal_receiver()

    def init_analysis(self):
        """Setup analysis to make it ready to work.

        .. note:: Copied or adapted from the dock
        """
        self.analysis = Analysis()
        # Layers
        self.analysis.hazard_layer = self.parent.hazard_layer
        self.analysis.exposure_layer = self.parent.exposure_layer
        self.analysis.aggregation_layer = self.parent.aggregation_layer
        # TODO test if the implement aggregation layer works!

        # noinspection PyTypeChecker
        self.analysis.hazard_keyword = self.keyword_io.read_keywords(
            self.parent.hazard_layer)
        self.analysis.exposure_keyword = self.keyword_io.read_keywords(
            self.parent.exposure_layer)
        # Need to check since aggregation layer is not mandatory
        if self.analysis.aggregation_layer:
            self.analysis.aggregation_keyword = self.keyword_io.read_keywords(
                self.parent.aggregation_layer)

        # Impact Function
        impact_function = self.impact_function_manager.get(
            self.parent.selected_function()['id'])
        impact_function.parameters = self.parent.if_params
        self.analysis.impact_function = impact_function

        # Variables
        self.analysis.clip_hard = self.clip_hard
        self.analysis.show_intermediate_layers = self.show_intermediate_layers
        self.analysis.run_in_thread_flag = self.run_in_thread_flag
        self.analysis.map_canvas = self.iface.mapCanvas()

        # Extent
        if self.parent.rbExtentUser.isChecked():
            self.analysis.user_extent = self.extent.user_extent
        else:
            self.analysis.user_extent = None
        self.analysis.user_extent_crs = self.extent.user_extent_crs
        self.analysis.clip_to_viewport = self.parent.rbExtentScreen.isChecked()

    def completed(self):
        """Slot activated when the process is done.

        .. note:: Adapted from the dock
        """

        # Try to run completion code
        try:
            from datetime import datetime
            LOGGER.debug(datetime.now())
            LOGGER.debug('get engine impact layer')
            LOGGER.debug(self.analysis is None)
            engine_impact_layer = self.analysis.get_impact_layer()

            # Load impact layer into QGIS
            qgis_impact_layer = read_impact_layer(engine_impact_layer)

            report = self.show_results(
                qgis_impact_layer, engine_impact_layer)

        except Exception, e:  # pylint: disable=W0703
            # FIXME (Ole): This branch is not covered by the tests
            self.analysis_error(e, self.tr('Error loading impact layer.'))
        else:
Esempio n. 5
0
def analysis_setup(command_line_arguments, hazard, exposure, aggregation=None):
    """Sets up an analysis object.

    .. versionadded:: 3.2

    :param command_line_arguments: User inputs.
    :type command_line_arguments: CommandLineArguments

    :param hazard: Hazard layer
    :type hazard: QgsLayer

    :param exposure: Exposure Layer
    :type exposure: QgsLayer

    :param aggregation: Aggregation Layer
    :type aggregation: QgsLayer

    :raises: Exception
    """
    # IF
    impact_function_manager = ImpactFunctionManager()
    impact_function = impact_function_manager.get(command_line_arguments.impact_function)
    keyword_io = KeywordIO()

    try:
        from safe.utilities.analysis import Analysis
    except ImportError as ie:
        LOGGER.debug("Import error for Analysis module")
        print ie.message
        raise ImportError
    analysis = Analysis()
    analysis.impact_function = impact_function
    analysis.hazard = hazard
    analysis.exposure = exposure
    analysis.aggregation = aggregation
    # analysis.hazard_keyword = keyword_io.read_keywords(hazard)
    # analysis.exposure_keyword = keyword_io.read_keywords(exposure)
    analysis.clip_hard = False
    analysis.show_intermediate_layers = False
    analysis.run_in_thread_flag = False
    analysis.map_canvas = CANVAS
    # QSetting context
    settings = QSettings()
    crs = settings.value("inasafe/analysis_extent_crs", "", type=str)
    analysis.user_extent_crs = QgsCoordinateReferenceSystem(crs)
    try:
        analysis.user_extent = QgsRectangle(
            float(command_line_arguments.extent[0]),
            float(command_line_arguments.extent[1]),
            float(command_line_arguments.extent[2]),
            float(command_line_arguments.extent[3]),
        )
    except AttributeError:
        print "No extents"
        pass
    analysis.setup_analysis()
    return analysis
Esempio n. 6
0
class AnalysisHandler(QObject):
    """Analysis handler for the dock and the wizard."""

    analysisDone = pyqtSignal(bool)

    # noinspection PyUnresolvedReferences
    def __init__(self, parent):
        """Constructor for the class.

        :param parent: Parent widget i.e. the wizard dialog.
        :type parent: QWidget
        """

        QtCore.QObject.__init__(self)
        self.parent = parent
        # Do not delete this
        self.iface = parent.iface
        self.keyword_io = KeywordIO()

        self.extent = Extent(self.iface)
        self.analysis = None

        # Values for settings these get set in read_settings.
        self.run_in_thread_flag = None
        self.zoom_to_impact_flag = None
        self.hide_exposure_flag = None
        self.clip_hard = None
        self.show_intermediate_layers = None
        self.show_rubber_bands = False

        self.last_analysis_rubberband = None
        # This is a rubber band to show what the AOI of the
        # next analysis will be. Also added in 2.1.0
        self.next_analysis_rubberband = None

        self.read_settings()

    def enable_signal_receiver(self):
        """Setup dispatcher for all available signal from Analysis.

        .. note:: Adapted from the dock
        """
        dispatcher.connect(self.show_busy, signal=BUSY_SIGNAL)

        dispatcher.connect(self.hide_busy, signal=NOT_BUSY_SIGNAL)

        dispatcher.connect(self.completed, signal=ANALYSIS_DONE_SIGNAL)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(self.show_dynamic_message,
                           signal=DYNAMIC_MESSAGE_SIGNAL)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(self.parent.wvResults.static_message_event,
                           signal=STATIC_MESSAGE_SIGNAL,
                           sender=dispatcher.Any)

        # noinspection PyArgumentEqualDefault
        dispatcher.connect(self.parent.wvResults.error_message_event,
                           signal=ERROR_MESSAGE_SIGNAL,
                           sender=dispatcher.Any)

    def disable_signal_receiver(self):
        """Remove dispatcher for all available signal from Analysis.

        .. note:: Adapted from the dock
        """
        dispatcher.disconnect(self.show_busy, signal=BUSY_SIGNAL)

        dispatcher.disconnect(self.hide_busy, signal=NOT_BUSY_SIGNAL)

        dispatcher.disconnect(self.completed, signal=ANALYSIS_DONE_SIGNAL)

        dispatcher.disconnect(self.show_dynamic_message,
                              signal=DYNAMIC_MESSAGE_SIGNAL)

    def show_static_message(self, message):
        """Send a static message to the message viewer.

        Static messages cause any previous content in the MessageViewer to be
        replaced with new content.

        .. note:: Copied from the dock

        :param message: An instance of our rich message class.
        :type message: Message

        """
        dispatcher.send(signal=STATIC_MESSAGE_SIGNAL,
                        sender=self,
                        message=message)

    def show_dynamic_message(self, sender, message):
        """Send a dynamic message to the message viewer.

        Dynamic messages are appended to any existing content in the
        MessageViewer.

        .. note:: Modified from the dock

        :param sender: The object that sent the message.
        :type sender: Object, None

        :param message: An instance of our rich message class.
        :type message: Message

        """
        # TODO Hardcoded step - may overflow, if number of messages increase
        self.parent.pbProgress.setValue(self.parent.pbProgress.value() + 15)
        self.parent.wvResults.dynamic_message_event(sender, message)

    def show_error_message(self, error_message):
        """Send an error message to the message viewer.

        Error messages cause any previous content in the MessageViewer to be
        replaced with new content.

        .. note:: Copied from the dock

        :param error_message: An instance of our rich error message class.
        :type error_message: ErrorMessage
        """
        dispatcher.send(signal=ERROR_MESSAGE_SIGNAL,
                        sender=self,
                        message=error_message)
        self.hide_busy()

    def read_settings(self):
        """Restore settings from QSettings.

        Do this on init and after changing options in the options dialog.
        """

        settings = QSettings()

        flag = bool(settings.value('inasafe/showRubberBands', False,
                                   type=bool))
        self.extent.show_rubber_bands = flag
        try:
            extent = settings.value('inasafe/analysis_extent', '', type=str)
            crs = settings.value('inasafe/analysis_extent_crs', '', type=str)
        except TypeError:
            # Any bogus stuff in settings and we just clear them
            extent = ''
            crs = ''

        if extent != '' and crs != '':
            extent = extent_string_to_array(extent)
            try:
                self.extent.user_extent = QgsRectangle(*extent)
                self.extent.user_extent_crs = QgsCoordinateReferenceSystem(crs)
                self.extent.show_user_analysis_extent()
            except TypeError:
                self.extent.user_extent = None
                self.extent.user_extent_crs = None

        flag = settings.value('inasafe/useThreadingFlag', False, type=bool)
        self.run_in_thread_flag = flag

        flag = settings.value('inasafe/setZoomToImpactFlag', True, type=bool)
        self.zoom_to_impact_flag = flag

        # whether exposure layer should be hidden after model completes
        flag = settings.value('inasafe/setHideExposureFlag', False, type=bool)
        self.hide_exposure_flag = flag

        # whether to 'hard clip' layers (e.g. cut buildings in half if they
        # lie partially in the AOI
        self.clip_hard = settings.value('inasafe/clip_hard', False, type=bool)

        # whether to show or not postprocessing generated layers
        self.show_intermediate_layers = settings.value(
            'inasafe/show_intermediate_layers', False, type=bool)

        # whether to show or not dev only options
        self.developer_mode = settings.value('inasafe/developer_mode',
                                             False,
                                             type=bool)

        # whether to show or not a custom Logo
        self.organisation_logo_path = settings.value(
            'inasafe/organisation_logo_path',
            default_organisation_logo_path(),
            type=str)
        flag = bool(
            settings.value('inasafe/showOrganisationLogoInDockFlag',
                           True,
                           type=bool))

    def show_busy(self):
        """Lock buttons and enable the busy cursor."""
        self.parent.pbnNext.setEnabled(False)
        self.parent.pbnBack.setEnabled(False)
        self.parent.pbnCancel.setEnabled(False)
        QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
        self.parent.repaint()
        QtGui.qApp.processEvents()

    def hide_busy(self):
        """Unlock buttons A helper function to indicate processing is done."""
        self.parent.pbnNext.setEnabled(True)
        self.parent.pbnBack.setEnabled(True)
        self.parent.pbnCancel.setEnabled(True)
        self.parent.repaint()
        QtGui.qApp.restoreOverrideCursor()

    def analysis_error(self, exception, message):
        """A helper to spawn an error and halt processing.

        An exception will be logged, busy status removed and a message
        displayed.

        .. note:: Copied from the dock

        :param message: an ErrorMessage to display
        :type message: ErrorMessage, Message

        :param exception: An exception that was raised
        :type exception: Exception
        """
        self.hide_busy()
        LOGGER.exception(message)
        message = get_error_message(exception, context=message)
        self.show_error_message(message)
        self.analysisDone.emit(False)

    def setup_and_run_analysis(self):
        """Setup and execute the analysis"""
        self.enable_signal_receiver()

        self.show_busy()
        self.init_analysis()
        try:
            self.analysis.setup_analysis()
        except InsufficientOverlapError as e:
            raise e

        self.extent.show_last_analysis_extent(self.analysis.clip_parameters[1])

        # Start the analysis
        self.analysis.run_analysis()

        self.disable_signal_receiver()

    def init_analysis(self):
        """Setup analysis to make it ready to work.

        .. note:: Copied or adapted from the dock
        """
        self.analysis = Analysis()
        # Layers
        self.analysis.hazard_layer = self.parent.hazard_layer
        self.analysis.exposure_layer = self.parent.exposure_layer
        self.analysis.aggregation_layer = self.parent.aggregation_layer
        # TODO test if the implement aggregation layer works!

        # noinspection PyTypeChecker
        self.analysis.hazard_keyword = self.keyword_io.read_keywords(
            self.parent.hazard_layer)
        self.analysis.exposure_keyword = self.keyword_io.read_keywords(
            self.parent.exposure_layer)
        # Need to check since aggregation layer is not mandatory
        if self.analysis.aggregation_layer:
            self.analysis.aggregation_keyword = self.keyword_io.read_keywords(
                self.parent.aggregation_layer)

        # Impact Function
        self.analysis.impact_function_id = self.parent.selected_function(
        )['id']
        self.analysis.impact_function_parameters = self.parent.if_params

        # Variables
        self.analysis.clip_hard = self.clip_hard
        self.analysis.show_intermediate_layers = self.show_intermediate_layers
        self.analysis.run_in_thread_flag = self.run_in_thread_flag
        self.analysis.map_canvas = self.iface.mapCanvas()

        # Extent
        if self.parent.rbExtentUser.isChecked():
            self.analysis.user_extent = self.extent.user_extent
        else:
            self.analysis.user_extent = None
        self.analysis.user_extent_crs = self.extent.user_extent_crs
        self.analysis.clip_to_viewport = self.parent.rbExtentScreen.isChecked()

    def completed(self):
        """Slot activated when the process is done.

        .. note:: Adapted from the dock
        """

        # Try to run completion code
        try:
            from datetime import datetime
            LOGGER.debug(datetime.now())
            LOGGER.debug('get engine impact layer')
            LOGGER.debug(self.analysis is None)
            engine_impact_layer = self.analysis.get_impact_layer()

            # Load impact layer into QGIS
            qgis_impact_layer = read_impact_layer(engine_impact_layer)

            report = self.show_results(qgis_impact_layer, engine_impact_layer)

        except Exception, e:  # pylint: disable=W0703
            # FIXME (Ole): This branch is not covered by the tests
            self.analysis_error(e, self.tr('Error loading impact layer.'))
        else:
Esempio n. 7
0
 def setUp(self):
     self.analysis = Analysis()
Esempio n. 8
0
class TestAnalysis(unittest.TestCase):
    """Test for Analysis class."""
    def setUp(self):
        self.analysis = Analysis()

    def test_get_optimal_extent(self):
        """Optimal extent is calculated correctly
        """

        exposure_path = os.path.join(TESTDATA, 'Population_2010.asc')
        hazard_path = os.path.join(HAZDATA,
                                   'Lembang_Earthquake_Scenario.asc')

        # Expected data
        haz_metadata = {'bounding_box': (105.3000035,
                                         -8.3749994999999995,
                                         110.2914705,
                                         -5.5667784999999999),
                        'resolution': (0.0083330000000000001,
                                       0.0083330000000000001)}

        exp_metadata = {'bounding_box': (94.972335000000001,
                                         -11.009721000000001,
                                         141.0140016666665,
                                         6.0736123333332639),
                        'resolution': (0.0083333333333333003,
                                       0.0083333333333333003)}

        # Verify relevant metada is ok
        H = read_layer(hazard_path)
        E = read_layer(exposure_path)

        hazard_bbox = H.get_bounding_box()
        assert numpy.allclose(hazard_bbox, haz_metadata['bounding_box'],
                              rtol=1.0e-12, atol=1.0e-12)

        exposure_bbox = E.get_bounding_box()
        assert numpy.allclose(exposure_bbox, exp_metadata['bounding_box'],
                              rtol=1.0e-12, atol=1.0e-12)

        hazard_res = H.get_resolution()
        assert numpy.allclose(hazard_res, haz_metadata['resolution'],
                              rtol=1.0e-12, atol=1.0e-12)

        exposure_res = E.get_resolution()
        assert numpy.allclose(exposure_res, exp_metadata['resolution'],
                              rtol=1.0e-12, atol=1.0e-12)

        # First, do some examples that produce valid results
        ref_box = [105.3000035, -8.3749995, 110.2914705, -5.5667785]
        view_port = [94.972335, -11.009721, 141.014002, 6.073612]

        bbox = self.analysis.get_optimal_extent(
            hazard_bbox, exposure_bbox, view_port)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        # testing with viewport clipping disabled
        bbox = self.analysis.get_optimal_extent(
            hazard_bbox, exposure_bbox, None)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        view_port = [105.3000035,
                     -8.3749994999999995,
                     110.2914705,
                     -5.5667784999999999]
        bbox = self.analysis.get_optimal_extent(
            hazard_bbox, exposure_bbox, view_port)
        assert numpy.allclose(bbox, ref_box,
                              rtol=1.0e-12, atol=1.0e-12)

        # Very small viewport fully inside other layers
        view_port = [106.0, -6.0, 108.0, -5.8]
        bbox = self.analysis.get_optimal_extent(
            hazard_bbox, exposure_bbox, view_port)

        assert numpy.allclose(bbox, view_port,
                              rtol=1.0e-12, atol=1.0e-12)

        # viewport that intersects hazard layer
        view_port = [107.0, -6.0, 112.0, -3.0]
        ref_box = [107, -6, 110.2914705, -5.5667785]

        bbox = self.analysis.get_optimal_extent(
            hazard_bbox, exposure_bbox, view_port)
        assert numpy.allclose(bbox, ref_box,
                              rtol=1.0e-12, atol=1.0e-12)

        # Then one where boxes don't overlap
        view_port = [105.3, -4.3, 110.29, -2.5]
        try:
            self.analysis.get_optimal_extent(
                hazard_bbox, exposure_bbox, view_port)
        except InsufficientOverlapError, e:
            message = 'Did not find expected error message in %s' % str(e)
            assert 'did not overlap' in str(e), message
        else:
Esempio n. 9
0
def analysis_execution():

    from safe.test.utilities import get_qgis_app

    # get_qgis_app must be called before importing Analysis
    QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app()

    from safe.utilities.analysis import Analysis
    from safe.utilities.keyword_io import KeywordIO

    analysis = Analysis()

    arg = AnalysisArguments.read_arguments()

    register_impact_functions()

    registry = ImpactFunctionManager().registry

    function = registry.get_instance(arg.impact_function_name)

    hazard_layer = safe_to_qgis_layer(read_layer(arg.hazard_filename))
    exposure_layer = safe_to_qgis_layer(read_layer(arg.exposure_filename))
    if arg.aggregation_filename:
        aggregation_layer = safe_to_qgis_layer(
            read_layer(arg.aggregation_filename))

    keywords_io = KeywordIO()

    try:
        analysis.map_canvas = IFACE.mapCanvas()
        analysis.hazard_layer = hazard_layer
        analysis.hazard_keyword = keywords_io.read_keywords(hazard_layer)
        analysis.exposure_layer = exposure_layer
        analysis.exposure_keyword = keywords_io.read_keywords(exposure_layer)
        if aggregation_layer:
            analysis.aggregation_layer = aggregation_layer
            analysis.aggregation_keyword = keywords_io.read_keywords(
                aggregation_layer)
        analysis.impact_function = function

        analysis.setup_analysis()
        print 'Setup analysis done'
        analysis.run_analysis()
        print 'Analysis done'
    except Exception as e:
        print e.message

    impact = analysis.impact_layer
    qgis_impact = safe_to_qgis_layer(impact)

    generate_styles(impact, qgis_impact)

    copy_impact_layer(impact, arg.impact_filename)
Esempio n. 10
0
    def test_clip_both(self):
        """Raster and Vector layers can be clipped."""

        # Create a vector layer
        layer_name = 'padang'
        vector_layer = QgsVectorLayer(VECTOR_PATH, layer_name, 'ogr')
        message = ('Did not find layer "%s" in path "%s"' %
                   (layer_name, VECTOR_PATH))
        assert vector_layer.isValid(), message

        # Create a raster layer
        layer_name = 'shake'
        raster_layer = QgsRasterLayer(RASTERPATH, layer_name)
        message = ('Did not find layer "%s" in path "%s"' %
                   (layer_name, RASTERPATH))
        assert raster_layer.isValid(), message

        # Create a bounding box
        view_port_geo_extent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        hazard_geo_extent = [
            raster_layer.extent().xMinimum(),
            raster_layer.extent().yMinimum(),
            raster_layer.extent().xMaximum(),
            raster_layer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        exposure_geo_extent = [
            vector_layer.extent().xMinimum(),
            vector_layer.extent().yMinimum(),
            vector_layer.extent().xMaximum(),
            vector_layer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        analysis = Analysis()
        geo_extent = analysis.get_optimal_extent(hazard_geo_extent,
                                                 exposure_geo_extent,
                                                 view_port_geo_extent)

        # Clip the vector to the bbox
        result = clip_layer(vector_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        read_safe_layer(result.source())

        # Clip the raster to the bbox
        result = clip_layer(raster_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        read_safe_layer(result.source())

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        result = clip_layer(vector_layer,
                            geo_extent,
                            extra_keywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()
        # message = 'Extra keyword was not found in %s: %s' % (myResult,
        # keywords)
        assert keywords['kermit'] == 'piggy'

        # Clip the raster to the bbox
        result = clip_layer(raster_layer,
                            geo_extent,
                            extra_keywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()

        message = ('Extra keyword was not found in %s: %s' %
                   (result.source(), keywords))
        assert keywords['zoot'] == 'animal', message
Esempio n. 11
0
    def test_clip_both(self):
        """Raster and Vector layers can be clipped."""

        # Create a vector layer
        layer_name = 'padang'
        vector_layer = QgsVectorLayer(VECTOR_PATH, layer_name, 'ogr')
        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, VECTOR_PATH))
        assert vector_layer.isValid(), message

        # Create a raster layer
        layer_name = 'shake'
        raster_layer = QgsRasterLayer(RASTERPATH, layer_name)
        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH))
        assert raster_layer.isValid(), message

        # Create a bounding box
        view_port_geo_extent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        hazard_geo_extent = [
            raster_layer.extent().xMinimum(),
            raster_layer.extent().yMinimum(),
            raster_layer.extent().xMaximum(),
            raster_layer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        exposure_geo_extent = [
            vector_layer.extent().xMinimum(),
            vector_layer.extent().yMinimum(),
            vector_layer.extent().xMaximum(),
            vector_layer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        analysis = Analysis()
        geo_extent = analysis.get_optimal_extent(
            hazard_geo_extent, exposure_geo_extent, view_port_geo_extent)

        # Clip the vector to the bbox
        result = clip_layer(vector_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        read_safe_layer(result.source())

        # Clip the raster to the bbox
        result = clip_layer(raster_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        read_safe_layer(result.source())

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        result = clip_layer(
            vector_layer, geo_extent, extra_keywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()
        # message = 'Extra keyword was not found in %s: %s' % (myResult,
        # keywords)
        assert keywords['kermit'] == 'piggy'

        # Clip the raster to the bbox
        result = clip_layer(
            raster_layer, geo_extent, extra_keywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()

        message = ('Extra keyword was not found in %s: %s' %
                   (result.source(), keywords))
        assert keywords['zoot'] == 'animal', message
Esempio n. 12
0
def analysis_setup(command_line_arguments, hazard, exposure, aggregation=None):
    """Sets up an analysis object.

    .. versionadded:: 3.2

    :param command_line_arguments: User inputs.
    :type command_line_arguments: CommandLineArguments

    :param hazard: Hazard layer
    :type hazard: QgsLayer

    :param exposure: Exposure Layer
    :type exposure: QgsLayer

    :param aggregation: Aggregation Layer
    :type aggregation: QgsLayer

    :raises: Exception
    """
    # IF
    impact_function_manager = ImpactFunctionManager()
    impact_function = impact_function_manager.get(
        command_line_arguments.impact_function)
    keyword_io = KeywordIO()

    try:
        from safe.utilities.analysis import Analysis
    except ImportError as ie:
        LOGGER.debug('Import error for Analysis module')
        print ie.message
        raise ImportError
    analysis = Analysis()
    analysis.impact_function = impact_function
    analysis.hazard = hazard
    analysis.exposure = exposure
    analysis.aggregation = aggregation
    # analysis.hazard_keyword = keyword_io.read_keywords(hazard)
    # analysis.exposure_keyword = keyword_io.read_keywords(exposure)
    analysis.clip_hard = False
    analysis.show_intermediate_layers = False
    analysis.run_in_thread_flag = False
    analysis.map_canvas = CANVAS
    # QSetting context
    settings = QSettings()
    crs = settings.value('inasafe/analysis_extent_crs', '', type=str)
    analysis.user_extent_crs = QgsCoordinateReferenceSystem(crs)
    try:
        analysis.user_extent = QgsRectangle(
            float(command_line_arguments.extent[0]),
            float(command_line_arguments.extent[1]),
            float(command_line_arguments.extent[2]),
            float(command_line_arguments.extent[3]))
    except AttributeError:
        print "No extents"
        pass
    analysis.setup_analysis()
    return analysis
Esempio n. 13
0
def analysis_execution():

    from safe.test.utilities import get_qgis_app

    # get_qgis_app must be called before importing Analysis
    QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app()

    from safe.utilities.analysis import Analysis
    from safe.utilities.keyword_io import KeywordIO

    analysis = Analysis()

    arg = AnalysisArguments.read_arguments()

    register_impact_functions()

    registry = ImpactFunctionManager().registry

    function = registry.get_instance(arg.impact_function_name)

    hazard_layer = safe_to_qgis_layer(read_layer(arg.hazard_filename))
    exposure_layer = safe_to_qgis_layer(read_layer(arg.exposure_filename))
    if arg.aggregation_filename:
        aggregation_layer = safe_to_qgis_layer(read_layer(
            arg.aggregation_filename))

    keywords_io = KeywordIO()

    try:
        analysis.map_canvas = IFACE.mapCanvas()
        analysis.hazard_layer = hazard_layer
        analysis.hazard_keyword = keywords_io.read_keywords(hazard_layer)
        analysis.exposure_layer = exposure_layer
        analysis.exposure_keyword = keywords_io.read_keywords(exposure_layer)
        if aggregation_layer:
            analysis.aggregation_layer = aggregation_layer
            analysis.aggregation_keyword = keywords_io.read_keywords(
                aggregation_layer)
        analysis.impact_function = function

        analysis.setup_analysis()
        print 'Setup analysis done'
        analysis.run_analysis()
        print 'Analysis done'
    except Exception as e:
        print e.message

    impact = analysis.impact_layer
    qgis_impact = safe_to_qgis_layer(impact)

    generate_styles(impact, qgis_impact)

    copy_impact_layer(impact, arg.impact_filename)
Esempio n. 14
0
 def setUp(self):
     self.analysis = Analysis()
Esempio n. 15
0
class TestAnalysis(unittest.TestCase):
    """Test for Analysis class."""
    def setUp(self):
        self.analysis = Analysis()

    def test_get_optimal_extent(self):
        """Optimal extent is calculated correctly
        """

        exposure_path = os.path.join(TESTDATA, 'Population_2010.asc')
        hazard_path = os.path.join(HAZDATA, 'Lembang_Earthquake_Scenario.asc')

        # Expected data
        haz_metadata = {
            'bounding_box': (105.3000035, -8.3749994999999995, 110.2914705,
                             -5.5667784999999999),
            'resolution': (0.0083330000000000001, 0.0083330000000000001)
        }

        exp_metadata = {
            'bounding_box': (94.972335000000001, -11.009721000000001,
                             141.0140016666665, 6.0736123333332639),
            'resolution': (0.0083333333333333003, 0.0083333333333333003)
        }

        # Verify relevant metada is ok
        H = read_layer(hazard_path)
        E = read_layer(exposure_path)

        hazard_bbox = H.get_bounding_box()
        assert numpy.allclose(hazard_bbox,
                              haz_metadata['bounding_box'],
                              rtol=1.0e-12,
                              atol=1.0e-12)

        exposure_bbox = E.get_bounding_box()
        assert numpy.allclose(exposure_bbox,
                              exp_metadata['bounding_box'],
                              rtol=1.0e-12,
                              atol=1.0e-12)

        hazard_res = H.get_resolution()
        assert numpy.allclose(hazard_res,
                              haz_metadata['resolution'],
                              rtol=1.0e-12,
                              atol=1.0e-12)

        exposure_res = E.get_resolution()
        assert numpy.allclose(exposure_res,
                              exp_metadata['resolution'],
                              rtol=1.0e-12,
                              atol=1.0e-12)

        # First, do some examples that produce valid results
        ref_box = [105.3000035, -8.3749995, 110.2914705, -5.5667785]
        view_port = [94.972335, -11.009721, 141.014002, 6.073612]

        bbox = self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                                view_port)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        # testing with viewport clipping disabled
        bbox = self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                                None)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        view_port = [
            105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999
        ]
        bbox = self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                                view_port)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        # Very small viewport fully inside other layers
        view_port = [106.0, -6.0, 108.0, -5.8]
        bbox = self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                                view_port)

        assert numpy.allclose(bbox, view_port, rtol=1.0e-12, atol=1.0e-12)

        # viewport that intersects hazard layer
        view_port = [107.0, -6.0, 112.0, -3.0]
        ref_box = [107, -6, 110.2914705, -5.5667785]

        bbox = self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                                view_port)
        assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12)

        # Then one where boxes don't overlap
        view_port = [105.3, -4.3, 110.29, -2.5]
        try:
            self.analysis.get_optimal_extent(hazard_bbox, exposure_bbox,
                                             view_port)
        except InsufficientOverlapError, e:
            message = 'Did not find expected error message in %s' % str(e)
            assert 'did not overlap' in str(e), message
        else: