Esempio n. 1
0
    def test_classification_thresholds(self):
        """Test for classification_thresholds method."""
        thresholds = default_classification_thresholds(flood_hazard_classes)
        wet_class = flood_hazard_classes['classes'][0]
        dry_class = flood_hazard_classes['classes'][1]

        expected = {
            'dry': [
                dry_class['numeric_default_min'],
                dry_class['numeric_default_max']
            ],
            'wet': [
                wet_class['numeric_default_min'],
                wet_class['numeric_default_max']
            ]
        }
        self.assertDictEqual(thresholds, expected)

        unit_knots_key = unit_knots['key']
        thresholds = default_classification_thresholds(
            cyclone_au_bom_hazard_classes, unit_knots_key)
        category_5_class = cyclone_au_bom_hazard_classes['classes'][0]
        category_4_class = cyclone_au_bom_hazard_classes['classes'][1]
        category_3_class = cyclone_au_bom_hazard_classes['classes'][2]
        category_2_class = cyclone_au_bom_hazard_classes['classes'][3]
        category_1_class = cyclone_au_bom_hazard_classes['classes'][4]
        tropical_depression_class = cyclone_au_bom_hazard_classes['classes'][5]
        expected = {
            'tropical_depression': [
                tropical_depression_class['numeric_default_min'],
                tropical_depression_class['numeric_default_max']
                [unit_knots_key]
            ],
            'category_1': [
                category_1_class['numeric_default_min'][unit_knots_key],
                category_1_class['numeric_default_max'][unit_knots_key]
            ],
            'category_2': [
                category_2_class['numeric_default_min'][unit_knots_key],
                category_2_class['numeric_default_max'][unit_knots_key]
            ],
            'category_3': [
                category_3_class['numeric_default_min'][unit_knots_key],
                category_3_class['numeric_default_max'][unit_knots_key]
            ],
            'category_4': [
                category_4_class['numeric_default_min'][unit_knots_key],
                category_4_class['numeric_default_max'][unit_knots_key]
            ],
            'category_5': [
                category_5_class['numeric_default_min'][unit_knots_key],
                category_5_class['numeric_default_max']
            ]
        }
        self.assertDictEqual(thresholds, expected)
Esempio n. 2
0
    def test_classification_thresholds(self):
        """Test for classification_thresholds method."""
        thresholds = default_classification_thresholds(flood_hazard_classes)
        wet_class = flood_hazard_classes['classes'][0]
        dry_class = flood_hazard_classes['classes'][1]

        expected = {
            'dry': [
                dry_class['numeric_default_min'],
                dry_class['numeric_default_max']
            ],
            'wet': [
                wet_class['numeric_default_min'],
                wet_class['numeric_default_max']
            ]
        }
        self.assertDictEqual(thresholds, expected)

        unit_knots_key = unit_knots['key']
        thresholds = default_classification_thresholds(
            cyclone_au_bom_hazard_classes, unit_knots_key)
        category_5_class = cyclone_au_bom_hazard_classes['classes'][0]
        category_4_class = cyclone_au_bom_hazard_classes['classes'][1]
        category_3_class = cyclone_au_bom_hazard_classes['classes'][2]
        category_2_class = cyclone_au_bom_hazard_classes['classes'][3]
        category_1_class = cyclone_au_bom_hazard_classes['classes'][4]
        tropical_depression_class = cyclone_au_bom_hazard_classes['classes'][5]
        expected = {
            'tropical_depression': [
                tropical_depression_class['numeric_default_min'],
                tropical_depression_class['numeric_default_max'][
                    unit_knots_key]
            ],
            'category_1': [
                category_1_class['numeric_default_min'][unit_knots_key],
                category_1_class['numeric_default_max'][unit_knots_key]
            ],
            'category_2': [
                category_2_class['numeric_default_min'][unit_knots_key],
                category_2_class['numeric_default_max'][unit_knots_key]
            ],
            'category_3': [
                category_3_class['numeric_default_min'][unit_knots_key],
                category_3_class['numeric_default_max'][unit_knots_key]
            ],
            'category_4': [
                category_4_class['numeric_default_min'][unit_knots_key],
                category_4_class['numeric_default_max'][unit_knots_key]
            ],
            'category_5': [
                category_5_class['numeric_default_min'][unit_knots_key],
                category_5_class['numeric_default_max']
            ]
        }
        self.assertDictEqual(thresholds, expected)
