forked from inasafe/inasafe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
minimum_needs.py
147 lines (126 loc) · 5.1 KB
/
minimum_needs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# coding=utf-8
"""Module used to generate context for minimum needs section."""
from safe.common.parameters.resource_parameter import ResourceParameter
from safe.definitions.fields import displaced_field, additional_minimum_needs
from safe.definitions.minimum_needs import (
minimum_needs_fields,
minimum_needs_namespace)
from safe.report.extractors.util import (
resolve_from_dictionary,
value_from_field_name)
from safe.utilities.i18n import tr
from safe.utilities.rounding import format_number
__copyright__ = "Copyright 2016, The InaSAFE Project"
__license__ = "GPL version 3"
__email__ = "info@inasafe.org"
__revision__ = '$Format:%H$'
def minimum_needs_extractor(impact_report, component_metadata):
"""Extracting minimum needs of the impact layer.
:param impact_report: the impact report that acts as a proxy to fetch
all the data that extractor needed
:type impact_report: safe.report.impact_report.ImpactReport
:param component_metadata: the component metadata. Used to obtain
information about the component we want to render
:type component_metadata: safe.report.report_metadata.
ReportComponentsMetadata
:return: context for rendering phase
:rtype: dict
.. versionadded:: 4.0
"""
context = {}
extra_args = component_metadata.extra_args
analysis_layer = impact_report.analysis
analysis_keywords = analysis_layer.keywords['inasafe_fields']
use_rounding = impact_report.impact_function.use_rounding
header = resolve_from_dictionary(extra_args, 'header')
context['header'] = header
# check if displaced is not zero
try:
displaced_field_name = analysis_keywords[displaced_field['key']]
total_displaced = value_from_field_name(
displaced_field_name, analysis_layer)
if total_displaced == 0:
zero_displaced_message = resolve_from_dictionary(
extra_args, 'zero_displaced_message')
context['zero_displaced'] = {
'status': True,
'message': zero_displaced_message
}
return context
except KeyError:
# in case no displaced field
pass
# minimum needs calculation only affect population type exposure
# check if analysis keyword have minimum_needs keywords
have_minimum_needs_field = False
for field_key in analysis_keywords:
if field_key.startswith(minimum_needs_namespace):
have_minimum_needs_field = True
break
if not have_minimum_needs_field:
return context
frequencies = {}
# map each needs to its frequency groups
for field in (minimum_needs_fields + additional_minimum_needs):
need_parameter = field.get('need_parameter')
if isinstance(need_parameter, ResourceParameter):
frequency = need_parameter.frequency
else:
frequency = field.get('frequency')
if frequency:
if frequency not in frequencies:
frequencies[frequency] = [field]
else:
frequencies[frequency].append(field)
needs = []
analysis_feature = next(analysis_layer.getFeatures())
header_frequency_format = resolve_from_dictionary(
extra_args, 'header_frequency_format')
total_header = resolve_from_dictionary(extra_args, 'total_header')
need_header_format = resolve_from_dictionary(
extra_args, 'need_header_format')
# group the needs by frequency
for key, frequency in list(frequencies.items()):
group = {
'header': header_frequency_format.format(frequency=tr(key)),
'total_header': total_header,
'needs': []
}
for field in frequency:
# check value exists in the field
field_idx = analysis_layer.fields().lookupField(field['field_name'])
if field_idx == -1:
# skip if field doesn't exists
continue
value = format_number(
analysis_feature[field_idx],
use_rounding=use_rounding,
is_population=True)
unit_abbreviation = ''
if field.get('need_parameter'):
need_parameter = field['need_parameter']
""":type: ResourceParameter"""
name = tr(need_parameter.name)
unit_abbreviation = need_parameter.unit.abbreviation
else:
if field.get('header_name'):
name = field.get('header_name')
else:
name = field.get('name')
need_unit = field.get('unit')
if need_unit:
unit_abbreviation = need_unit.get('abbreviation')
if unit_abbreviation:
header = need_header_format.format(
name=name,
unit_abbreviation=unit_abbreviation)
else:
header = name
item = {
'header': header,
'value': value
}
group['needs'].append(item)
needs.append(group)
context['needs'] = needs
return context