Add Disaster Management section to Resilience Category

This commit is contained in:
Mike Simpson 2023-04-17 21:48:21 +01:00
parent bed7b43fd9
commit 906ebd7431
10 changed files with 318 additions and 120 deletions

View File

@ -913,6 +913,32 @@
<LineSymbolizer stroke="#888" stroke-width="3.0"/> <LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule> </Rule>
</Style> </Style>
<Style name="disaster_severity">
<Rule>
<Filter>[disaster_severity] = "Building destroyed"</Filter>
<PolygonSymbolizer fill="#bd0026" />
</Rule>
<Rule>
<Filter>[disaster_severity] = "Very severe"</Filter>
<PolygonSymbolizer fill="#e31a1c" />
</Rule>
<Rule>
<Filter>[disaster_severity] = "Severe"</Filter>
<PolygonSymbolizer fill="#fc4e2a" />
</Rule>
<Rule>
<Filter>[disaster_severity] = "Moderate"</Filter>
<PolygonSymbolizer fill="#fd8d3c" />
</Rule>
<Rule>
<Filter>[disaster_severity] = "Minimal"</Filter>
<PolygonSymbolizer fill="#feb24c" />
</Rule>
<Rule>
<Filter>[disaster_severity] = "No damage visible"</Filter>
<PolygonSymbolizer fill="#fed976" />
</Rule>
</Style>
<Style name="dynamics_demolished_count"> <Style name="dynamics_demolished_count">
<Rule> <Rule>
<Filter>[dynamics_has_demolished_buildings] = false</Filter> <Filter>[dynamics_has_demolished_buildings] = false</Filter>

View File

@ -407,8 +407,23 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
other_team_source_link: { other_team_source_link: {
edit: true, edit: true,
verify: true verify: true
} },
disaster_type: {
edit: true,
verify: true
},
disaster_severity: {
edit: true,
verify: true
},
disaster_assessment_method: {
edit: true,
verify: true
},
disaster_source_link: {
edit: true,
verify: true
},
}); });

View File