Esempio n. 3
0
    def activate_classification(self, exposure, classification=None):
        """Set active to True for classification for the exposure.

        If classification = None, all classification set active = False.

        :param exposure: Exposure definition.
        :type exposure: dict

        :param classification: Classification definition.
        :type classification: dict
        """
        if self.layer_mode == layer_mode_continuous:
            selected_unit = self.parent.step_kw_unit.selected_unit()['key']
            target = self.thresholds.get(exposure['key'])
            if target is None:
                self.thresholds[exposure['key']] = {}
            target = self.thresholds.get(exposure['key'])
        else:
            selected_unit = None
            target = self.value_maps.get(exposure['key'])
            if target is None:
                self.value_maps[exposure['key']] = {}
            target = self.value_maps.get(exposure['key'])

        if classification is not None:
            if classification['key'] not in target:
                if self.layer_mode == layer_mode_continuous:
                    default_classes = default_classification_thresholds(
                        classification, selected_unit)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                else:
                    default_classes = default_classification_value_maps(
                        classification)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                return

        for classification_key, value in target.items():
            if classification is None:
                value['active'] = False
                continue

            if classification_key == classification['key']:
                value['active'] = True
            else:
                value['active'] = False
    def activate_classification(self, exposure, classification=None):
        """Set active to True for classification for the exposure.

        If classification = None, all classification set active = False.

        :param exposure: Exposure definition.
        :type exposure: dict

        :param classification: Classification definition.
        :type classification: dict
        """
        if self.layer_mode == layer_mode_continuous:
            selected_unit = self.parent.step_kw_unit.selected_unit()['key']
            target = self.thresholds.get(exposure['key'])
            if target is None:
                self.thresholds[exposure['key']] = {}
            target = self.thresholds.get(exposure['key'])
        else:
            selected_unit = None
            target = self.value_maps.get(exposure['key'])
            if target is None:
                self.value_maps[exposure['key']] = {}
            target = self.value_maps.get(exposure['key'])

        if classification is not None:
            if classification['key'] not in target:
                if self.layer_mode == layer_mode_continuous:
                    default_classes = default_classification_thresholds(
                        classification, selected_unit)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                else:
                    default_classes = default_classification_value_maps(
                        classification)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                return

        for classification_key, value in target.items():
            if classification is None:
                value['active'] = False
                continue

            if classification_key == classification['key']:
                value['active'] = True
            else:
                value['active'] = False
