# Path: safe/definitions/hazard_classifications.py

# 
# Path: safe/definitions/layer_purposes.py

# 
# Path: safe/utilities/pivot_table.py
# class FlatTable():
#     """ Flat table object - used as a source of data for pivot tables.
#     After constructing the object, repeatedly call "add_value" method
#     for each row of the input table. FlatTable stores only fields
#     that are important for the creation of pivot tables later. It also
#     aggregates values of rows where specified fields have the same value,
#     saving memory by not storing all source data.
# 
#     An example of use for the flat table - afterwards it can be converted
#     into a pivot table:
# 
#     flat_table = FlatTable('hazard_type', 'road_type', 'district')
# 
#     for f in layer.getFeatures():
#         flat_table.add_value(
#             f.geometry().length(),
#             hazard_type=f['hazard'],
#             road_type=f['road'],
#             zone=f['zone'])
#     """
# 
#     def __init__(self, *args):
#         """ Construct flat table, fields are passed"""
#         self.groups = args
#         self.data = {}
#         # Store keys, allowing for consistent ordered
#         self.data_keys = []
# 
#     def add_value(self, value, **kwargs):
#         key = tuple(kwargs[group] for group in self.groups)
#         if key not in self.data:
#             self.data[key] = 0
#         self.data_keys.append(key)
#         self.data[key] += value
# 
#     def get_value(self, **kwargs):
#         """Return the value for a specific key."""
#         key = tuple(kwargs[group] for group in self.groups)
#         if key not in self.data:
#             self.data[key] = 0
#         return self.data[key]
# 
#     def group_values(self, group_name):
#         """Return all distinct group values for given group."""
#         group_index = self.groups.index(group_name)
#         values = []
#         for key in self.data_keys:
#             if key[group_index] not in values:
#                 values.append(key[group_index])
#         return values
# 
#     def to_json(self):
#         """Return json representation of FlatTable
# 
#         :returns: JSON string.
#         :rtype: str
#         """
#         return json.dumps(self.to_dict())
# 
#     def from_json(self, json_string):
#         """Override current FlatTable using data from json.
# 
#         :param json_string: JSON String
#         :type json_string: str
#         """
# 
#         obj = json.loads(json_string)
#         self.from_dict(obj['groups'], obj['data'])
# 
#         return self
# 
#     def to_dict(self):
#         """Return common list python object.
#         :returns: Dictionary of groups and data
#         :rtype: dict
#         """
#         list_data = []
#         for key, value in list(self.data.items()):
#             row = list(key)
#             row.append(value)
#             list_data.append(row)
#         return {
#             'groups': self.groups,
#             'data': list_data
#         }
# 
#     def from_dict(self, groups, data):
#         """Populate FlatTable based on groups and data.
# 
#         :param groups: List of group name.
#         :type groups: list
# 
#         :param data: Dictionary of raw table.
#         :type data: list
# 
#         example of groups: ["road_type", "hazard"]
#         example of data: [
#             ["residential", "low", 50],
#             ["residential", "medium", 30],
#             ["secondary", "low", 40],
#             ["primary", "high", 10],
#             ["primary", "medium", 20]
#             ]
#         """
#         self.groups = tuple(groups)
#         for item in data:
#             kwargs = {}
#             for i in range(len(self.groups)):
#                 kwargs[self.groups[i]] = item[i]
#             self.add_value(item[-1], **kwargs)
# 
#         return self


from numbers import Number
from qgis.core import QgsWkbTypes, QgsFeatureRequest, QgsFeature
from safe.definitions.fields import (
    aggregation_id_field,
    aggregation_name_field,
    hazard_id_field,
    hazard_class_field,
    exposure_type_field,
    total_affected_field,
    total_not_affected_field,
    total_not_exposed_field,
    total_field,
    affected_field,
    hazard_count_field,
    exposure_count_field,
    exposure_class_field,
    summary_rules,
)
from safe.definitions.hazard_classifications import not_exposed_class
from safe.definitions.layer_purposes import \
    layer_purpose_exposure_summary_table
from safe.definitions.processing_steps import (
    summary_4_exposure_summary_table_steps)
from safe.definitions.utilities import definition
from safe.gis.sanity_check import check_layer
from safe.gis.vector.summary_tools import (
    check_inputs, create_absolute_values_structure)
from safe.gis.vector.tools import (
    create_field_from_definition,
    read_dynamic_inasafe_field,
    create_memory_layer)
from safe.processors import post_processor_affected_function
from safe.utilities.gis import qgis_version
from safe.utilities.pivot_table import FlatTable
from safe.utilities.profiling import profile
        attributes.append(total)

        if summarization_dicts:
            for key in sorted_keys:
                attributes.append(summarization_dicts[key].get(
                    exposure_type, 0))
        else:
            for i, field in enumerate(absolute_values.values()):
                value = field[0].get_value(
                    all='all'
                )
                attributes.append(value)

        feature.setAttributes(attributes)
        tabular.addFeature(feature)

        # Sanity check ± 1 to the result. Disabled for now as it seems ± 1 is
        # not enough. ET 13/02/17
        # total_computed = (
        #     total_affected + total_not_affected + total_not_exposed)
        # if not -1 < (total_computed - total) < 1:
        #     raise ComputationError

    tabular.commitChanges()

    tabular.keywords['title'] = layer_purpose_exposure_summary_table['name']
    if qgis_version() >= 21800:
        tabular.setName(tabular.keywords['title'])
    else:
        tabular.setLayerName(tabular.keywords['title'])

# Path: safe/definitions/hazard_classifications.py

