Beispiel #1
0
    def inasafe_fields_for_the_layer(self):
        """Return a list of inasafe fields the current layer.

        :returns: A list where each value represents inasafe field.
        :rtype: list
        """
        if (self.parent.get_layer_geometry_key() ==
                layer_geometry_raster['key']):
            return []
        # Get hazard or exposure value
        layer_purpose_key = self.parent.step_kw_purpose.selected_purpose(
        )['key']
        if layer_purpose_key != layer_purpose_aggregation['key']:
            subcategory_key = self.parent.step_kw_subcategory.\
                selected_subcategory()['key']
        else:
            subcategory_key = None
        # Get all fields with replace_null = True
        inasafe_fields = get_fields(layer_purpose_key,
                                    subcategory_key,
                                    replace_null=True,
                                    in_group=False)
        # remove compulsory field since it has been set in previous step
        try:
            inasafe_fields.remove(
                get_compulsory_fields(layer_purpose_key, subcategory_key))
        except ValueError:
            pass
        return inasafe_fields
    def inasafe_fields_for_the_layer(self):
        """Return a list of inasafe fields the current layer.

        :returns: A list where each value represents inasafe field.
        :rtype: list
        """
        if (self.parent.get_layer_geometry_key() ==
                layer_geometry_raster['key']):
            return []
        # Get hazard or exposure value
        layer_purpose_key = self.parent.step_kw_purpose.selected_purpose()[
            'key']
        if layer_purpose_key != layer_purpose_aggregation['key']:
            subcategory_key = self.parent.step_kw_subcategory.\
                selected_subcategory()['key']
        else:
            subcategory_key = None
        # Get all fields with replace_null = False
        inasafe_fields = get_fields(
            layer_purpose_key,
            subcategory_key,
            replace_null=False,
            in_group=False)
        # remove compulsory field since it has been set in previous step
        try:
            inasafe_fields.remove(get_compulsory_fields(
                layer_purpose_key, subcategory_key))
        except ValueError:
            pass
        return inasafe_fields
Beispiel #3
0
    def field_keyword_for_the_layer(self):
        """Return the proper keyword for field for the current layer.

        :returns: the field keyword
        :rtype: str
        """
        layer_purpose_key = self.step_kw_purpose.selected_purpose()['key']
        if layer_purpose_key == layer_purpose_aggregation['key']:
            return get_compulsory_fields(layer_purpose_key)['key']
        elif layer_purpose_key in [
                layer_purpose_exposure['key'], layer_purpose_hazard['key']]:
            layer_subcategory_key = \
                self.step_kw_subcategory.selected_subcategory()['key']
            return get_compulsory_fields(
                layer_purpose_key, layer_subcategory_key)['key']
        else:
            raise InvalidParameterError
Beispiel #4
0
    def field_keyword_for_the_layer(self):
        """Return the proper keyword for field for the current layer.

        :returns: the field keyword
        :rtype: str
        """
        layer_purpose_key = self.step_kw_purpose.selected_purpose()['key']
        if layer_purpose_key == layer_purpose_aggregation['key']:
            return get_compulsory_fields(layer_purpose_key)['key']
        elif layer_purpose_key in [
                layer_purpose_exposure['key'], layer_purpose_hazard['key']]:
            layer_subcategory_key = \
                self.step_kw_subcategory.selected_subcategory()['key']
            return get_compulsory_fields(
                layer_purpose_key, layer_subcategory_key)['key']
        else:
            raise InvalidParameterError
Beispiel #5
0
    def get_next_step(self):
        """Find the proper step when user clicks the Next button.

        :returns: The step to be switched to
        :rtype: WizardStep
        """
        layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        if layer_purpose != layer_purpose_aggregation:
            subcategory = self.parent.step_kw_subcategory.\
                selected_subcategory()
        else:
            subcategory = {'key': None}

        # Has layer groups, go to field mapping
        field_groups = get_field_groups(
            layer_purpose['key'], subcategory['key'])
        compulsory_field = get_compulsory_fields(
            layer_purpose['key'], subcategory['key'])

        # It's aggregation and has field_groups.
        if field_groups and layer_purpose == layer_purpose_aggregation:
            return self.parent.step_kw_fields_mapping

        # It has field_groups and the compulsory field is population count.
        if field_groups and compulsory_field == population_count_field:
            return self.parent.step_kw_fields_mapping

        # Has classifications, go to multi classifications
        if subcategory.get('classifications'):
            if layer_purpose == layer_purpose_hazard:
                return self.parent.step_kw_multi_classifications
            elif layer_purpose == layer_purpose_exposure:
                return self.parent.step_kw_classification

        # Check if it can go to inasafe field step
        non_compulsory_fields = get_non_compulsory_fields(
            layer_purpose['key'], subcategory['key'])
        if not skip_inasafe_field(self.parent.layer, non_compulsory_fields):
            return self.parent.step_kw_inasafe_fields

        # Check if it can go to inasafe default field step
        default_inasafe_fields = get_fields(
            layer_purpose['key'],
            subcategory['key'],
            replace_null=True,
            in_group=False)
        if default_inasafe_fields:
            return self.parent.step_kw_default_inasafe_fields

        # Any other case
        return self.parent.step_kw_source