Esempio n. 5
0
    def create_keyword_file(self, algorithm):
        """Create keyword file for the raster file created.

        Basically copy a template from keyword file in converter data
        and add extra keyword (usually a title)

        :param algorithm: Which re-sampling algorithm to use.
            valid options are 'nearest' (for nearest neighbour), 'invdist'
            (for inverse distance), 'average' (for moving average). Defaults
            to 'nearest' if not specified. Note that passing re-sampling alg
            parameters is currently not supported. If None is passed it will
            be replaced with 'nearest'.
        :type algorithm: str
        """
        keyword_io = KeywordIO()

        # Set thresholds for each exposure
        mmi_default_classes = default_classification_thresholds(
            earthquake_mmi_scale)
        mmi_default_threshold = {
            earthquake_mmi_scale['key']: {
                'active': True,
                'classes': mmi_default_classes
            }
        }
        generic_default_classes = default_classification_thresholds(
            generic_hazard_classes)
        generic_default_threshold = {
            generic_hazard_classes['key']: {
                'active': True,
                'classes': generic_default_classes
            }
        }

        threshold_keyword = {}
        for exposure in exposure_all:
            # Not all exposure is supported by earthquake_mmi_scale
            if exposure in earthquake_mmi_scale['exposures']:
                threshold_keyword[exposure['key']] = mmi_default_threshold
            else:
                threshold_keyword[exposure['key']] = generic_default_threshold

        extra_keywords = {
            extra_keyword_earthquake_latitude['key']:
            self.latitude,
            extra_keyword_earthquake_longitude['key']:
            self.longitude,
            extra_keyword_earthquake_magnitude['key']:
            self.magnitude,
            extra_keyword_earthquake_depth['key']:
            self.depth,
            extra_keyword_earthquake_description['key']:
            self.description,
            extra_keyword_earthquake_location['key']:
            self.location,
            extra_keyword_earthquake_event_time['key']:
            self.time.strftime('%Y-%m-%dT%H:%M:%S'),
            extra_keyword_time_zone['key']:
            self.time_zone,
            extra_keyword_earthquake_x_minimum['key']:
            self.x_minimum,
            extra_keyword_earthquake_x_maximum['key']:
            self.x_maximum,
            extra_keyword_earthquake_y_minimum['key']:
            self.y_minimum,
            extra_keyword_earthquake_y_maximum['key']:
            self.y_maximum,
            extra_keyword_earthquake_event_id['key']:
            self.event_id
        }
        for key, value in self.extra_keywords.items():
            extra_keywords[key] = value

        # Delete empty element.
        empty_keys = []
        for key, value in extra_keywords.items():
            if value is None:
                empty_keys.append(key)
        for empty_key in empty_keys:
            extra_keywords.pop(empty_key)
        keywords = {
            'hazard': hazard_earthquake['key'],
            'hazard_category': hazard_category_single_event['key'],
            'keyword_version': inasafe_keyword_version,
            'layer_geometry': layer_geometry_raster['key'],
            'layer_mode': layer_mode_continuous['key'],
            'layer_purpose': layer_purpose_hazard['key'],
            'continuous_hazard_unit': unit_mmi['key'],
            'classification': earthquake_mmi_scale['key'],
            'thresholds': threshold_keyword,
            'extra_keywords': extra_keywords,
            'active_band': 1
        }

        if self.algorithm_name:
            layer_path = os.path.join(
                self.output_dir,
                '%s-%s.tif' % (self.output_basename, algorithm))
        else:
            layer_path = os.path.join(self.output_dir,
                                      '%s.tif' % self.output_basename)

        # append title and source to the keywords file
        if len(self.title.strip()) == 0:
            keyword_title = self.output_basename
        else:
            keyword_title = self.title

        keywords['title'] = keyword_title

        hazard_layer = QgsRasterLayer(layer_path, keyword_title)

        if not hazard_layer.isValid():
            raise InvalidLayerError()

        keyword_io.write_keywords(hazard_layer, keywords)