@ -1,27 +1,112 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom';
import InfoBox from '../../components/info-box'; import InfoBox from '../../components/info-box';
import { Category } from '../../config/categories-config';
import { dataFields } from '../../config/data-fields-config'; import { dataFields } from '../../config/data-fields-config';
import DataEntry from '../data-components/data-entry'; import DataEntry from '../data-components/data-entry';
import { DataEntryGroup } from '../data-components/data-entry-group'; import { DataEntryGroup } from '../data-components/data-entry-group';
import { DynamicsBuildingPane, DynamicsDataEntry } from './dynamics/dynamics-data-entry'; import SelectDataEntry from '../data-components/select-data-entry';
import { FieldRow } from '../data-components/field-row';
import NumericDataEntry from '../data-components/numeric-data-entry';
import withCopyEdit from '../data-container'; import withCopyEdit from '../data-container';
import Verification from '../data-components/verification';
import { CategoryViewProps } from './category-view-props'; import { CategoryViewProps } from './category-view-props';
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry'; import { useDisplayPreferences } from '../../displayPreferences-context';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
/** /**
* Dynamics view/edit section * Dynamics view/edit section
*/ */
const ResilienceView: React.FunctionComponent<CategoryViewProps> = (props) => { const ResilienceView: React.FunctionComponent<CategoryViewProps> = (props) => {
const { historicData, historicDataSwitchOnClick, darkLightTheme } = useDisplayPreferences();
return (<> return (<>
<DataEntryGroup name="Disaster Management" collapsed={true} >
<InfoBox>
This feature is designed to help communities capture data on the state of buildings
during major disasters, to support emergency services and to record damage to aid reconstruction programmes.
</InfoBox>
<button className={`map-switcher-inline ${historicData}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={historicDataSwitchOnClick}>
{(historicData === 'enabled')?'Click here to hide disaster maps':'Click here to show disaster maps'}
</button>
<SelectDataEntry
slug='disaster_type'
title={dataFields.disaster_type.title}
value={props.building.disaster_type}
options={[
'Flood',
'Earthquake',
'Hurricane',
'Fire',
'Extreme heat',
'Political/war damage',
'Other human (blast damage/spills etc.)',
'Other'
]}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<SelectDataEntry
slug='disaster_severity'
title={dataFields.disaster_severity.title}
value={props.building.disaster_severity}
options={[
'Building destroyed',
'Very severe',
'Severe',
'Moderate',
'Minimal',
'No damage visible',
]}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="disaster_severity"
allow_verify={props.user !== undefined && props.building.disaster_severity !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("disaster_severity")}
user_verified_as={props.user_verified.disaster_severity}
verified_count={props.building.verified.disaster_severity}
/>
<SelectDataEntry
slug='disaster_assessment_method'
title={dataFields.disaster_assessment_method.title}
value={props.building.disaster_assessment_method}
options={[
'Citizen/Passerby by eye',
'Government assessor',
'Specialist emergency group/charity',
'Other',
]}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="disaster_assessment_method"
allow_verify={props.user !== undefined && props.building.disaster_assessment_method !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("disaster_assessment_method")}
user_verified_as={props.user_verified.disaster_assessment_method}
verified_count={props.building.verified.disaster_assessment_method}
/>
<MultiDataEntry
title={dataFields.disaster_source_link.title}
slug="disaster_source_link"
value={props.building.disaster_source_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.disaster_source_link.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</DataEntryGroup>
<DataEntryGroup name="Resilience indicators" collapsed={true} >
<InfoBox> <InfoBox>
This section is under development. This section is under development.
</InfoBox> </InfoBox>
@ -97,6 +182,7 @@ const ResilienceView: React.FunctionComponent<CategoryViewProps> = (props) => {
value="" value=""
mode='view' mode='view'
/> />
</DataEntryGroup>
</>) </>)
}; };

View File

@ -354,7 +354,36 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
elements: [] elements: []
}, },
}], }],
[Category.Resilience]: [{ [Category.Resilience]: [
{
mapStyle: 'disaster_severity',
legend: {
title: 'Severity of damage',
description: 'Severity of damage to building',
elements: [
{
text: 'Building destroyed',
color: '#bd0026',
}, {
text: 'Very severe',
color: '#e31a1c',
}, {
text: 'Severe',
color: '#fc4e2a',
}, {
text: 'Moderate',
color: '#fd8d3c',
}, {
text: 'Minimal ',
color: '#feb24c',
}, {
text: 'No damage visible',
color: '#fed976',
},
],
},
},
{
mapStyle: 'dynamics_demolished_count', mapStyle: 'dynamics_demolished_count',
legend: { legend: {
title: 'Resilience', title: 'Resilience',
@ -387,6 +416,7 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
} }
], ],
}, },
}] }
]
}; };

View File

@ -811,6 +811,27 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
title: "Source other significant team members", title: "Source other significant team members",
example: ["", "", ""], example: ["", "", ""],
}, },
disaster_type: {
category: Category.Resilience,
title: "What type of disaster management do you wish to collect data for?",
example: "Flood"
},
disaster_severity: {
category: Category.Resilience,
title: "How severe do you assess the damage to be?",
example: "Building destroyed"
},
disaster_assessment_method: {
category: Category.Resilience,
title: "Please add a method of assessment",
example: "Citizen/Passerby by eye"
},
disaster_source_link: {
category: Category.Resilience,
title: "Please add a source link to official documentation where applicable",
tooltip: "URL for data sources(s)",
example: ["", "", ""],
},
}; };
export const allFieldsConfig = {...dataFields, ...buildingUserFields}; export const allFieldsConfig = {...dataFields, ...buildingUserFields};

View File

@ -21,6 +21,7 @@ export type BuildingMapTileset = 'date_year' |
'building_attachment_form' | 'building_attachment_form' |
'landuse' | 'landuse' |
'dynamics_demolished_count' | 'dynamics_demolished_count' |
'disaster_severity' |
'team' | 'team' |
'survival_status'; 'survival_status';

View File

@ -266,6 +266,13 @@ const LAYER_QUERIES = {
buildings buildings
WHERE WHERE
current_landuse_order IS NOT NULL`, current_landuse_order IS NOT NULL`,
disaster_severity: `
SELECT
geometry_id,
disaster_severity
FROM
buildings
WHERE disaster_severity IS NOT NULL`,
dynamics_demolished_count: ` dynamics_demolished_count: `
SELECT SELECT
geometry_id, geometry_id,

View File

@ -58,7 +58,11 @@ COPY (SELECT
community_type_worth_keeping_total, community_type_worth_keeping_total,
likes_total, likes_total,
survival_status, survival_status,
survival_source survival_source,
disaster_type,
disaster_severity,
disaster_assessment_method,
disaster_source_link
FROM buildings) FROM buildings)
TO '/tmp/building_attributes.csv' TO '/tmp/building_attributes.csv'
WITH CSV HEADER WITH CSV HEADER

View File

@ -0,0 +1,4 @@
ALTER TABLE buildings DROP COLUMN IF EXISTS disaster_type;
ALTER TABLE buildings DROP COLUMN IF EXISTS disaster_severity;
ALTER TABLE buildings DROP COLUMN IF EXISTS disaster_assessment_method;
ALTER TABLE buildings DROP COLUMN IF EXISTS disaster_source_link;

View File

@ -0,0 +1,4 @@
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS disaster_type text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS disaster_severity text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS disaster_assessment_method text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS disaster_source_link text[];