Beispiel #6
0
    def get_next_step(self):
        """Find the proper step when user clicks the Next button.

        :returns: The step to be switched to
        :rtype: WizardStep
        """
        if self.parent.get_layer_geometry_key() == \
                layer_geometry_raster['key']:
            return self.parent.step_kw_source

        layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        if layer_purpose['key'] != layer_purpose_aggregation['key']:
            subcategory = self.parent.step_kw_subcategory. \
                selected_subcategory()
        else:
            subcategory = {'key': None}

        # Get all fields with replace_null = False
        inasafe_fields = get_fields(
            layer_purpose['key'],
            subcategory['key'],
            replace_null=False,
            in_group=False
        )
        # remove compulsory field since it has been set in previous step
        try:
            inasafe_fields.remove(get_compulsory_fields(
                layer_purpose['key'], subcategory['key']))
        except ValueError:
            pass

        # Check if possible to skip inasafe field step
        if skip_inasafe_field(self.parent.layer, inasafe_fields):
            default_inasafe_fields = get_fields(
                layer_purpose['key'],
                subcategory['key'],
                replace_null=True,
                in_group=False
            )
            # Check if it can go to inasafe default step
            if default_inasafe_fields:
                return self.parent.step_kw_default_inasafe_fields
            # Else, go to source step
            else:
                return self.parent.step_kw_source

        # If not possible to skip inasafe field step, then go there
        else:
            return self.parent.step_kw_inasafe_fields
Beispiel #7
0
 def test_get_compulsory_field(self):
     """Test get_compulsory_field method."""
     compulsory_field = get_compulsory_fields('exposure', 'structure')
     expected_fields = exposure_structure['compulsory_fields']
     self.assertListEqual([compulsory_field], expected_fields)
def _remove_features(layer):
    """Remove features which do not have information for InaSAFE or an invalid
    geometry.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer
    """
    # Get the layer purpose of the layer.
    layer_purpose = layer.keywords['layer_purpose']
    layer_subcategory = layer.keywords.get(layer_purpose)

    compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory)

    inasafe_fields = layer.keywords['inasafe_fields']
    field_name = inasafe_fields.get(compulsory_field['key'])
    if not field_name:
        msg = 'Keyword %s is missing from %s' % (
            compulsory_field['key'], layer_purpose)
        raise InvalidKeywordsForProcessingAlgorithm(msg)
    index = layer.fieldNameIndex(field_name)

    request = QgsFeatureRequest()
    request.setSubsetOfAttributes([field_name], layer.pendingFields())
    layer.startEditing()
    i = 0
    for feature in layer.getFeatures(request):
        if isinstance(feature.attributes()[index], QPyNullVariant):
            if layer_purpose == 'hazard':
                # Remove the feature if the hazard is null.
                layer.deleteFeature(feature.id())
                i += 1
            elif layer_purpose == 'aggregation':
                # Put the ID if the value is null.
                layer.changeAttributeValue(
                    feature.id(), index, str(feature.id()))
            elif layer_purpose == 'exposure':
                # Put an empty value, the value mapping will take care of it
                # in the 'other' group.
                layer.changeAttributeValue(
                    feature.id(), index, '')

        # Check if there is en empty geometry.
        geometry = feature.geometry()
        if not geometry:
            layer.deleteFeature(feature.id())
            i += 1
            continue

        # Check if the geometry is empty.
        if geometry.isGeosEmpty():
            layer.deleteFeature(feature.id())
            i += 1
            continue

        # Check if the geometry is valid.
        if not geometry.isGeosValid():
            # polygonize can produce some invalid geometries
            # For instance a polygon like this, sharing a same point :
            #      _______
            #      |  ___|__
            #      |  |__|  |
            #      |________|
            # layer.deleteFeature(feature.id())
            # i += 1
            pass

        # TODO We need to add more tests
        # like checking if the value is in the value_mapping.
    layer.commitChanges()
    LOGGER.debug(tr(
        'Features which have been removed from %s : %s'
        % (layer.keywords['layer_purpose'], i)))