# 
# Path: safe/definitions/layer_purposes.py

# 
# Path: safe/utilities/pivot_table.py
# class FlatTable():
#     """ Flat table object - used as a source of data for pivot tables.
#     After constructing the object, repeatedly call "add_value" method
#     for each row of the input table. FlatTable stores only fields
#     that are important for the creation of pivot tables later. It also
#     aggregates values of rows where specified fields have the same value,
#     saving memory by not storing all source data.
# 
#     An example of use for the flat table - afterwards it can be converted
#     into a pivot table:
# 
#     flat_table = FlatTable('hazard_type', 'road_type', 'district')
# 
#     for f in layer.getFeatures():
#         flat_table.add_value(
#             f.geometry().length(),
#             hazard_type=f['hazard'],
#             road_type=f['road'],
#             zone=f['zone'])
#     """
# 
#     def __init__(self, *args):
#         """ Construct flat table, fields are passed"""
#         self.groups = args
#         self.data = {}
#         # Store keys, allowing for consistent ordered
#         self.data_keys = []
# 
#     def add_value(self, value, **kwargs):
#         key = tuple(kwargs[group] for group in self.groups)
#         if key not in self.data:
#             self.data[key] = 0
#         self.data_keys.append(key)
#         self.data[key] += value
# 
#     def get_value(self, **kwargs):
#         """Return the value for a specific key."""
#         key = tuple(kwargs[group] for group in self.groups)
#         if key not in self.data:
#             self.data[key] = 0
#         return self.data[key]
# 
#     def group_values(self, group_name):
#         """Return all distinct group values for given group."""
#         group_index = self.groups.index(group_name)
#         values = []
#         for key in self.data_keys:
#             if key[group_index] not in values:
#                 values.append(key[group_index])
#         return values
# 
#     def to_json(self):
#         """Return json representation of FlatTable
# 
#         :returns: JSON string.
#         :rtype: str
#         """
#         return json.dumps(self.to_dict())
# 
#     def from_json(self, json_string):
#         """Override current FlatTable using data from json.
# 
#         :param json_string: JSON String
#         :type json_string: str
#         """
# 
#         obj = json.loads(json_string)
#         self.from_dict(obj['groups'], obj['data'])
# 
#         return self
# 
#     def to_dict(self):
#         """Return common list python object.
#         :returns: Dictionary of groups and data
#         :rtype: dict
#         """
#         list_data = []
#         for key, value in list(self.data.items()):
#             row = list(key)
#             row.append(value)
#             list_data.append(row)
#         return {
#             'groups': self.groups,
#             'data': list_data
#         }
# 
#     def from_dict(self, groups, data):
#         """Populate FlatTable based on groups and data.
# 
#         :param groups: List of group name.
#         :type groups: list
# 
#         :param data: Dictionary of raw table.
#         :type data: list
# 
#         example of groups: ["road_type", "hazard"]
#         example of data: [
#             ["residential", "low", 50],
#             ["residential", "medium", 30],
#             ["secondary", "low", 40],
#             ["primary", "high", 10],
#             ["primary", "medium", 20]
#             ]
#         """
#         self.groups = tuple(groups)
#         for item in data:
#             kwargs = {}
#             for i in range(len(self.groups)):
#                 kwargs[self.groups[i]] = item[i]
#             self.add_value(item[-1], **kwargs)
# 
#         return self


# Path: safe/gis/vector/summary_4_exposure_summary_table.py
from numbers import Number
from qgis.core import QgsWkbTypes, QgsFeatureRequest, QgsFeature
from safe.definitions.fields import (
    aggregation_id_field,
    aggregation_name_field,
    hazard_id_field,
    hazard_class_field,
    exposure_type_field,
    total_affected_field,
    total_not_affected_field,
    total_not_exposed_field,
    total_field,
    affected_field,
    hazard_count_field,
    exposure_count_field,
    exposure_class_field,
    summary_rules,
)
from safe.definitions.hazard_classifications import not_exposed_class
from safe.definitions.layer_purposes import \
    layer_purpose_exposure_summary_table
from safe.definitions.processing_steps import (
    summary_4_exposure_summary_table_steps)
from safe.definitions.utilities import definition
from safe.gis.sanity_check import check_layer
from safe.gis.vector.summary_tools import (
    check_inputs, create_absolute_values_structure)
from safe.gis.vector.tools import (
    create_field_from_definition,
    read_dynamic_inasafe_field,
    create_memory_layer)
from safe.processors import post_processor_affected_function
from safe.utilities.gis import qgis_version
from safe.utilities.pivot_table import FlatTable
from safe.utilities.profiling import profile

        attributes.append(total)

        if summarization_dicts:
            for key in sorted_keys:
                attributes.append(summarization_dicts[key].get(
                    exposure_type, 0))
        else:
            for i, field in enumerate(absolute_values.values()):
                value = field[0].get_value(
                    all='all'
                )
                attributes.append(value)

        feature.setAttributes(attributes)
        tabular.addFeature(feature)

        # Sanity check ± 1 to the result. Disabled for now as it seems ± 1 is
        # not enough. ET 13/02/17
        # total_computed = (
        #     total_affected + total_not_affected + total_not_exposed)
        # if not -1 < (total_computed - total) < 1:
        #     raise ComputationError

    tabular.commitChanges()

    tabular.keywords['title'] = layer_purpose_exposure_summary_table['name']
    if qgis_version() >= 21800:
        tabular.setName(tabular.keywords['title'])
    else:
        tabular.setLayerName(tabular.keywords['title'])

    tabular.keywords['layer_purpose'] = layer_purpose_exposure_summary_table[