Esempio n. 6
0
    def setup_left_panel(self):
        """Setup the UI for left panel.

        Generate all exposure, combobox, and edit button.
        """
        hazard = self.parent.step_kw_subcategory.selected_subcategory()
        left_panel_heading = QLabel(tr('Classifications'))
        left_panel_heading.setFont(big_font)
        self.left_layout.addWidget(left_panel_heading)

        inner_left_layout = QGridLayout()

        row = 0
        for exposure in exposure_all:
            special_case = False
            # Filter out unsupported exposure for the hazard
            if exposure in hazard['disabled_exposures']:
                # Remove from the storage if the exposure is disabled
                if self.layer_mode == layer_mode_continuous:
                    if exposure['key'] in self.thresholds:
                        self.thresholds.pop(exposure['key'])
                else:
                    if exposure['key'] in self.value_maps:
                        self.value_maps.pop(exposure['key'])
                continue
            # Trick for EQ raster for population #3853
            if exposure == exposure_population and hazard == hazard_earthquake:
                if is_raster_layer(self.parent.layer):
                    if self.layer_mode == layer_mode_continuous:
                        self.use_default_thresholds = True
                        special_case = True
                        # Set classification for EQ Raster for Population
                        self.thresholds[exposure_population['key']] = {
                            earthquake_mmi_scale['key']: {
                                'classes': default_classification_thresholds(
                                    earthquake_mmi_scale),
                                'active': True
                            }
                        }

            # Add label
            # Hazard on Exposure Classifications
            label = tr(
                '{hazard_name} on {exposure_name} Classifications').format(
                hazard_name=hazard['name'],
                exposure_name=exposure['name']
            )
            exposure_label = QLabel(label)

            # Add combo box
            exposure_combo_box = QComboBox()
            hazard_classifications = hazard.get('classifications')
            exposure_combo_box.addItem(tr('No classifications'))
            exposure_combo_box.setItemData(
                0, None, Qt.UserRole)

            current_index = 0
            i = 0
            # Iterate through all available hazard classifications
            for hazard_classification in hazard_classifications:
                # Skip if the classification is not for the exposure
                if 'exposures' in hazard_classification:
                    if exposure not in hazard_classification['exposures']:
                        continue
                exposure_combo_box.addItem(hazard_classification['name'])
                exposure_combo_box.setItemData(
                    i + 1, hazard_classification, Qt.UserRole)
                if self.layer_mode == layer_mode_continuous:
                    current_hazard_classifications = self.thresholds.get(
                        exposure['key'])
                else:
                    current_hazard_classifications = self.value_maps.get(
                        exposure['key'])
                if current_hazard_classifications:
                    current_hazard_classification = \
                        current_hazard_classifications.get(
                            hazard_classification['key'])
                    if current_hazard_classification:
                        is_active = current_hazard_classification.get('active')
                        if is_active:
                            current_index = i + 1
                i += 1
            # Set current classification
            exposure_combo_box.setCurrentIndex(current_index)

            # Add edit button
            exposure_edit_button = QPushButton(tr('Edit'))

            # For special case. Raster EQ on Population.
            if special_case:
                mmi_index = exposure_combo_box.findText(
                    earthquake_mmi_scale['name'])
                exposure_combo_box.setCurrentIndex(mmi_index)
                exposure_combo_box.setEnabled(False)
                exposure_edit_button.setEnabled(False)
                tool_tip_message = tr(
                    'InaSAFE use default classification for Raster Earthquake '
                    'hazard on population.')
                exposure_label.setToolTip(tool_tip_message)
                exposure_combo_box.setToolTip(tool_tip_message)
                exposure_edit_button.setToolTip(tool_tip_message)

            else:
                if current_index == 0:
                    # Disable if there is no classification chosen.
                    exposure_edit_button.setEnabled(False)
                exposure_edit_button.clicked.connect(
                    partial(self.edit_button_clicked,
                        edit_button=exposure_edit_button,
                        exposure_combo_box=exposure_combo_box,
                        exposure=exposure))
                exposure_combo_box.currentIndexChanged.connect(
                    partial(
                        self.classifications_combo_box_changed,
                        exposure=exposure,
                        exposure_combo_box=exposure_combo_box,
                        edit_button=exposure_edit_button))

            # Arrange in layout
            inner_left_layout.addWidget(exposure_label, row, 0)
            inner_left_layout.addWidget(exposure_combo_box, row, 1)
            inner_left_layout.addWidget(exposure_edit_button, row, 2)

            # Adding to step's attribute
            self.exposures.append(exposure)
            self.exposure_combo_boxes.append(exposure_combo_box)
            self.exposure_edit_buttons.append(exposure_edit_button)
            self.exposure_labels.append(label)
            if special_case:
                self.special_case_index = len(self.exposures) - 1

            row += 1

        self.left_layout.addLayout(inner_left_layout)
        # To push the inner_left_layout up
        self.left_layout.addStretch(1)
    def setup_left_panel(self):
        """Setup the UI for left panel.

        Generate all exposure, combobox, and edit button.
        """
        hazard = self.parent.step_kw_subcategory.selected_subcategory()
        left_panel_heading = QLabel(tr('Classifications'))
        left_panel_heading.setFont(big_font)
        self.left_layout.addWidget(left_panel_heading)

        inner_left_layout = QGridLayout()

        row = 0
        for exposure in exposure_all:
            special_case = False
            # Filter out unsupported exposure for the hazard
            if exposure in hazard['disabled_exposures']:
                # Remove from the storage if the exposure is disabled
                if self.layer_mode == layer_mode_continuous:
                    if exposure['key'] in self.thresholds:
                        self.thresholds.pop(exposure['key'])
                else:
                    if exposure['key'] in self.value_maps:
                        self.value_maps.pop(exposure['key'])
                continue
            # Trick for EQ raster for population #3853
            if exposure == exposure_population and hazard == hazard_earthquake:
                if is_raster_layer(self.parent.layer):
                    if self.layer_mode == layer_mode_continuous:
                        self.use_default_thresholds = True
                        special_case = True
                        # Set classification for EQ Raster for Population
                        self.thresholds[exposure_population['key']] = {
                            earthquake_mmi_scale['key']: {
                                'classes': default_classification_thresholds(
                                    earthquake_mmi_scale),
                                'active': True
                            }
                        }

            # Add label
            # Hazard on Exposure Classifications
            label = tr(
                '{hazard_name} on {exposure_name} Classifications').format(
                hazard_name=hazard['name'],
                exposure_name=exposure['name']
            )
            exposure_label = QLabel(label)

            # Add combo box
            exposure_combo_box = QComboBox()
            hazard_classifications = hazard.get('classifications')
            exposure_combo_box.addItem(tr('No classifications'))
            exposure_combo_box.setItemData(
                0, None, Qt.UserRole)

            current_index = 0
            i = 0
            # Iterate through all available hazard classifications
            for hazard_classification in hazard_classifications:
                # Skip if the classification is not for the exposure
                if 'exposures' in hazard_classification:
                    if exposure not in hazard_classification['exposures']:
                        continue
                exposure_combo_box.addItem(hazard_classification['name'])
                exposure_combo_box.setItemData(
                    i + 1, hazard_classification, Qt.UserRole)
                if self.layer_mode == layer_mode_continuous:
                    current_hazard_classifications = self.thresholds.get(
                        exposure['key'])
                else:
                    current_hazard_classifications = self.value_maps.get(
                        exposure['key'])
                if current_hazard_classifications:
                    current_hazard_classification = \
                        current_hazard_classifications.get(
                            hazard_classification['key'])
                    if current_hazard_classification:
                        is_active = current_hazard_classification.get('active')
                        if is_active:
                            current_index = i + 1
                i += 1
            # Set current classification
            exposure_combo_box.setCurrentIndex(current_index)

            # Add edit button
            exposure_edit_button = QPushButton(tr('Edit'))

            # For special case. Raster EQ on Population.
            if special_case:
                mmi_index = exposure_combo_box.findText(
                    earthquake_mmi_scale['name'])
                exposure_combo_box.setCurrentIndex(mmi_index)
                exposure_combo_box.setEnabled(False)
                exposure_edit_button.setEnabled(False)
                tool_tip_message = tr(
                    'InaSAFE use default classification for Raster Earthquake '
                    'hazard on population.')
                exposure_label.setToolTip(tool_tip_message)
                exposure_combo_box.setToolTip(tool_tip_message)
                exposure_edit_button.setToolTip(tool_tip_message)

            else:
                if current_index == 0:
                    # Disable if there is no classification chosen.
                    exposure_edit_button.setEnabled(False)
                exposure_edit_button.clicked.connect(
                    partial(self.edit_button_clicked,
                        edit_button=exposure_edit_button,
                        exposure_combo_box=exposure_combo_box,
                        exposure=exposure))
                exposure_combo_box.currentIndexChanged.connect(
                    partial(
                        self.classifications_combo_box_changed,
                        exposure=exposure,
                        exposure_combo_box=exposure_combo_box,
                        edit_button=exposure_edit_button))

            # Arrange in layout
            inner_left_layout.addWidget(exposure_label, row, 0)
            inner_left_layout.addWidget(exposure_combo_box, row, 1)
            inner_left_layout.addWidget(exposure_edit_button, row, 2)

            # Adding to step's attribute
            self.exposures.append(exposure)
            self.exposure_combo_boxes.append(exposure_combo_box)
            self.exposure_edit_buttons.append(exposure_edit_button)
            self.exposure_labels.append(label)
            if special_case:
                self.special_case_index = len(self.exposures) - 1

            row += 1

        self.left_layout.addLayout(inner_left_layout)
        # To push the inner_left_layout up
        self.left_layout.addStretch(1)