def _remove_features(layer):
    """Remove features which do not have information for InaSAFE or an invalid
    geometry.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer
    """
    # Get the layer purpose of the layer.
    layer_purpose = layer.keywords['layer_purpose']
    layer_subcategory = layer.keywords.get(layer_purpose)

    compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory)

    inasafe_fields = layer.keywords['inasafe_fields']
    # Compulsory fields can be list of field name or single field name.
    # We need to iterate through all of them
    field_names = inasafe_fields.get(compulsory_field['key'])
    if not isinstance(field_names, list):
        field_names = [field_names]
    for field_name in field_names:
        if not field_name:
            message = 'Keyword %s is missing from %s' % (
                compulsory_field['key'], layer_purpose)
            raise InvalidKeywordsForProcessingAlgorithm(message)
        index = layer.fields().lookupField(field_name)

        request = QgsFeatureRequest()
        request.setSubsetOfAttributes([field_name], layer.fields())
        layer.startEditing()
        i = 0
        for feature in layer.getFeatures(request):
            feat_attr = feature.attributes()[index]
            if (feat_attr is None
                    or (hasattr(feat_attr, 'isNull') and feat_attr.isNull())):
                if layer_purpose == 'hazard':
                    # Remove the feature if the hazard is null.
                    layer.deleteFeature(feature.id())
                    i += 1
                elif layer_purpose == 'aggregation':
                    # Put the ID if the value is null.
                    layer.changeAttributeValue(feature.id(), index,
                                               str(feature.id()))
                elif layer_purpose == 'exposure':
                    # Put an empty value, the value mapping will take care of
                    # it in the 'other' group.
                    layer.changeAttributeValue(feature.id(), index, '')

            # Check if there is en empty geometry.
            geometry = feature.geometry()
            if not geometry:
                layer.deleteFeature(feature.id())
                i += 1
                continue

            # Check if the geometry is empty.
            if geometry.isEmpty():
                layer.deleteFeature(feature.id())
                i += 1
                continue

            # Check if the geometry is valid.
            if not geometry.isGeosValid():
                # polygonize can produce some invalid geometries
                # For instance a polygon like this, sharing a same point :
                #      _______
                #      |  ___|__
                #      |  |__|  |
                #      |________|
                # layer.deleteFeature(feature.id())
                # i += 1
                pass

            # TODO We need to add more tests
            # like checking if the value is in the value_mapping.
        layer.commitChanges()
        if i:
            LOGGER.critical('Features which have been removed from %s : %s' %
                            (layer.keywords['layer_purpose'], i))
        else:
            LOGGER.info(
                'No feature has been removed from %s during the vector layer '
                'preparation' % layer.keywords['layer_purpose'])
def _remove_features(layer):
    """Remove features which do not have information for InaSAFE or an invalid
    geometry.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer
    """
    # Get the layer purpose of the layer.
    layer_purpose = layer.keywords['layer_purpose']
    layer_subcategory = layer.keywords.get(layer_purpose)

    compulsory_field = get_compulsory_fields(layer_purpose, layer_subcategory)

    inasafe_fields = layer.keywords['inasafe_fields']
    # Compulsory fields can be list of field name or single field name.
    # We need to iterate through all of them
    field_names = inasafe_fields.get(compulsory_field['key'])
    if not isinstance(field_names, list):
        field_names = [field_names]
    for field_name in field_names:
        if not field_name:
            message = 'Keyword %s is missing from %s' % (
                compulsory_field['key'], layer_purpose)
            raise InvalidKeywordsForProcessingAlgorithm(message)
        index = layer.fieldNameIndex(field_name)

        request = QgsFeatureRequest()
        request.setSubsetOfAttributes([field_name], layer.pendingFields())
        layer.startEditing()
        i = 0
        for feature in layer.getFeatures(request):
            if isinstance(feature.attributes()[index], QPyNullVariant):
                if layer_purpose == 'hazard':
                    # Remove the feature if the hazard is null.
                    layer.deleteFeature(feature.id())
                    i += 1
                elif layer_purpose == 'aggregation':
                    # Put the ID if the value is null.
                    layer.changeAttributeValue(
                        feature.id(), index, str(feature.id()))
                elif layer_purpose == 'exposure':
                    # Put an empty value, the value mapping will take care of
                    # it in the 'other' group.
                    layer.changeAttributeValue(
                        feature.id(), index, '')

            # Check if there is en empty geometry.
            geometry = feature.geometry()
            if not geometry:
                layer.deleteFeature(feature.id())
                i += 1
                continue

            # Check if the geometry is empty.
            if geometry.isGeosEmpty():
                layer.deleteFeature(feature.id())
                i += 1
                continue

            # Check if the geometry is valid.
            if not geometry.isGeosValid():
                # polygonize can produce some invalid geometries
                # For instance a polygon like this, sharing a same point :
                #      _______
                #      |  ___|__
                #      |  |__|  |
                #      |________|
                # layer.deleteFeature(feature.id())
                # i += 1
                pass

            # TODO We need to add more tests
            # like checking if the value is in the value_mapping.
        layer.commitChanges()
        LOGGER.debug(tr(
            'Features which have been removed from %s : %s'
            % (layer.keywords['layer_purpose'], i)))
Beispiel #11
0
 def test_get_compulsory_field(self):
     """Test get_compulsory_field method."""
     compulsory_field = get_compulsory_fields('exposure', 'structure')
     expected_fields = exposure_structure['compulsory_fields']
     self.assertListEqual([compulsory_field], expected_fields)