Esempio n. 8
0
    def create_keyword_file(self, algorithm):
        """Create keyword file for the raster file created.

        Basically copy a template from keyword file in converter data
        and add extra keyword (usually a title)

        :param algorithm: Which re-sampling algorithm to use.
            valid options are 'nearest' (for nearest neighbour), 'invdist'
            (for inverse distance), 'average' (for moving average). Defaults
            to 'nearest' if not specified. Note that passing re-sampling alg
            parameters is currently not supported. If None is passed it will
            be replaced with 'nearest'.
        :type algorithm: str
        """
        keyword_io = KeywordIO()

        # Set thresholds for each exposure
        mmi_default_classes = default_classification_thresholds(
            earthquake_mmi_scale
        )
        mmi_default_threshold = {
            earthquake_mmi_scale['key']: {
                'active': True,
                'classes': mmi_default_classes
            }
        }
        generic_default_classes = default_classification_thresholds(
            generic_hazard_classes
        )
        generic_default_threshold = {
            generic_hazard_classes['key']: {
                'active': True,
                'classes': generic_default_classes
            }
        }

        threshold_keyword = {}
        for exposure in exposure_all:
            # Not all exposure is supported by earthquake_mmi_scale
            if exposure in earthquake_mmi_scale['exposures']:
                threshold_keyword[exposure['key']] = mmi_default_threshold
            else:
                threshold_keyword[
                    exposure['key']] = generic_default_threshold

        extra_keywords = {
            extra_keyword_earthquake_latitude['key']: self.latitude,
            extra_keyword_earthquake_longitude['key']: self.longitude,
            extra_keyword_earthquake_magnitude['key']: self.magnitude,
            extra_keyword_earthquake_depth['key']: self.depth,
            extra_keyword_earthquake_description['key']: self.description,
            extra_keyword_earthquake_location['key']: self.location,
            extra_keyword_earthquake_event_time['key']: self.time.strftime(
                '%Y-%m-%dT%H:%M:%S'),
            extra_keyword_time_zone['key']: self.time_zone,
            extra_keyword_earthquake_x_minimum['key']: self.x_minimum,
            extra_keyword_earthquake_x_maximum['key']: self.x_maximum,
            extra_keyword_earthquake_y_minimum['key']: self.y_minimum,
            extra_keyword_earthquake_y_maximum['key']: self.y_maximum,
            extra_keyword_earthquake_event_id['key']: self.event_id
        }
        for key, value in list(self.extra_keywords.items()):
            extra_keywords[key] = value

        # Delete empty element.
        empty_keys = []
        for key, value in list(extra_keywords.items()):
            if value is None:
                empty_keys.append(key)
        for empty_key in empty_keys:
            extra_keywords.pop(empty_key)
        keywords = {
            'hazard': hazard_earthquake['key'],
            'hazard_category': hazard_category_single_event['key'],
            'keyword_version': inasafe_keyword_version,
            'layer_geometry': layer_geometry_raster['key'],
            'layer_mode': layer_mode_continuous['key'],
            'layer_purpose': layer_purpose_hazard['key'],
            'continuous_hazard_unit': unit_mmi['key'],
            'classification': earthquake_mmi_scale['key'],
            'thresholds': threshold_keyword,
            'extra_keywords': extra_keywords,
            'active_band': 1
        }

        if self.algorithm_name:
            layer_path = os.path.join(
                self.output_dir, '%s-%s.tif' % (
                    self.output_basename, algorithm))
        else:
            layer_path = os.path.join(
                self.output_dir, '%s.tif' % self.output_basename)

        # append title and source to the keywords file
        if len(self.title.strip()) == 0:
            keyword_title = self.output_basename
        else:
            keyword_title = self.title

        keywords['title'] = keyword_title

        hazard_layer = QgsRasterLayer(layer_path, keyword_title)

        if not hazard_layer.isValid():
            raise InvalidLayerError()

        keyword_io.write_keywords(hazard_layer, keywords)