Merge branch 'colouring-cities:master' into ali
This commit is contained in:
commit
a33e98c27b
7
.github/workflows/etl.yml
vendored
7
.github/workflows/etl.yml
vendored
@ -8,9 +8,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.7'
|
python-version: "3.11"
|
||||||
- name:
|
- name: Install dependencies
|
||||||
Install dependencies
|
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libgeos-dev
|
sudo apt-get install libgeos-dev
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
@ -19,7 +18,7 @@ jobs:
|
|||||||
python -m pip install -r etl/requirements.txt
|
python -m pip install -r etl/requirements.txt
|
||||||
- name: Run Flake8
|
- name: Run Flake8
|
||||||
run: |
|
run: |
|
||||||
ls etl/*py | grep -v 'join_building_data' | xargs flake8 --exclude etl/__init__.py
|
flake8 etl --ignore=E501
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
python -m pytest
|
python -m pytest
|
@ -1,4 +1,4 @@
|
|||||||
# Colouring London
|
# Colouring Cities Core Platform
|
||||||
[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors)
|
[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors)
|
||||||
![Build status](https://github.com/colouring-cities/colouring-core/workflows/Node.js%20CI/badge.svg)
|
![Build status](https://github.com/colouring-cities/colouring-core/workflows/Node.js%20CI/badge.svg)
|
||||||
|
|
||||||
|
@ -19,7 +19,19 @@
|
|||||||
</Style>
|
</Style>
|
||||||
<Style name="base_night_outlines">
|
<Style name="base_night_outlines">
|
||||||
<Rule>
|
<Rule>
|
||||||
<LineSymbolizer stroke="#ff0000ff" stroke-width="1" />
|
<MaxScaleDenominator>20000</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>1200</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#0081AF" stroke-width="0.5"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>12000</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>8000</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#0081AF" stroke-width="1.8"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>8000</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>0</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#0081AF" stroke-width="4.0"/>
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Style name="base_boroughs">
|
<Style name="base_boroughs">
|
||||||
@ -913,6 +925,83 @@
|
|||||||
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
|
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style name="original_landuse">
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Agriculture And Fisheries"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#73ccd1" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Minerals"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#45cce3" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Unclassified, presumed non-residential"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#6c6f8e" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Recreation And Leisure"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#ffbfbf" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Transport"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#b3de69" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Utilities And Infrastructure"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#cccccc" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Residential" and not ([typology_original_use_order] = "Garden buildings") and not ([typology_original_use_order] = "Hotels, boarding and guest houses") and not ([typology_original_use_verified])</Filter>
|
||||||
|
<PolygonSymbolizer fill="#252aa6" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Residential" and not ([typology_original_use_order] = "Garden buildings") and not ([typology_original_use_order] = "Hotels, boarding and guest houses") and ([typology_original_use_verified])</Filter>
|
||||||
|
<PolygonSymbolizer fill="#7025a6" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Residential" and [typology_original_use_order] = "Hotels, boarding and guest houses"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#3c4194" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Residential" and [typology_original_use_order] = "Garden buildings" </Filter>
|
||||||
|
<PolygonSymbolizer fill="#1157fa" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Community Services"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#fa667d" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Retail"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#ff8c00" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Industry And Business"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#f5f58f" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Vacant And Derelict"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#ffffff" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Defence"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#898944" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_original_use_order] = "Mixed Use"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#e5050d" />
|
||||||
|
</Rule>
|
||||||
|
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>8530</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>4264</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>4264</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>0</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
<Style name="disaster_severity">
|
<Style name="disaster_severity">
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>[disaster_severity] = "Building destroyed"</Filter>
|
<Filter>[disaster_severity] = "Building destroyed"</Filter>
|
||||||
@ -973,4 +1062,139 @@
|
|||||||
<PolygonSymbolizer fill="#ffe8a9" />
|
<PolygonSymbolizer fill="#ffe8a9" />
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style name="typology_classification">
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Low-rise: Not part of a group/cluster (1-3 core floors- excluding extensions)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#0311AB" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Low-rise: Part of dense block/row/terrace"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#3845D4" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Low-rise: Part of group of widely spaced blocks (includes semi-detached houses)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#6D79FD" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Mid-rise: Not part of a group/cluster (4-7 core floors)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FF5D00" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Mid-rise: Part of group of densely spaced blocks"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FF8000" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "Mid-rise: Part of group of widely spaced blocks"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FFA200" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "High rise: Not part of a group/cluster"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#AB1303" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "High-rise: Part of group of densely spaced blocks (8 + core floors)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#D43A29" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_classification] = "High-rise: Part of group of widely spaced blocks"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FC604F" />
|
||||||
|
</Rule>
|
||||||
|
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>17061</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>4264</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>4264</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>0</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="2.0"/>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
|
<Style name="typology_style_period">
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "43AD-410 (Roman)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FFF739" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "410-1485 (Medieval)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#C5BD00" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1485-1603 (Tudor)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#FF9A39" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1603-1714 (Stuart)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#C56000" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1714-1837 (Georgian)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#EA8072" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1837-1901 (Victorian)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#A71200" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1901-1914 (Edwardian)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#A272D4" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1914-1945 (WWI-WWII)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#3988C5" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1946-1979 (Post war)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#5ADFA2" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "1980-1999 (Late 20th Century)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#C2F47A" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_style_period] = "2000-2025 (Early 21st Century)"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#6FB40A" />
|
||||||
|
</Rule>
|
||||||
|
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>17061</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>4264</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>4264</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>0</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="2.0"/>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
|
<Style name="typology_dynamic_classification">
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_dynamic_classification] = "Repetitive small, domestic plots"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#96484A" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_dynamic_classification] = "Linear non-domestic, i.e. high streets"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#4B9889" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_dynamic_classification] = "Large plots with internal roads"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#4F8DA8" />
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<Filter>[typology_dynamic_classification] = "Other"</Filter>
|
||||||
|
<PolygonSymbolizer fill="#897A5D" />
|
||||||
|
</Rule>
|
||||||
|
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>17061</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>4264</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
<MaxScaleDenominator>4264</MaxScaleDenominator>
|
||||||
|
<MinScaleDenominator>0</MinScaleDenominator>
|
||||||
|
<LineSymbolizer stroke="#888" stroke-width="2.0"/>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
</Map>
|
</Map>
|
||||||
|
246
app/package-lock.json
generated
246
app/package-lock.json
generated
@ -128,9 +128,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/core/node_modules/semver": {
|
"node_modules/@babel/core/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -196,9 +196,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -264,9 +264,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
|
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -1664,9 +1664,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
|
"node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -1895,9 +1895,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/preset-env/node_modules/semver": {
|
"node_modules/@babel/preset-env/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -4099,9 +4099,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-istanbul/node_modules/semver": {
|
"node_modules/babel-plugin-istanbul/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -4138,9 +4138,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
|
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -6160,9 +6160,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/default-gateway/node_modules/semver": {
|
"node_modules/default-gateway/node_modules/semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
@ -6994,9 +6994,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react/node_modules/semver": {
|
"node_modules/eslint-plugin-react/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -9776,9 +9776,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/istanbul-lib-instrument/node_modules/semver": {
|
"node_modules/istanbul-lib-instrument/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -10747,9 +10747,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/make-dir/node_modules/semver": {
|
"node_modules/make-dir/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
@ -11523,9 +11523,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/normalize-package-data/node_modules/semver": {
|
"node_modules/normalize-package-data/node_modules/semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
@ -15234,9 +15234,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dev-utils/node_modules/semver": {
|
"node_modules/react-dev-utils/node_modules/semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
@ -16217,9 +16217,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sane/node_modules/semver": {
|
"node_modules/sane/node_modules/semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
@ -16363,9 +16363,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.3.8",
|
"version": "7.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
},
|
},
|
||||||
@ -18206,9 +18206,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tiny-async-pool/node_modules/semver": {
|
"node_modules/tiny-async-pool/node_modules/semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
@ -18311,23 +18311,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tough-cookie": {
|
"node_modules/tough-cookie": {
|
||||||
"version": "4.0.0",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
|
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"psl": "^1.1.33",
|
"psl": "^1.1.33",
|
||||||
"punycode": "^2.1.1",
|
"punycode": "^2.1.1",
|
||||||
"universalify": "^0.1.2"
|
"universalify": "^0.2.0",
|
||||||
|
"url-parse": "^1.5.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tough-cookie/node_modules/universalify": {
|
"node_modules/tough-cookie/node_modules/universalify": {
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
@ -19636,9 +19637,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack-dev-server/node_modules/semver": {
|
"node_modules/webpack-dev-server/node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@ -20144,9 +20145,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/word-wrap": {
|
"node_modules/word-wrap": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@ -20356,9 +20357,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20408,9 +20409,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20460,9 +20461,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
}
|
}
|
||||||
@ -21429,9 +21430,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
}
|
}
|
||||||
@ -21605,9 +21606,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
}
|
}
|
||||||
@ -23391,9 +23392,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23423,9 +23424,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
}
|
}
|
||||||
@ -24995,9 +24996,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
@ -25705,9 +25706,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27756,9 +27757,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28521,9 +28522,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -29127,9 +29128,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31910,9 +31911,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
@ -32690,9 +32691,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
@ -32809,9 +32810,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "7.3.8",
|
"version": "7.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
}
|
}
|
||||||
@ -34294,9 +34295,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34379,20 +34380,21 @@
|
|||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||||
},
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "4.0.0",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
|
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"psl": "^1.1.33",
|
"psl": "^1.1.33",
|
||||||
"punycode": "^2.1.1",
|
"punycode": "^2.1.1",
|
||||||
"universalify": "^0.1.2"
|
"universalify": "^0.2.0",
|
||||||
|
"url-parse": "^1.5.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"universalify": {
|
"universalify": {
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35535,9 +35537,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"sockjs-client": {
|
"sockjs-client": {
|
||||||
@ -35831,9 +35833,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"word-wrap": {
|
"word-wrap": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"worker-rpc": {
|
"worker-rpc": {
|
||||||
|
@ -59,6 +59,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
location_name_link: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
location_number: {
|
location_number: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -103,6 +107,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
},
|
},
|
||||||
|
location_alternative_footprint_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
date_year: {
|
date_year: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -126,6 +134,14 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
date_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
date_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
facade_year: {
|
facade_year: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -254,6 +270,14 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
construction_core_material_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_core_material_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
construction_secondary_materials: {
|
construction_secondary_materials: {
|
||||||
edit: false,
|
edit: false,
|
||||||
},
|
},
|
||||||
@ -261,6 +285,116 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
construction_roof_covering_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_roof_covering_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_structural_system: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_structural_system_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_structural_system_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_foundation: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_foundation_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_foundation_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_roof_shape: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_roof_shape_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_roof_shape_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_irregularities: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_irregularities_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_irregularities_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_decorative_features: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_decorative_feature_materials: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_decorative_feature_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_decorative_feature_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_external_wall: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_external_wall_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_external_wall_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_internal_wall: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_internal_wall_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_internal_wall_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_ground_floor: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_ground_floor_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
construction_ground_floor_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
planning_portal_link: {
|
planning_portal_link: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -277,10 +411,22 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_crowdsourced_site_completion_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_crowdsourced_site_completion_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_crowdsourced_planning_id: {
|
planning_crowdsourced_planning_id: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_in_conservation_area: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_in_conservation_area_id: {
|
planning_in_conservation_area_id: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -301,6 +447,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_world_heritage_site: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_world_list_id: {
|
planning_world_list_id: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -309,14 +459,26 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_in_apa: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_in_apa_url: {
|
planning_in_apa_url: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_local_list: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_local_list_url: {
|
planning_local_list_url: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_historic_area_assessment: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
planning_historic_area_assessment_url: {
|
planning_historic_area_assessment_url: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -325,6 +487,30 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
planning_missing_data: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_missing_data_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_heritage_at_risk: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_scientific_interest: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_scientific_interest_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
planning_scientific_interest_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
sust_breeam_rating: {
|
sust_breeam_rating: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
@ -355,6 +541,14 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true,
|
verify: true,
|
||||||
},
|
},
|
||||||
|
building_attachment_source_type: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
|
building_attachment_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true,
|
||||||
|
},
|
||||||
date_change_building_use: {
|
date_change_building_use: {
|
||||||
edit: true,
|
edit: true,
|
||||||
},
|
},
|
||||||
@ -482,6 +676,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
},
|
},
|
||||||
|
developer_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
developer_source_type: {
|
developer_source_type: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
@ -494,6 +692,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
},
|
},
|
||||||
|
landowner_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
landowner_source_type: {
|
landowner_source_type: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
@ -506,6 +708,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
},
|
},
|
||||||
|
designers_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
designers_source_type: {
|
designers_source_type: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
@ -530,6 +736,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
},
|
},
|
||||||
|
builder_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
builder_source_type: {
|
builder_source_type: {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
@ -685,7 +895,95 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
|
|||||||
age_retrofit_date_source_links : {
|
age_retrofit_date_source_links : {
|
||||||
edit: true,
|
edit: true,
|
||||||
verify: true
|
verify: true
|
||||||
}
|
},
|
||||||
|
age_historical_raster_map_links : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
age_historical_vectorised_footprint_links : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_solar : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_solar_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_solar_source_links : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_green_roof : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_green_roof_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
energy_green_roof_source_links : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_classification : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_classification_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_classification_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_style_period : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_style_period_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_style_period_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_dynamic_classification : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_dynamic_classification_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_dynamic_classification_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_original_use : {
|
||||||
|
edit: true,
|
||||||
|
derivedEdit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_original_use_verified: {
|
||||||
|
edit: true,
|
||||||
|
},
|
||||||
|
typology_original_use_order : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_original_use_source_type : {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
|
typology_original_use_source_links: {
|
||||||
|
edit: true,
|
||||||
|
verify: true
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ type GetAutofillOptionsFn = (value: string, all?: boolean) => Promise<AutofillOp
|
|||||||
|
|
||||||
const autofillFunctionMap : { [fieldName: string] : GetAutofillOptionsFn } = {
|
const autofillFunctionMap : { [fieldName: string] : GetAutofillOptionsFn } = {
|
||||||
current_landuse_group: getLanduseGroupOptions,
|
current_landuse_group: getLanduseGroupOptions,
|
||||||
|
typology_original_use: getLanduseGroupOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ function getLanduseGroupOptions(value: string, all: boolean = false) {
|
|||||||
landuse_id AS id,
|
landuse_id AS id,
|
||||||
description AS value
|
description AS value
|
||||||
FROM reference_tables.buildings_landuse_group
|
FROM reference_tables.buildings_landuse_group
|
||||||
|
ORDER BY description
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { ArgumentError } from '../../errors/general';
|
|||||||
import { updateLandUse } from './landUse';
|
import { updateLandUse } from './landUse';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process land use classifications - derive land use order from land use groups
|
* Process current land use classifications - derive land use order from land use groups
|
||||||
*/
|
*/
|
||||||
async function processCurrentLandUseClassifications(
|
async function processCurrentLandUseClassifications(
|
||||||
buildingId: number,
|
buildingId: number,
|
||||||
@ -40,6 +40,37 @@ async function processCurrentLandUseClassifications(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process original land use classifications - derive land use order from land use groups
|
||||||
|
*/
|
||||||
|
async function processOriginalLandUseClassifications(
|
||||||
|
buildingId: number,
|
||||||
|
buildingUpdate: Partial<BuildingAttributes>,
|
||||||
|
t?: ITask<any>
|
||||||
|
): Promise<any> {
|
||||||
|
const currentBuildingData = await getBuildingData(buildingId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const currentLandUseUpdate = await updateLandUse(
|
||||||
|
{
|
||||||
|
landUseGroup: currentBuildingData.typology_original_use,
|
||||||
|
landUseOrder: currentBuildingData.typology_original_use_order
|
||||||
|
}, {
|
||||||
|
landUseGroup: buildingUpdate.typology_original_use
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return Object.assign({}, buildingUpdate, {
|
||||||
|
typology_original_use: currentLandUseUpdate.landUseGroup,
|
||||||
|
typology_original_use_order: currentLandUseUpdate.landUseOrder,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if(error instanceof ArgumentError && error.argumentName === 'landUseUpdate') {
|
||||||
|
error.argumentName = 'buildingUpdate';
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process Dynamics data - check field relationships and sort demolished buildings by construction date
|
* Process Dynamics data - check field relationships and sort demolished buildings by construction date
|
||||||
@ -81,6 +112,9 @@ export async function processBuildingUpdate(buildingId: number, {attributes, use
|
|||||||
if(hasAnyOwnProperty(attributes, ['current_landuse_group'])) {
|
if(hasAnyOwnProperty(attributes, ['current_landuse_group'])) {
|
||||||
attributes = await processCurrentLandUseClassifications(buildingId, attributes, t);
|
attributes = await processCurrentLandUseClassifications(buildingId, attributes, t);
|
||||||
}
|
}
|
||||||
|
if(hasAnyOwnProperty(attributes, ['typology_original_use'])) {
|
||||||
|
attributes = await processOriginalLandUseClassifications(buildingId, attributes, t);
|
||||||
|
}
|
||||||
if(hasAnyOwnProperty(attributes, ['demolished_buildings', 'dynamics_has_demolished_buildings'])) {
|
if(hasAnyOwnProperty(attributes, ['demolished_buildings', 'dynamics_has_demolished_buildings'])) {
|
||||||
attributes = await processDynamicsDemolishedBuildings(buildingId, attributes, t);
|
attributes = await processDynamicsDemolishedBuildings(buildingId, attributes, t);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"cityName": "Cities",
|
"cityName": "Cities",
|
||||||
"projectBlurb": "Colouring {City Name} is part Colouring Cities.",
|
"projectBlurb": "Colouring {City Name} is part Colouring Cities.",
|
||||||
|
|
||||||
"githubURL": "https://github.com/colouring-cities/colouring-core",
|
"githubURL": "https://github.com/colouring-cities/colouring-core",
|
||||||
|
"manualURL": "https://github.com/colouring-cities/manual/wiki/M3.-COLOURING-BRITAIN",
|
||||||
"privacyStatement": "{Privacy statement goes here}",
|
"privacyStatement": "{Privacy statement goes here}",
|
||||||
|
|
||||||
"initialMapPosition": [ 51.5245255, -0.1338422 ],
|
"initialMapPosition": [ 51.5245255, -0.1338422 ],
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
import { StringNullableChain } from "lodash";
|
||||||
|
|
||||||
export interface CCConfig
|
export interface CCConfig
|
||||||
{
|
{
|
||||||
cityName: string; // City name (i.e. "Colouring {City Name}")
|
cityName: string; // City name (i.e. "Colouring {City Name}")
|
||||||
projectBlurb: string; // Description used on homepage
|
projectBlurb: string; // Description used on homepage
|
||||||
|
|
||||||
githubURL: string; // URL of the project's GitHub repository
|
githubURL: string; // URL of the project's GitHub repository
|
||||||
|
manualURL: string; // Link to the project's page in the Open Manual (i.e. https://github.com/colouring-cities/manual/wiki/M3.-COLOURING-BRITAIN)
|
||||||
privacyStatement: string; // Privacy statement, including where data is stored
|
privacyStatement: string; // Privacy statement, including where data is stored
|
||||||
|
|
||||||
initialMapPosition: [number, number]; // Initial location of the map [latitude, longitude]
|
initialMapPosition: [number, number]; // Initial location of the map [latitude, longitude]
|
||||||
|
@ -76,6 +76,12 @@ export const MultiDataEntry: React.FC<MultiDataEntryProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<ul className="data-entry-list">
|
<ul className="data-entry-list">
|
||||||
|
{
|
||||||
|
isEditing && isDisabled && values.length === 0 &&
|
||||||
|
<div className="input-group">
|
||||||
|
<input className="form-control no-entries" type="text" value="Please add a link below" disabled={true} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
{
|
{
|
||||||
values.map((val, i) => (
|
values.map((val, i) => (
|
||||||
<li className="input-group" key={i /* i as key prevents input component recreation on edit */}>
|
<li className="input-group" key={i /* i as key prevents input component recreation on edit */}>
|
||||||
|
@ -12,11 +12,20 @@ interface PatternDataEntryProps extends BaseDataEntryProps {
|
|||||||
*/
|
*/
|
||||||
pattern: string;
|
pattern: string;
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
|
valueTransform?: (val: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PatternDataEntry: React.FC<PatternDataEntryProps> = props => {
|
export const PatternDataEntry: React.FC<PatternDataEntryProps> = props => {
|
||||||
const handleChange = (value: string) => {
|
const handleChange = (value: string) => {
|
||||||
props.onChange?.(props.slug, value);
|
props.onChange?.(props.slug, transformValue(value));
|
||||||
|
};
|
||||||
|
|
||||||
|
const transformValue = (value: string) => {
|
||||||
|
const transform = props.valueTransform || (x => x);
|
||||||
|
const transformedValue = value === '' ?
|
||||||
|
null :
|
||||||
|
transform(value);
|
||||||
|
return transformedValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -99,7 +99,9 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
|
|||||||
'likes_total',
|
'likes_total',
|
||||||
'community_type_worth_keeping_total',
|
'community_type_worth_keeping_total',
|
||||||
'community_local_significance_total',
|
'community_local_significance_total',
|
||||||
'community_expected_planning_application_total'
|
'community_expected_planning_application_total',
|
||||||
|
'typology_original_use',
|
||||||
|
'typology_original_use_verified'
|
||||||
]
|
]
|
||||||
for (let key in dataFields) {
|
for (let key in dataFields) {
|
||||||
let fieldName = props.building == undefined ? undefined : props.building[key];
|
let fieldName = props.building == undefined ? undefined : props.building[key];
|
||||||
@ -286,6 +288,13 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
|
|||||||
|
|
||||||
this.doSubmit(edits);
|
this.doSubmit(edits);
|
||||||
}
|
}
|
||||||
|
if (slug == 'typology_original_use'){
|
||||||
|
const edits = {
|
||||||
|
'typology_original_use_verified': true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.doSubmit(edits);
|
||||||
|
}
|
||||||
console.log(slug + " verify button clicked")
|
console.log(slug + " verify button clicked")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
import '../../map/map-button.css';
|
import '../../map/map-button.css';
|
||||||
import { dataFields } from '../../config/data-fields-config';
|
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-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 { DynamicsBuildingPane, DynamicsDataEntry } from './dynamics/dynamics-data-entry';
|
||||||
@ -40,27 +40,49 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
const ageLinkUrl = `/${props.mode}/${Category.Age}/${props.building.building_id}`;
|
const ageLinkUrl = `/${props.mode}/${Category.Age}/${props.building.building_id}`;
|
||||||
|
|
||||||
const { historicData, historicDataSwitchOnClick, darkLightTheme } = useDisplayPreferences();
|
const { historicData, historicDataSwitchOnClick, darkLightTheme } = useDisplayPreferences();
|
||||||
|
const { historicMap, historicMapSwitchOnClick } = useDisplayPreferences();
|
||||||
|
|
||||||
const switchToSurvivalMapStyle = (e) => {
|
const switchToSurvivalMapStyle = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('survival_status');
|
||||||
|
historicMapSwitchOnClick(e);
|
||||||
|
|
||||||
if (props.mapColourScale == "survival_status") {
|
if (historicData === 'enabled') {
|
||||||
props.onMapColourScale('date_year');
|
|
||||||
historicDataSwitchOnClick(e);
|
historicDataSwitchOnClick(e);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
|
||||||
|
const switchToSurvivalDataStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
props.onMapColourScale('survival_status');
|
props.onMapColourScale('survival_status');
|
||||||
historicDataSwitchOnClick(e);
|
historicDataSwitchOnClick(e);
|
||||||
|
|
||||||
|
if (historicMap === 'enabled') {
|
||||||
|
historicMapSwitchOnClick(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.building.date_source == "Expert knowledge of building" ||
|
const switchToAgeMapStyle = (e) => {
|
||||||
props.building.date_source == "Expert estimate from image" ||
|
e.preventDefault();
|
||||||
props.building.date_source == null
|
|
||||||
){
|
if (historicData === 'enabled') {
|
||||||
|
historicDataSwitchOnClick(e);
|
||||||
|
}
|
||||||
|
if (historicMap === 'enabled') {
|
||||||
|
historicMapSwitchOnClick(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
props.onMapColourScale('date_year');
|
||||||
|
}
|
||||||
|
|
||||||
|
const switchToStylePeriodMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('typology_style_period')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Building age">
|
<DataEntryGroup name="Building age/construction date">
|
||||||
<YearDataEntry
|
<YearDataEntry
|
||||||
year={props.building.date_year}
|
year={props.building.date_year}
|
||||||
upper={props.building.date_upper}
|
upper={props.building.date_upper}
|
||||||
@ -107,7 +129,7 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.facade_year}
|
user_verified_as={props.user_verified.facade_year}
|
||||||
verified_count={props.building.verified.facade_year}
|
verified_count={props.building.verified.facade_year}
|
||||||
/>
|
/>
|
||||||
|
<hr/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.date_source.title}
|
title={dataFields.date_source.title}
|
||||||
slug="date_source"
|
slug="date_source"
|
||||||
@ -116,8 +138,8 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.date_source.tooltip}
|
tooltip={dataFields.date_source.tooltip}
|
||||||
placeholder={dataFields.date_source.example}
|
|
||||||
options={dataFields.date_source.items}
|
options={dataFields.date_source.items}
|
||||||
|
placeholder={dataFields.date_source.example}
|
||||||
/>
|
/>
|
||||||
{(props.building.date_source == dataFields.date_source.items[0] ||
|
{(props.building.date_source == dataFields.date_source.items[0] ||
|
||||||
props.building.date_source == dataFields.date_source.items[1] ||
|
props.building.date_source == dataFields.date_source.items[1] ||
|
||||||
@ -137,6 +159,101 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.date_source_type.title}
|
||||||
|
slug="date_source_type"
|
||||||
|
value={props.building.date_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.date_source_type.tooltip}
|
||||||
|
options={dataFields.date_source_type.items}
|
||||||
|
placeholder={dataFields.date_source_type.example}
|
||||||
|
/>
|
||||||
|
{(props.building.date_source_type == dataFields.date_source_type.items[0] ||
|
||||||
|
props.building.date_source_type == dataFields.date_source_type.items[1] ||
|
||||||
|
props.building.date_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.date_source_links.title}
|
||||||
|
slug="date_source_links"
|
||||||
|
value={props.building.date_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.date_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{/*<DataEntry
|
||||||
|
title="Year of completion (best estimate)"
|
||||||
|
slug=""
|
||||||
|
value=""
|
||||||
|
mode='view'
|
||||||
|
tooltip='Coming Soon'
|
||||||
|
/>*/}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Architectural style">
|
||||||
|
{(props.mapColourScale == "typology_style_period") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAgeMapStyle}>
|
||||||
|
Click here to return to building age.
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToStylePeriodMapStyle}>
|
||||||
|
Click here to show architectural style.
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_style_period.title}
|
||||||
|
slug="typology_style_period"
|
||||||
|
value={props.building.typology_style_period}
|
||||||
|
tooltip={dataFields.typology_style_period.tooltip}
|
||||||
|
options={dataFields.typology_style_period.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="typology_style_period"
|
||||||
|
allow_verify={props.user !== undefined && props.building.typology_style_period !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("typology_style_period")}
|
||||||
|
user_verified_as={props.user_verified.typology_style_period}
|
||||||
|
verified_count={props.building.verified.typology_style_period}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_style_period_source_type.title}
|
||||||
|
slug="typology_style_period_source_type"
|
||||||
|
value={props.building.typology_style_period_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_style_period_source_type.tooltip}
|
||||||
|
placeholder={dataFields.typology_style_period_source_type.example}
|
||||||
|
options={dataFields.typology_style_period_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.typology_style_period_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.typology_style_period_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.typology_style_period_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_style_period_source_links.title}
|
||||||
|
slug="typology_style_period_source_links"
|
||||||
|
value={props.building.typology_style_period_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_style_period_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Cladding, extensions and retrofits">
|
<DataEntryGroup name="Cladding, extensions and retrofits">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
@ -290,9 +407,6 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Lifespan and site history">
|
<DataEntryGroup name="Lifespan and site history">
|
||||||
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
|
|
||||||
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
|
|
||||||
</button>
|
|
||||||
<DataEntryGroup name="Constructions and demolitions on this site" showCount={false}>
|
<DataEntryGroup name="Constructions and demolitions on this site" showCount={false}>
|
||||||
<DynamicsBuildingPane>
|
<DynamicsBuildingPane>
|
||||||
<label>Current building (age data <Link to={ageLinkUrl}>editable here</Link>)</label>
|
<label>Current building (age data <Link to={ageLinkUrl}>editable here</Link>)</label>
|
||||||
@ -379,388 +493,31 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
Please let us know your suggestions on the <a href="https://discuss.colouring.london/t/dynamics-category-discussion/107">discussion forum</a>! (external link - save your edits first)
|
Please let us know your suggestions on the <a href="https://discuss.colouring.london/t/dynamics-category-discussion/107">discussion forum</a>! (external link - save your edits first)
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Survival and loss tracked using historical maps" collapsed={true} >
|
<DataEntryGroup name="Survival tracking" collapsed={true} >
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
<i>
|
<i>
|
||||||
Can you help us create a map that shows how many buildings in London have survived since the 1890s?
|
Can you help us create a map that shows how many buildings in London have survived since the 1890s?
|
||||||
Choose a colour to indicate whether the building has survived.
|
Choose a colour to indicate whether the building has survived.
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
|
{(historicMap === "enabled") ?
|
||||||
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAgeMapStyle}>
|
||||||
|
Click here to hide the 1890s OS historical map.
|
||||||
</button>
|
</button>
|
||||||
<SelectDataEntry
|
:
|
||||||
title={dataFields.survival_status.title}
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
|
||||||
slug="survival_status"
|
Click here to show the 1890s OS historical map.
|
||||||
value={props.building.survival_status}
|
|
||||||
tooltip={dataFields.survival_status.tooltip}
|
|
||||||
options={SurvivalStatusOptions}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.survival_source.title}
|
|
||||||
slug="survival_source"
|
|
||||||
value={props.building.survival_source}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.survival_source.tooltip}
|
|
||||||
placeholder={dataFields.survival_source.example}
|
|
||||||
options={dataFields.survival_source.items}
|
|
||||||
/>
|
|
||||||
{(props.building.survival_source == dataFields.survival_source_links[0] ||
|
|
||||||
props.building.survival_source == dataFields.survival_source_links[1] ||
|
|
||||||
props.building.survival_source == null) ? <></> :
|
|
||||||
<><MultiDataEntry
|
|
||||||
title={dataFields.survival_source_links.title}
|
|
||||||
slug="survival_source_links"
|
|
||||||
value={props.building.survival_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.survival_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<DataEntryGroup name="Building age">
|
|
||||||
<YearDataEntry
|
|
||||||
year={props.building.date_year}
|
|
||||||
upper={props.building.date_upper}
|
|
||||||
lower={props.building.date_lower}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
|
|
||||||
allow_verify={props.user !== undefined && props.building.date_year !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("date_year")}
|
|
||||||
user_verified_as={props.user_verified.date_year}
|
|
||||||
verified_count={props.building.verified.date_year}
|
|
||||||
|
|
||||||
allow_verify_upper={props.user !== undefined && props.building.date_upper !== null && !props.edited}
|
|
||||||
onVerify_upper={props.onVerify}
|
|
||||||
user_verified_upper={props.user_verified.hasOwnProperty("date_upper")}
|
|
||||||
user_verified_as_upper={props.user_verified.date_upper}
|
|
||||||
verified_count_upper={props.building.verified.date_upper}
|
|
||||||
|
|
||||||
allow_verify_lower={props.user !== undefined && props.building.date_lower !== null && !props.edited}
|
|
||||||
onVerify_lower={props.onVerify}
|
|
||||||
user_verified_lower={props.user_verified.hasOwnProperty("date_lower")}
|
|
||||||
user_verified_as_lower={props.user_verified.date_lower}
|
|
||||||
verified_count_lower={props.building.verified.date_lower}
|
|
||||||
/>
|
|
||||||
<NumericDataEntry
|
|
||||||
title={dataFields.facade_year.title}
|
|
||||||
slug="facade_year"
|
|
||||||
value={props.building.facade_year}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={1}
|
|
||||||
max={currentYear}
|
|
||||||
tooltip={dataFields.facade_year.tooltip}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="facade_year"
|
|
||||||
allow_verify={props.user !== undefined && props.building.facade_year !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("facade_year")}
|
|
||||||
user_verified_as={props.user_verified.facade_year}
|
|
||||||
verified_count={props.building.verified.facade_year}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.date_source.title}
|
|
||||||
slug="date_source"
|
|
||||||
value={props.building.date_source}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.date_source.tooltip}
|
|
||||||
options={dataFields.date_source.items}
|
|
||||||
placeholder={dataFields.date_source.example}
|
|
||||||
/>
|
|
||||||
{(props.building.date_source == dataFields.date_source.items[0] ||
|
|
||||||
props.building.date_source == dataFields.date_source.items[1] ||
|
|
||||||
props.building.date_source == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.date_link.title}
|
|
||||||
slug="date_link"
|
|
||||||
value={props.building.date_link}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.date_link.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
|
||||||
<DataEntryGroup name="Cladding, extensions and retrofits">
|
|
||||||
<NumericDataEntry
|
|
||||||
slug='age_cladding_date'
|
|
||||||
title={dataFields.age_cladding_date.title}
|
|
||||||
value={props.building.age_cladding_date}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={1}
|
|
||||||
max={currentYear}
|
|
||||||
tooltip={dataFields.extension_year.tooltip}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="age_cladding_date"
|
|
||||||
allow_verify={props.user !== undefined && props.building.age_cladding_date !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("age_cladding_date")}
|
|
||||||
user_verified_as={props.user_verified.age_cladding_date}
|
|
||||||
verified_count={props.building.verified.age_cladding_date}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.age_cladding_date_source_type.title}
|
|
||||||
slug="age_cladding_date_source_type"
|
|
||||||
value={props.building.age_cladding_date_source_type}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_cladding_date_source_type.tooltip}
|
|
||||||
options={dataFields.age_cladding_date_source_type.items}
|
|
||||||
placeholder={dataFields.age_cladding_date_source_type.example}
|
|
||||||
/>
|
|
||||||
{(props.building.age_cladding_date_source_type == dataFields.age_cladding_date_source_type.items[0] ||
|
|
||||||
props.building.age_cladding_date_source_type == dataFields.age_cladding_date_source_type.items[1] ||
|
|
||||||
props.building.age_cladding_date_source_type == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.age_cladding_date_source_links.title}
|
|
||||||
slug="age_cladding_date_source_links"
|
|
||||||
value={props.building.age_cladding_date_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_cladding_date_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<hr/>
|
|
||||||
<NumericDataEntry
|
|
||||||
slug='age_extension_date'
|
|
||||||
title={dataFields.age_extension_date.title}
|
|
||||||
value={props.building.age_extension_date}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={1}
|
|
||||||
max={currentYear}
|
|
||||||
tooltip={dataFields.extension_year.tooltip}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="age_extension_date"
|
|
||||||
allow_verify={props.user !== undefined && props.building.age_extension_date !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("age_extension_date")}
|
|
||||||
user_verified_as={props.user_verified.age_extension_date}
|
|
||||||
verified_count={props.building.verified.age_extension_date}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.age_extension_date_source_type.title}
|
|
||||||
slug="age_extension_date_source_type"
|
|
||||||
value={props.building.age_extension_date_source_type}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_extension_date_source_type.tooltip}
|
|
||||||
options={dataFields.age_extension_date_source_type.items}
|
|
||||||
placeholder={dataFields.age_extension_date_source_type.example}
|
|
||||||
/>
|
|
||||||
{(props.building.age_extension_date_source_type == dataFields.age_extension_date_source_type.items[0] ||
|
|
||||||
props.building.age_extension_date_source_type == dataFields.age_extension_date_source_type.items[1] ||
|
|
||||||
props.building.age_extension_date_source_type == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.age_extension_date_source_links.title}
|
|
||||||
slug="age_extension_date_source_links"
|
|
||||||
value={props.building.age_extension_date_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_extension_date_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<hr/>
|
|
||||||
<NumericDataEntry
|
|
||||||
slug='age_retrofit_date'
|
|
||||||
title={dataFields.age_retrofit_date.title}
|
|
||||||
value={props.building.age_retrofit_date}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={1}
|
|
||||||
max={currentYear}
|
|
||||||
tooltip={dataFields.extension_year.tooltip}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="age_retrofit_date"
|
|
||||||
allow_verify={props.user !== undefined && props.building.age_retrofit_date !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("age_retrofit_date")}
|
|
||||||
user_verified_as={props.user_verified.age_retrofit_date}
|
|
||||||
verified_count={props.building.verified.age_retrofit_date}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.age_retrofit_date_source_type.title}
|
|
||||||
slug="age_retrofit_date_source_type"
|
|
||||||
value={props.building.age_retrofit_date_source_type}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_retrofit_date_source_type.tooltip}
|
|
||||||
options={dataFields.age_retrofit_date_source_type.items}
|
|
||||||
placeholder={dataFields.age_retrofit_date_source_type.example}
|
|
||||||
/>
|
|
||||||
{(props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[0] ||
|
|
||||||
props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[1] ||
|
|
||||||
props.building.age_retrofit_date_source_type == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.age_retrofit_date_source_links.title}
|
|
||||||
slug="age_retrofit_date_source_links"
|
|
||||||
value={props.building.age_retrofit_date_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.age_retrofit_date_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
|
||||||
<DataEntryGroup name="Lifespan and site history">
|
|
||||||
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
|
|
||||||
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
|
|
||||||
</button>
|
</button>
|
||||||
<DataEntryGroup name="Constructions and demolitions on this site" showCount={false}>
|
|
||||||
<DynamicsBuildingPane>
|
|
||||||
<label>Current building (age data <Link to={ageLinkUrl}>editable here</Link>)</label>
|
|
||||||
<FieldRow>
|
|
||||||
<div>
|
|
||||||
<NumericDataEntry
|
|
||||||
slug=''
|
|
||||||
title={dataFields.demolished_buildings.items.year_constructed.title}
|
|
||||||
value={currentBuildingConstructionYear}
|
|
||||||
disabled={true}
|
|
||||||
mode='view'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<NumericDataEntry
|
|
||||||
slug=''
|
|
||||||
title={dataFields.demolished_buildings.items.year_demolished.title}
|
|
||||||
value={undefined}
|
|
||||||
placeholder='---'
|
|
||||||
disabled={true}
|
|
||||||
mode='view'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{flex: '0 1 27%'}}>
|
|
||||||
<DataEntry
|
|
||||||
slug=''
|
|
||||||
title='Lifespan to date'
|
|
||||||
value={ (thisYear - currentBuildingConstructionYear) + ''}
|
|
||||||
disabled={true}
|
|
||||||
mode='view'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FieldRow>
|
|
||||||
</DynamicsBuildingPane>
|
|
||||||
{
|
|
||||||
currentBuildingConstructionYear == undefined ?
|
|
||||||
<InfoBox>To add historical records, fill in the <Link to={ageLinkUrl}>Age</Link> data first.</InfoBox> :
|
|
||||||
|
|
||||||
<>
|
|
||||||
<LogicalDataEntry
|
|
||||||
slug='dynamics_has_demolished_buildings'
|
|
||||||
title={dataFields.dynamics_has_demolished_buildings.title}
|
|
||||||
value={building.dynamics_has_demolished_buildings}
|
|
||||||
disallowFalse={(building.demolished_buildings?.length ?? 0) > 0}
|
|
||||||
disallowNull={(building.demolished_buildings?.length ?? 0) > 0}
|
|
||||||
|
|
||||||
onChange={props.onSaveChange}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
building.dynamics_has_demolished_buildings &&
|
|
||||||
<>
|
|
||||||
<DynamicsDataEntry
|
|
||||||
|
|
||||||
/*
|
|
||||||
Will clear the edits and new record data upon navigating to another building.
|
|
||||||
Should get a better way to do this, plus a way to actually keep unsaved edits.
|
|
||||||
*/
|
|
||||||
key={building.building_id}
|
|
||||||
|
|
||||||
value={building.demolished_buildings}
|
|
||||||
editableEntries={true}
|
|
||||||
slug='demolished_buildings'
|
|
||||||
title={dataFields.demolished_buildings.title}
|
|
||||||
mode={props.mode}
|
|
||||||
onChange={props.onChange}
|
|
||||||
onSaveAdd={props.onSaveAdd}
|
|
||||||
hasEdits={props.edited}
|
|
||||||
maxYear={currentBuildingConstructionYear}
|
|
||||||
minYear={50}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
props.mode === 'view' &&
|
|
||||||
<InfoBox>Switch to edit mode to add/edit past building records</InfoBox>
|
|
||||||
}
|
}
|
||||||
</>
|
{(historicData === "enabled") ?
|
||||||
}
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAgeMapStyle}>
|
||||||
</>
|
Click here to hide the 1890s OS historical map with modern footprints.
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
|
||||||
<InfoBox type='warning'>
|
|
||||||
This section is under development in collaboration with the historic environment sector.
|
|
||||||
Please let us know your suggestions on the <a href="https://discuss.colouring.london/t/dynamics-category-discussion/107">discussion forum</a>! (external link - save your edits first)
|
|
||||||
</InfoBox>
|
|
||||||
</DataEntryGroup>
|
|
||||||
<DataEntryGroup name="Survival and loss tracked using historical maps" collapsed={true} >
|
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
|
||||||
<i>
|
|
||||||
Can you help us create a map that shows how many buildings in London have survived since the 1890s?
|
|
||||||
Choose a colour to indicate whether the building has survived.
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
|
|
||||||
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
|
|
||||||
</button>
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalDataStyle}>
|
||||||
|
Click here to show the 1890s OS historical map with modern footprints.
|
||||||
|
</button>
|
||||||
|
}
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.survival_status.title}
|
title={dataFields.survival_status.title}
|
||||||
slug="survival_status"
|
slug="survival_status"
|
||||||
@ -800,6 +557,40 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Historical map data options" collapsed={true} >
|
||||||
|
<InfoBox type='warning'>
|
||||||
|
This section is under development
|
||||||
|
</InfoBox>
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i>
|
||||||
|
This section provides links to open digitised historical maps/mapping data that we are using in the Colouring Cities platform.
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.age_historical_raster_map_links.title}
|
||||||
|
slug="age_historical_raster_map_links"
|
||||||
|
value={props.building.age_historical_raster_map_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.age_historical_raster_map_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.age_historical_vectorised_footprint_links.title}
|
||||||
|
slug="age_historical_vectorised_footprint_links"
|
||||||
|
value={props.building.age_historical_vectorised_footprint_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.age_historical_vectorised_footprint_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
import '../../map/map-button.css';
|
import '../../map/map-button.css';
|
||||||
import withCopyEdit from '../data-container';
|
import withCopyEdit from '../data-container';
|
||||||
@ -15,6 +15,7 @@ import SelectDataEntry from '../data-components/select-data-entry';
|
|||||||
import Verification from '../data-components/verification';
|
import Verification from '../data-components/verification';
|
||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||||
|
import DataEntry from '../data-components/data-entry';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Community view/edit section
|
* Community view/edit section
|
||||||
@ -38,8 +39,9 @@ const CommunityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
const { darkLightTheme } = useDisplayPreferences();
|
const { darkLightTheme } = useDisplayPreferences();
|
||||||
const worthKeepingReasonsNonEmpty = Object.values(props.building.community_type_worth_keeping_reasons ?? {}).some(x => x);
|
const worthKeepingReasonsNonEmpty = Object.values(props.building.community_type_worth_keeping_reasons ?? {}).some(x => x);
|
||||||
return <>
|
return (
|
||||||
<DataEntryGroup name="Community views on building types">
|
<Fragment>
|
||||||
|
<DataEntryGroup name="Community views on how well buildings work">
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
<i>
|
<i>
|
||||||
Note: We are currently only collecting data on non-residential buildings.
|
Note: We are currently only collecting data on non-residential buildings.
|
||||||
@ -133,6 +135,11 @@ const CommunityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
/>
|
/>
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i>
|
||||||
|
For more information on current planning applications, refer to the Planning Controls category.
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
{(props.mapColourScale == "community_expected_planning_application_total") ?
|
{(props.mapColourScale == "community_expected_planning_application_total") ?
|
||||||
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
|
||||||
{'Click to return to liked typologies mapped.'}
|
{'Click to return to liked typologies mapped.'}
|
||||||
@ -144,7 +151,7 @@ const CommunityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Building use for community activities">
|
<DataEntryGroup name="Buildings in community use">
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
<i>
|
<i>
|
||||||
Here we are collecting information on the location of buildings used for community activities so we can track loss of/additions to community space over time.
|
Here we are collecting information on the location of buildings used for community activities so we can track loss of/additions to community space over time.
|
||||||
@ -223,7 +230,8 @@ const CommunityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</>
|
</Fragment>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const CommunityContainer = withCopyEdit(CommunityView);
|
const CommunityContainer = withCopyEdit(CommunityView);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
import { dataFields } from '../../config/data-fields-config';
|
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
||||||
import DataEntry from '../data-components/data-entry';
|
import DataEntry from '../data-components/data-entry';
|
||||||
import SelectDataEntry from '../data-components/select-data-entry';
|
import SelectDataEntry from '../data-components/select-data-entry';
|
||||||
import withCopyEdit from '../data-container';
|
import withCopyEdit from '../data-container';
|
||||||
@ -9,6 +9,8 @@ import Verification from '../data-components/verification';
|
|||||||
import { CategoryViewProps } from './category-view-props';
|
import { CategoryViewProps } from './category-view-props';
|
||||||
import InfoBox from '../../components/info-box';
|
import InfoBox from '../../components/info-box';
|
||||||
import { DataEntryGroup } from '../data-components/data-entry-group';
|
import { DataEntryGroup } from '../data-components/data-entry-group';
|
||||||
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
|
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry';
|
||||||
|
|
||||||
const ConstructionMaterialsOptions = [
|
const ConstructionMaterialsOptions = [
|
||||||
'Wood',
|
'Wood',
|
||||||
@ -21,23 +23,205 @@ const ConstructionMaterialsOptions = [
|
|||||||
'Other Man-Made Material'
|
'Other Man-Made Material'
|
||||||
];
|
];
|
||||||
|
|
||||||
const RoofCoveringOptions = [
|
|
||||||
'Slate',
|
|
||||||
'Clay Tile',
|
|
||||||
'Wood',
|
|
||||||
'Asphalt',
|
|
||||||
'Iron or Steel',
|
|
||||||
'Other Metal',
|
|
||||||
'Other Natural Material',
|
|
||||||
'Other Man-Made Material'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construction view/edit section
|
* Construction view/edit section
|
||||||
*/
|
*/
|
||||||
const ConstructionView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
const ConstructionView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
<DataEntryGroup name="Structural system">
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_structural_system.title}
|
||||||
|
slug="construction_structural_system"
|
||||||
|
value={props.building.construction_structural_system}
|
||||||
|
tooltip={dataFields.construction_structural_system.tooltip}
|
||||||
|
options={dataFields.construction_structural_system.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_structural_system"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_structural_system !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_structural_system")}
|
||||||
|
user_verified_as={props.user_verified.construction_structural_system}
|
||||||
|
verified_count={props.building.verified.construction_structural_system}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_structural_system_source_type.title}
|
||||||
|
slug="construction_structural_system_source_type"
|
||||||
|
value={props.building.construction_structural_system_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_structural_system_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_structural_system_source_type.example}
|
||||||
|
options={dataFields.construction_structural_system_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_structural_system_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_structural_system_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_structural_system_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_structural_system_source_links.title}
|
||||||
|
slug="construction_structural_system_source_links"
|
||||||
|
value={props.building.construction_structural_system_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_structural_system_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_foundation.title}
|
||||||
|
slug="construction_foundation"
|
||||||
|
value={props.building.construction_foundation}
|
||||||
|
tooltip={dataFields.construction_foundation.tooltip}
|
||||||
|
options={dataFields.construction_foundation.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_foundation"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_foundation !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_foundation")}
|
||||||
|
user_verified_as={props.user_verified.construction_foundation}
|
||||||
|
verified_count={props.building.verified.construction_foundation}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_foundation_source_type.title}
|
||||||
|
slug="construction_foundation_source_type"
|
||||||
|
value={props.building.construction_foundation_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_foundation_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_foundation_source_type.example}
|
||||||
|
options={dataFields.construction_foundation_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_foundation_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_foundation_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_foundation_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_foundation_source_links.title}
|
||||||
|
slug="construction_foundation_source_links"
|
||||||
|
value={props.building.construction_foundation_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_foundation_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_roof_shape.title}
|
||||||
|
slug="construction_roof_shape"
|
||||||
|
value={props.building.construction_roof_shape}
|
||||||
|
tooltip={dataFields.construction_roof_shape.tooltip}
|
||||||
|
options={dataFields.construction_roof_shape.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_roof_shape"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_roof_shape !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_roof_shape")}
|
||||||
|
user_verified_as={props.user_verified.construction_roof_shape}
|
||||||
|
verified_count={props.building.verified.construction_roof_shape}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_roof_shape_source_type.title}
|
||||||
|
slug="construction_roof_shape_source_type"
|
||||||
|
value={props.building.construction_roof_shape_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_roof_shape_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_roof_shape_source_type.example}
|
||||||
|
options={dataFields.construction_roof_shape_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_roof_shape_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_roof_shape_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_roof_shape_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_roof_shape_source_links.title}
|
||||||
|
slug="construction_roof_shape_source_links"
|
||||||
|
value={props.building.construction_roof_shape_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_roof_shape_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_irregularities.title}
|
||||||
|
slug="construction_irregularities"
|
||||||
|
value={props.building.construction_irregularities}
|
||||||
|
tooltip={dataFields.construction_irregularities.tooltip}
|
||||||
|
options={dataFields.construction_irregularities.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_irregularities"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_irregularities !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_irregularities")}
|
||||||
|
user_verified_as={props.user_verified.construction_irregularities}
|
||||||
|
verified_count={props.building.verified.construction_irregularities}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_irregularities_source_type.title}
|
||||||
|
slug="construction_irregularities_source_type"
|
||||||
|
value={props.building.construction_irregularities_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_irregularities_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_irregularities_source_type.example}
|
||||||
|
options={dataFields.construction_irregularities_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_irregularities_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_irregularities_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_irregularities_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_irregularities_source_links.title}
|
||||||
|
slug="construction_irregularities_source_links"
|
||||||
|
value={props.building.construction_irregularities_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_irregularities_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Materials">
|
<DataEntryGroup name="Materials">
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.construction_core_material.title}
|
title={dataFields.construction_core_material.title}
|
||||||
@ -58,22 +242,185 @@ const ConstructionView: React.FunctionComponent<CategoryViewProps> = (props) =>
|
|||||||
verified_count={props.building.verified.construction_core_material}
|
verified_count={props.building.verified.construction_core_material}
|
||||||
/>
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.construction_secondary_materials.title}
|
title={dataFields.construction_core_material_source_type.title}
|
||||||
disabled={true}
|
slug="construction_core_material_source_type"
|
||||||
slug="construction_secondary_materials"
|
value={props.building.construction_core_material_source_type}
|
||||||
value={props.building.construction_secondary_materials}
|
mode={props.mode}
|
||||||
tooltip={dataFields.construction_secondary_materials.tooltip}
|
copy={props.copy}
|
||||||
options={ConstructionMaterialsOptions}
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_core_material_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_core_material_source_type.example}
|
||||||
|
options={dataFields.construction_core_material_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_core_material_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_core_material_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_core_material_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_core_material_source_links.title}
|
||||||
|
slug="construction_core_material_source_links"
|
||||||
|
value={props.building.construction_core_material_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_core_material_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_external_wall.title}
|
||||||
|
slug="construction_external_wall"
|
||||||
|
value={props.building.construction_external_wall}
|
||||||
|
tooltip={dataFields.construction_external_wall.tooltip}
|
||||||
|
options={dataFields.construction_external_wall.items}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/>
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_external_wall"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_external_wall !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_external_wall")}
|
||||||
|
user_verified_as={props.user_verified.construction_external_wall}
|
||||||
|
verified_count={props.building.verified.construction_external_wall}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_external_wall_source_type.title}
|
||||||
|
slug="construction_external_wall_source_type"
|
||||||
|
value={props.building.construction_external_wall_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_external_wall_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_external_wall_source_type.example}
|
||||||
|
options={dataFields.construction_external_wall_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_external_wall_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_external_wall_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_external_wall_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_external_wall_source_links.title}
|
||||||
|
slug="construction_external_wall_source_links"
|
||||||
|
value={props.building.construction_external_wall_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_external_wall_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_internal_wall.title}
|
||||||
|
slug="construction_internal_wall"
|
||||||
|
value={props.building.construction_internal_wall}
|
||||||
|
tooltip={dataFields.construction_internal_wall.tooltip}
|
||||||
|
options={dataFields.construction_internal_wall.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_internal_wall"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_internal_wall !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_internal_wall")}
|
||||||
|
user_verified_as={props.user_verified.construction_internal_wall}
|
||||||
|
verified_count={props.building.verified.construction_internal_wall}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_internal_wall_source_type.title}
|
||||||
|
slug="construction_internal_wall_source_type"
|
||||||
|
value={props.building.construction_internal_wall_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_internal_wall_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_internal_wall_source_type.example}
|
||||||
|
options={dataFields.construction_internal_wall_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_internal_wall_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_internal_wall_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_internal_wall_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_internal_wall_source_links.title}
|
||||||
|
slug="construction_internal_wall_source_links"
|
||||||
|
value={props.building.construction_internal_wall_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_internal_wall_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_ground_floor.title}
|
||||||
|
slug="construction_ground_floor"
|
||||||
|
value={props.building.construction_ground_floor}
|
||||||
|
tooltip={dataFields.construction_ground_floor.tooltip}
|
||||||
|
options={dataFields.construction_ground_floor.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_ground_floor"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_ground_floor !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_ground_floor")}
|
||||||
|
user_verified_as={props.user_verified.construction_ground_floor}
|
||||||
|
verified_count={props.building.verified.construction_ground_floor}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_ground_floor_source_type.title}
|
||||||
|
slug="construction_ground_floor_source_type"
|
||||||
|
value={props.building.construction_ground_floor_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_ground_floor_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_ground_floor_source_type.example}
|
||||||
|
options={dataFields.construction_ground_floor_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_ground_floor_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_ground_floor_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_ground_floor_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_ground_floor_source_links.title}
|
||||||
|
slug="construction_ground_floor_source_links"
|
||||||
|
value={props.building.construction_ground_floor_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_ground_floor_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.construction_roof_covering.title}
|
title={dataFields.construction_roof_covering.title}
|
||||||
slug="construction_roof_covering"
|
slug="construction_roof_covering"
|
||||||
value={props.building.construction_roof_covering}
|
value={props.building.construction_roof_covering}
|
||||||
tooltip={dataFields.construction_roof_covering.tooltip}
|
tooltip={dataFields.construction_roof_covering.tooltip}
|
||||||
options={RoofCoveringOptions}
|
options={dataFields.construction_roof_covering.items}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
@ -86,14 +433,105 @@ const ConstructionView: React.FunctionComponent<CategoryViewProps> = (props) =>
|
|||||||
user_verified_as={props.user_verified.construction_roof_covering}
|
user_verified_as={props.user_verified.construction_roof_covering}
|
||||||
verified_count={props.building.verified.construction_roof_covering}
|
verified_count={props.building.verified.construction_roof_covering}
|
||||||
/>
|
/>
|
||||||
</DataEntryGroup>
|
<SelectDataEntry
|
||||||
<DataEntryGroup name="Construction sectors">
|
title={dataFields.construction_roof_covering_source_type.title}
|
||||||
<DataEntry
|
slug="construction_roof_covering_source_type"
|
||||||
title="Construction system type"
|
value={props.building.construction_roof_covering_source_type}
|
||||||
slug=""
|
mode={props.mode}
|
||||||
value=""
|
copy={props.copy}
|
||||||
mode='view'
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_roof_covering_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_roof_covering_source_type.example}
|
||||||
|
options={dataFields.construction_roof_covering_source_type.items}
|
||||||
/>
|
/>
|
||||||
|
{(props.building.construction_roof_covering_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_roof_covering_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_roof_covering_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_roof_covering_source_links.title}
|
||||||
|
slug="construction_roof_covering_source_links"
|
||||||
|
value={props.building.construction_roof_covering_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_roof_covering_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Decorative features">
|
||||||
|
<LogicalDataEntry
|
||||||
|
slug='construction_decorative_features'
|
||||||
|
title={dataFields.construction_decorative_features.title}
|
||||||
|
value={props.building.construction_decorative_features}
|
||||||
|
onChange={props.onSaveChange}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_decorative_features"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_decorative_features !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_decorative_features")}
|
||||||
|
user_verified_as={props.user_verified.construction_decorative_features}
|
||||||
|
verified_count={props.building.verified.construction_decorative_features}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
props.building.construction_decorative_features &&
|
||||||
|
<>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_decorative_feature_materials.title}
|
||||||
|
slug="construction_decorative_feature_materials"
|
||||||
|
value={props.building.construction_decorative_feature_materials}
|
||||||
|
tooltip={dataFields.construction_decorative_feature_materials.tooltip}
|
||||||
|
options={dataFields.construction_decorative_feature_materials.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="construction_decorative_feature_materials"
|
||||||
|
allow_verify={props.user !== undefined && props.building.construction_decorative_feature_materials !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("construction_decorative_feature_materials")}
|
||||||
|
user_verified_as={props.user_verified.construction_decorative_feature_materials}
|
||||||
|
verified_count={props.building.verified.construction_decorative_feature_materials}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.construction_decorative_feature_source_type.title}
|
||||||
|
slug="construction_decorative_feature_source_type"
|
||||||
|
value={props.building.construction_decorative_feature_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_decorative_feature_source_type.tooltip}
|
||||||
|
placeholder={dataFields.construction_decorative_feature_source_type.example}
|
||||||
|
options={dataFields.construction_decorative_feature_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.construction_decorative_feature_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.construction_decorative_feature_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.construction_decorative_feature_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.construction_decorative_feature_source_links.title}
|
||||||
|
slug="construction_decorative_feature_source_links"
|
||||||
|
value={props.building.construction_decorative_feature_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.construction_decorative_feature_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -11,6 +11,7 @@ import InfoBox from '../../components/info-box';
|
|||||||
import { CategoryViewProps } from './category-view-props';
|
import { CategoryViewProps } from './category-view-props';
|
||||||
import { DataEntryGroup } from '../data-components/data-entry-group';
|
import { DataEntryGroup } from '../data-components/data-entry-group';
|
||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
|
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry';
|
||||||
|
|
||||||
const EnergyCategoryOptions = ["A", "B", "C", "D", "E", "F", "G"];
|
const EnergyCategoryOptions = ["A", "B", "C", "D", "E", "F", "G"];
|
||||||
const BreeamRatingOptions = [
|
const BreeamRatingOptions = [
|
||||||
@ -25,9 +26,20 @@ const BreeamRatingOptions = [
|
|||||||
* Sustainability view/edit section
|
* Sustainability view/edit section
|
||||||
*/
|
*/
|
||||||
const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||||
|
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Energy rating data">
|
<DataEntryGroup name="Environmental quality rating">
|
||||||
|
<DataEntry
|
||||||
|
title="Official environmental quality rating"
|
||||||
|
slug=""
|
||||||
|
value=""
|
||||||
|
mode='view'
|
||||||
|
/>
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Energy rating">
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.sust_breeam_rating.title}
|
title={dataFields.sust_breeam_rating.title}
|
||||||
slug="sust_breeam_rating"
|
slug="sust_breeam_rating"
|
||||||
@ -46,7 +58,6 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
|
|||||||
user_verified_as={props.user_verified.sust_breeam_rating}
|
user_verified_as={props.user_verified.sust_breeam_rating}
|
||||||
verified_count={props.building.verified.sust_breeam_rating}
|
verified_count={props.building.verified.sust_breeam_rating}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.sust_dec.title}
|
title={dataFields.sust_dec.title}
|
||||||
slug="sust_dec"
|
slug="sust_dec"
|
||||||
@ -65,7 +76,6 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
|
|||||||
user_verified_as={props.user_verified.sust_dec}
|
user_verified_as={props.user_verified.sust_dec}
|
||||||
verified_count={props.building.verified.sust_dec}
|
verified_count={props.building.verified.sust_dec}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.sust_aggregate_estimate_epc.title}
|
title={dataFields.sust_aggregate_estimate_epc.title}
|
||||||
slug="sust_aggregate_estimate_epc"
|
slug="sust_aggregate_estimate_epc"
|
||||||
@ -78,91 +88,160 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
|
|||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/>
|
/>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Retrofit Data">
|
<DataEntryGroup name="Retrofit history">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.sust_retrofit_date.title}
|
slug='age_retrofit_date'
|
||||||
slug="sust_retrofit_date"
|
title={dataFields.age_retrofit_date.title}
|
||||||
value={props.building.sust_retrofit_date}
|
value={props.building.age_retrofit_date}
|
||||||
tooltip={dataFields.sust_retrofit_date.tooltip}
|
|
||||||
step={1}
|
|
||||||
min={1086}
|
|
||||||
max={new Date().getFullYear()}
|
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
|
step={1}
|
||||||
|
min={1}
|
||||||
|
max={currentYear}
|
||||||
|
tooltip={dataFields.extension_year.tooltip}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="sust_retrofit_date"
|
slug="age_retrofit_date"
|
||||||
allow_verify={props.user !== undefined && props.building.sust_retrofit_date !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.age_retrofit_date !== null && !props.edited}
|
||||||
onVerify={props.onVerify}
|
onVerify={props.onVerify}
|
||||||
user_verified={props.user_verified.hasOwnProperty("sust_retrofit_date")}
|
user_verified={props.user_verified.hasOwnProperty("age_retrofit_date")}
|
||||||
user_verified_as={props.user_verified.sust_retrofit_date}
|
user_verified_as={props.user_verified.age_retrofit_date}
|
||||||
verified_count={props.building.verified.sust_retrofit_date}
|
verified_count={props.building.verified.age_retrofit_date}
|
||||||
/>
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.sust_retrofit_source_type.title}
|
title={dataFields.age_retrofit_date_source_type.title}
|
||||||
slug="sust_retrofit_source_type"
|
slug="age_retrofit_date_source_type"
|
||||||
value={props.building.sust_retrofit_source_type}
|
value={props.building.age_retrofit_date_source_type}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.sust_retrofit_source_type.tooltip}
|
tooltip={dataFields.age_retrofit_date_source_type.tooltip}
|
||||||
options={dataFields.sust_retrofit_source_type.items}
|
options={dataFields.age_retrofit_date_source_type.items}
|
||||||
placeholder={dataFields.sust_retrofit_source_type.example}
|
placeholder={dataFields.age_retrofit_date_source_type.example}
|
||||||
/>
|
/>
|
||||||
{(props.building.sust_retrofit_source_type == dataFields.sust_retrofit_source_type.items[0] ||
|
{(props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[0] ||
|
||||||
props.building.sust_retrofit_source_type == dataFields.sust_retrofit_source_type.items[1] ||
|
props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[1] ||
|
||||||
props.building.sust_retrofit_source_type == null) ? <></> :
|
props.building.age_retrofit_date_source_type == null) ? <></> :
|
||||||
<>
|
<>
|
||||||
<MultiDataEntry
|
<MultiDataEntry
|
||||||
title={dataFields.sust_retrofit_source_links.title}
|
title={dataFields.age_retrofit_date_source_links.title}
|
||||||
slug="sust_retrofit_source_links"
|
slug="age_retrofit_date_source_links"
|
||||||
value={props.building.sust_retrofit_source_links}
|
value={props.building.age_retrofit_date_source_links}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.sust_retrofit_source_links.tooltip}
|
tooltip={dataFields.age_retrofit_date_source_links.tooltip}
|
||||||
placeholder="https://..."
|
placeholder="https://..."
|
||||||
editableEntries={true}
|
editableEntries={true}
|
||||||
isUrl={true}
|
isUrl={true}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
{/* <hr/>
|
</DataEntryGroup>
|
||||||
<DataEntry
|
<DataEntryGroup name="Solar panels">
|
||||||
title="Date of Significant Retrofits"
|
<LogicalDataEntry
|
||||||
slug=""
|
title={dataFields.energy_solar.title}
|
||||||
value=""
|
slug="energy_solar"
|
||||||
mode='view'
|
value={props.building.energy_solar}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_solar.tooltip}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="date_link"
|
slug="energy_solar"
|
||||||
allow_verify={props.user !== undefined && props.building.date_link !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.energy_solar !== null && !props.edited}
|
||||||
onVerify={props.onVerify}
|
onVerify={props.onVerify}
|
||||||
user_verified={props.user_verified.hasOwnProperty("date_link")}
|
user_verified={props.user_verified.hasOwnProperty("energy_solar")}
|
||||||
user_verified_as={props.user_verified.date_link}
|
user_verified_as={props.user_verified.energy_solar}
|
||||||
verified_count={props.building.verified.date_link}
|
verified_count={props.building.verified.energy_solar}
|
||||||
/>
|
/>
|
||||||
<DataEntry
|
{props.building.energy_solar == null ? <></> :
|
||||||
title="Source"
|
<>
|
||||||
slug=""
|
<SelectDataEntry
|
||||||
value=""
|
title={dataFields.energy_solar_source_type.title}
|
||||||
mode='view'
|
slug="energy_solar_source_type"
|
||||||
/> */}
|
value={props.building.energy_solar_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_solar_source_type.tooltip}
|
||||||
|
options={dataFields.energy_solar_source_type.items}
|
||||||
|
placeholder={dataFields.energy_solar_source_type.example}
|
||||||
|
/>
|
||||||
|
{(props.building.energy_solar_source_type == dataFields.energy_solar_source_type.items[0] ||
|
||||||
|
props.building.energy_solar_source_type == dataFields.energy_solar_source_type.items[1] ||
|
||||||
|
props.building.energy_solar_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.energy_solar_source_links.title}
|
||||||
|
slug="energy_solar_source_links"
|
||||||
|
value={props.building.energy_solar_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_solar_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Other sustainability features">
|
<DataEntryGroup name="Green walls/roof">
|
||||||
<DataEntry
|
<LogicalDataEntry
|
||||||
title="Does the building have Solar Panels?"
|
title={dataFields.energy_green_roof.title}
|
||||||
slug=""
|
slug="energy_green_roof"
|
||||||
value=""
|
value={props.building.energy_green_roof}
|
||||||
mode='view'
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_green_roof.tooltip}
|
||||||
/>
|
/>
|
||||||
<DataEntry
|
<Verification
|
||||||
title="Does the building have Green Walls / Green Roof"
|
slug="energy_green_roof"
|
||||||
slug=""
|
allow_verify={props.user !== undefined && props.building.energy_green_roof !== null && !props.edited}
|
||||||
value=""
|
onVerify={props.onVerify}
|
||||||
mode='view'
|
user_verified={props.user_verified.hasOwnProperty("energy_green_roof")}
|
||||||
|
user_verified_as={props.user_verified.energy_green_roof}
|
||||||
|
verified_count={props.building.verified.energy_green_roof}
|
||||||
/>
|
/>
|
||||||
|
{props.building.energy_green_roof == null ? <></> :
|
||||||
|
<>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.energy_green_roof_source_type.title}
|
||||||
|
slug="energy_green_roof_source_type"
|
||||||
|
value={props.building.energy_green_roof_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_green_roof_source_type.tooltip}
|
||||||
|
options={dataFields.energy_green_roof_source_type.items}
|
||||||
|
placeholder={dataFields.energy_green_roof_source_type.example}
|
||||||
|
/>
|
||||||
|
{(props.building.energy_green_roof_source_type == dataFields.energy_green_roof_source_type.items[0] ||
|
||||||
|
props.building.energy_green_roof_source_type == dataFields.energy_green_roof_source_type.items[1] ||
|
||||||
|
props.building.energy_green_roof_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.energy_green_roof_source_links.title}
|
||||||
|
slug="energy_green_roof_source_links"
|
||||||
|
value={props.building.energy_green_roof_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.energy_green_roof_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -32,14 +32,14 @@ const UseView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
const { darkLightTheme } = useDisplayPreferences();
|
const { darkLightTheme } = useDisplayPreferences();
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Residential/non-residential land use data (general)">
|
<DataEntryGroup name="General Land Use">
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
<i>
|
<i>
|
||||||
The vast majority of properties are residential (93% in the UK), so we have set 'residential' as the default value. Can you help us identify non-residential and mixed use buildings (and verify residential buildings too)?
|
The vast majority of properties are residential (93% in the UK), so we have set 'residential' as the default value. Can you help us identify non-residential and mixed use buildings (and verify residential buildings too)?
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<button className={`map-switcher-inline ${props.mapColourScale == "is_domestic" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToIsDomesticMapStyle}>
|
<button className={`map-switcher-inline ${props.mapColourScale == "is_domestic" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToIsDomesticMapStyle}>
|
||||||
{(props.mapColourScale == "is_domestic")? 'Showing domestic, non-domestic and mixed-use buildings (click to hide)' : 'Click to see domestic, non-domestic and mixed-use buildings on the map.'}
|
{(props.mapColourScale == "is_domestic")? 'Showing residential, non-residential and mixed-use buildings (click to hide)' : 'Click to see residential, non-residential and mixed-use buildings on the map.'}
|
||||||
</button>
|
</button>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.is_domestic.title}
|
title={dataFields.is_domestic.title}
|
||||||
@ -87,7 +87,7 @@ const UseView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Specific land use data">
|
<DataEntryGroup name="Specific land use(s)">
|
||||||
<MultiDataEntry
|
<MultiDataEntry
|
||||||
title={dataFields.current_landuse_group.title}
|
title={dataFields.current_landuse_group.title}
|
||||||
slug="current_landuse_group"
|
slug="current_landuse_group"
|
||||||
@ -138,6 +138,7 @@ const UseView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
<hr/>
|
||||||
{
|
{
|
||||||
props.mode != 'view' &&
|
props.mode != 'view' &&
|
||||||
<div>
|
<div>
|
||||||
|
@ -12,12 +12,14 @@ import SelectDataEntry from '../data-components/select-data-entry';
|
|||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
|
|
||||||
const locationNumberPattern = "[1-9]\\d*[a-z]?(-([1-9]\\d*))?"; ///[1-9]\d*[a-z]?(-([1-9]\d*))?/;
|
const locationNumberPattern = "[1-9]\\d*[a-z]?(-([1-9]\\d*))?"; ///[1-9]\d*[a-z]?(-([1-9]\d*))?/;
|
||||||
|
const postcodeCharacterPattern = "^[A-Z]{1,2}[0-9]{1,2}[A-Z]?(\\s*[0-9][A-Z]{1,2})?$";
|
||||||
|
const osmIdentifierPattern = "[0-9]{1,9}";
|
||||||
|
|
||||||
const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||||
const osm_url = "https://www.openstreetmap.org/way/"+props.building.ref_osm_id;
|
const osm_url = "www.openstreetmap.org/way/"+props.building.ref_osm_id;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Address data">
|
<DataEntryGroup name="Addresses">
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.location_name.title}
|
title={dataFields.location_name.title}
|
||||||
slug="location_name"
|
slug="location_name"
|
||||||
@ -26,8 +28,9 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.location_name.tooltip}
|
tooltip={dataFields.location_name.tooltip}
|
||||||
placeholder="https://..."
|
placeholder=""
|
||||||
isUrl={true}
|
isUrl={false}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_name"
|
slug="location_name"
|
||||||
@ -44,6 +47,23 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
mode='view'
|
mode='view'
|
||||||
tooltip="Not yet activated.<br><br>For security reasons, we do not allow the use of free text boxes and are currently looking into alternative ways to collect this data."
|
tooltip="Not yet activated.<br><br>For security reasons, we do not allow the use of free text boxes and are currently looking into alternative ways to collect this data."
|
||||||
/>
|
/>
|
||||||
|
<DataEntry
|
||||||
|
title={dataFields.location_name_link.title}
|
||||||
|
slug="location_name_link"
|
||||||
|
value={props.building.location_name_link}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.location_name_link.tooltip}
|
||||||
|
placeholder={dataFields.location_name_link.example}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
(props.building.location_name_link == null) ? <></> :
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i className="source-url">Source: <a href={props.building.location_name_link} target={"_blank"}>{props.building.location_name_link}</a></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<hr/>
|
<hr/>
|
||||||
<PatternDataEntry
|
<PatternDataEntry
|
||||||
title={dataFields.location_number.title}
|
title={dataFields.location_number.title}
|
||||||
@ -54,6 +74,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.location_number.tooltip}
|
tooltip={dataFields.location_number.tooltip}
|
||||||
|
maxLength={5}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_number"
|
slug="location_number"
|
||||||
@ -71,6 +92,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
maxLength={30}
|
maxLength={30}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_street"
|
slug="location_street"
|
||||||
@ -88,6 +110,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
maxLength={30}
|
maxLength={30}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_line_two"
|
slug="location_line_two"
|
||||||
@ -104,6 +127,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_town"
|
slug="location_town"
|
||||||
@ -113,15 +137,17 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.location_town}
|
user_verified_as={props.user_verified.location_town}
|
||||||
verified_count={props.building.verified.location_town}
|
verified_count={props.building.verified.location_town}
|
||||||
/>
|
/>
|
||||||
<DataEntry
|
<PatternDataEntry
|
||||||
title={dataFields.location_postcode.title}
|
title={dataFields.location_postcode.title}
|
||||||
slug="location_postcode"
|
slug="location_postcode"
|
||||||
value={props.building.location_postcode}
|
value={props.building.location_postcode}
|
||||||
|
pattern={postcodeCharacterPattern}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
maxLength={8}
|
maxLength={8}
|
||||||
valueTransform={x=>x.toUpperCase()}
|
valueTransform={x=>x.toUpperCase()}
|
||||||
|
tooltip={dataFields.location_postcode.tooltip}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="location_postcode"
|
slug="location_postcode"
|
||||||
@ -161,7 +187,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Property/footprint IDs and coordinate data">
|
<DataEntryGroup name="Property/footprint IDs and coordinates">
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.ref_toid.title}
|
title={dataFields.ref_toid.title}
|
||||||
slug="ref_toid"
|
slug="ref_toid"
|
||||||
@ -172,13 +198,27 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
|
{
|
||||||
|
(props.building.ref_toid == null) ? <></> :
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i className="source-url">Source: <a href="https://www.ordnancesurvey.co.uk/products/os-open-toid" target={"_blank"}>{"www.ordnancesurvey.co.uk/products/os-open-toid"}</a></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
<UPRNsDataEntry
|
<UPRNsDataEntry
|
||||||
title={dataFields.uprns.title}
|
title={dataFields.uprns.title}
|
||||||
slug="ref_uprns"
|
slug="ref_uprns"
|
||||||
value={props.building.uprns}
|
value={props.building.uprns}
|
||||||
tooltip={dataFields.uprns.tooltip}
|
tooltip={dataFields.uprns.tooltip}
|
||||||
/>
|
/>
|
||||||
<DataEntry
|
{
|
||||||
|
(props.building.uprns == null) ? <></> :
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i className="source-url">Source: <a href="https://beta.ordnancesurvey.co.uk/products/os-open-uprn" target={"_blank"}>{"beta.ordnancesurvey.co.uk/products/os-open-uprn"}</a></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<PatternDataEntry
|
||||||
title={dataFields.ref_osm_id.title}
|
title={dataFields.ref_osm_id.title}
|
||||||
slug="ref_osm_id"
|
slug="ref_osm_id"
|
||||||
value={props.building.ref_osm_id}
|
value={props.building.ref_osm_id}
|
||||||
@ -187,13 +227,8 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
tooltip={dataFields.ref_osm_id.tooltip}
|
tooltip={dataFields.ref_osm_id.tooltip}
|
||||||
maxLength={20}
|
maxLength={20}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
|
pattern={osmIdentifierPattern}
|
||||||
/>
|
/>
|
||||||
{
|
|
||||||
(props.building.ref_osm_id == null) ? <></> :
|
|
||||||
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
|
||||||
<i className="source-url">Source: <a href={osm_url} target={"_blank"}>{osm_url}</a></i>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<Verification
|
<Verification
|
||||||
slug="ref_osm_id"
|
slug="ref_osm_id"
|
||||||
allow_verify={props.user !== undefined && props.building.ref_osm_id !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.ref_osm_id !== null && !props.edited}
|
||||||
@ -202,6 +237,12 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.ref_osm_id}
|
user_verified_as={props.user_verified.ref_osm_id}
|
||||||
verified_count={props.building.verified.ref_osm_id}
|
verified_count={props.building.verified.ref_osm_id}
|
||||||
/>
|
/>
|
||||||
|
{
|
||||||
|
(props.building.ref_osm_id == null) ? <></> :
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i className="source-url">Source: <a href={"https://"+osm_url} target={"_blank"}>{osm_url}</a></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<hr/>
|
<hr/>
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.location_latitude.title}
|
title={dataFields.location_latitude.title}
|
||||||
@ -274,6 +315,19 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
<hr/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.location_alternative_footprint_links.title}
|
||||||
|
slug="location_alternative_footprint_links"
|
||||||
|
value={props.building.location_alternative_footprint_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.location_alternative_footprint_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -19,6 +19,8 @@ import { CategoryViewProps } from './category-view-props';
|
|||||||
import { Category } from '../../config/categories-config';
|
import { Category } from '../../config/categories-config';
|
||||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||||
import { processParam } from '../../../api/parameters';
|
import { processParam } from '../../../api/parameters';
|
||||||
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
|
import YearDataEntry from '../data-components/year-data-entry';
|
||||||
|
|
||||||
const currentTimestamp = new Date().valueOf();
|
const currentTimestamp = new Date().valueOf();
|
||||||
const milisecondsInYear = 1000 * 60 * 60 * 24 * 365;
|
const milisecondsInYear = 1000 * 60 * 60 * 24 * 365;
|
||||||
@ -63,10 +65,12 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
const { flood, floodSwitchOnClick, housing, housingSwitchOnClick, creative, creativeSwitchOnClick, vista, vistaSwitchOnClick, parcel, parcelSwitchOnClick, conservation, conservationSwitchOnClick, darkLightTheme } = useDisplayPreferences();
|
const { flood, floodSwitchOnClick, housing, housingSwitchOnClick, creative, creativeSwitchOnClick, vista, vistaSwitchOnClick, parcel, parcelSwitchOnClick, conservation, conservationSwitchOnClick, darkLightTheme } = useDisplayPreferences();
|
||||||
const communityLinkUrl = `/${props.mode}/${Category.Community}/${props.building.building_id}`;
|
const communityLinkUrl = `/${props.mode}/${Category.Community}/${props.building.building_id}`;
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Planning application information" collapsed={true} >
|
<DataEntryGroup name="Current planning applications" collapsed={true} >
|
||||||
<DataEntryGroup name="Current/active applications (official data)">
|
<DataEntryGroup name="Official data">
|
||||||
<InfoBox>
|
<InfoBox>
|
||||||
This section provides data on active applications. We define these as applications with any activity in the last year.
|
This section provides data on active applications. We define these as applications with any activity in the last year.
|
||||||
<br />
|
<br />
|
||||||
@ -85,7 +89,119 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
: <></>
|
: <></>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Past applications (official data)" collapsed={true} >
|
<DataEntryGroup name="Year of completion" collapsed={true} >
|
||||||
|
<LogicalDataEntry
|
||||||
|
slug='planning_crowdsourced_site_completion_status'
|
||||||
|
title={dataFields.planning_crowdsourced_site_completion_status.title}
|
||||||
|
tooltip={dataFields.planning_crowdsourced_site_completion_status.tooltip}
|
||||||
|
value={props.building.planning_crowdsourced_site_completion_status}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
mode={props.mode}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_crowdsourced_site_completion_status"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_crowdsourced_site_completion_status !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_site_completion_status")}
|
||||||
|
user_verified_as={props.user_verified.planning_crowdsourced_site_completion_status}
|
||||||
|
verified_count={props.building.verified.planning_crowdsourced_site_completion_status}
|
||||||
|
/>
|
||||||
|
{props.building.planning_crowdsourced_site_completion_status == null ? <></> :
|
||||||
|
<>
|
||||||
|
<NumericDataEntry
|
||||||
|
title={dataFields.planning_crowdsourced_site_completion_year.title}
|
||||||
|
slug="planning_crowdsourced_site_completion_year"
|
||||||
|
value={props.building.planning_crowdsourced_site_completion_year}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
step={1}
|
||||||
|
min={1}
|
||||||
|
max={currentYear}
|
||||||
|
tooltip={dataFields.planning_crowdsourced_site_completion_year.tooltip}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_crowdsourced_site_completion_year"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_crowdsourced_site_completion_year !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_site_completion_year")}
|
||||||
|
user_verified_as={props.user_verified.planning_crowdsourced_site_completion_year}
|
||||||
|
verified_count={props.building.verified.planning_crowdsourced_site_completion_year}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.planning_crowdsourced_site_completion_source_type.title}
|
||||||
|
slug="planning_crowdsourced_site_completion_source_type"
|
||||||
|
value={props.building.planning_crowdsourced_site_completion_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.planning_crowdsourced_site_completion_source_type.tooltip}
|
||||||
|
options={dataFields.planning_crowdsourced_site_completion_source_type.items}
|
||||||
|
placeholder={dataFields.planning_crowdsourced_site_completion_source_type.example}
|
||||||
|
/>
|
||||||
|
{(props.building.planning_crowdsourced_site_completion_source_type == dataFields.planning_crowdsourced_site_completion_source_type.items[0] ||
|
||||||
|
props.building.planning_crowdsourced_site_completion_source_type == dataFields.planning_crowdsourced_site_completion_source_type.items[1] ||
|
||||||
|
props.building.planning_crowdsourced_site_completion_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.planning_crowdsourced_site_completion_source_links.title}
|
||||||
|
slug="planning_crowdsourced_site_completion_source_links"
|
||||||
|
value={props.building.planning_crowdsourced_site_completion_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.planning_crowdsourced_site_completion_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Incomplete/missing data" collapsed={true} >
|
||||||
|
<LogicalDataEntry
|
||||||
|
slug='planning_missing_data'
|
||||||
|
title={dataFields.planning_missing_data.title}
|
||||||
|
tooltip={dataFields.planning_missing_data.tooltip}
|
||||||
|
value={props.building.planning_missing_data}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
mode={props.mode}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_missing_data"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_missing_data !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_missing_data")}
|
||||||
|
user_verified_as={props.user_verified.planning_missing_data}
|
||||||
|
verified_count={props.building.verified.planning_missing_data}
|
||||||
|
/>
|
||||||
|
{props.building.planning_missing_data == null ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.planning_missing_data_links.title}
|
||||||
|
slug="planning_missing_data_links"
|
||||||
|
value={props.building.planning_missing_data_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.planning_missing_data_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<InfoBox>
|
||||||
|
If you feel there are incorrect or missing data relating to this building please contact:
|
||||||
|
planningdata@London.gov.uk
|
||||||
|
</InfoBox>
|
||||||
|
</DataEntryGroup>
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Past applications" collapsed={true} >
|
||||||
<InfoBox>
|
<InfoBox>
|
||||||
This section provides data on past applications where available from the GLA, including those with no decision in over a year
|
This section provides data on past applications where available from the GLA, including those with no decision in over a year
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
@ -102,7 +218,7 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
: <></>
|
: <></>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Possible future applications (crowdsourced data)" collapsed={true} >
|
<DataEntryGroup name="Possible future applications" collapsed={true} >
|
||||||
<InfoBox type='info'>Click and colour buildings here if you think they may be subject to a future planning application involving demolition. To add your opinion on how well this building works, please also visit the <Link to={communityLinkUrl}>Community</Link> section.</InfoBox>
|
<InfoBox type='info'>Click and colour buildings here if you think they may be subject to a future planning application involving demolition. To add your opinion on how well this building works, please also visit the <Link to={communityLinkUrl}>Community</Link> section.</InfoBox>
|
||||||
{
|
{
|
||||||
props.mapColourScale != "community_expected_planning_application_total" ?
|
props.mapColourScale != "community_expected_planning_application_total" ?
|
||||||
@ -127,7 +243,6 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
Further improvements to this feature are currently being made.
|
Further improvements to this feature are currently being made.
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</DataEntryGroup>
|
|
||||||
<DataEntryGroup name="Planning zones" collapsed={true} >
|
<DataEntryGroup name="Planning zones" collapsed={true} >
|
||||||
<InfoBox>
|
<InfoBox>
|
||||||
To view planning zone data for London click the buttons below. You may need to <u>zoom out</u>.
|
To view planning zone data for London click the buttons below. You may need to <u>zoom out</u>.
|
||||||
@ -221,48 +336,26 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
<button className={`map-switcher-inline ${conservation}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={conservationSwitchOnClick}>
|
<button className={`map-switcher-inline ${conservation}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={conservationSwitchOnClick}>
|
||||||
{(conservation === 'enabled')? 'Click to hide Conservation Areas' : 'Click to see Conservation Areas'}
|
{(conservation === 'enabled')? 'Click to hide Conservation Areas' : 'Click to see Conservation Areas'}
|
||||||
</button>
|
</button>
|
||||||
<NumericDataEntryWithFormattedLink
|
<hr/>
|
||||||
title={dataFields.planning_list_id.title}
|
<LogicalDataEntry
|
||||||
slug="planning_list_id"
|
slug='planning_heritage_at_risk'
|
||||||
value={props.building.planning_list_id}
|
title={dataFields.planning_heritage_at_risk.title}
|
||||||
mode={props.mode}
|
tooltip={dataFields.planning_heritage_at_risk.tooltip}
|
||||||
|
value={props.building.planning_heritage_at_risk}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
placeholder="add ID here"
|
|
||||||
linkTargetFunction={(id: String) => { return "https://historicengland.org.uk/listing/the-list/list-entry/" + id + "?section=official-list-entry" } }
|
|
||||||
linkDescriptionFunction={(id: String) => { return "ID Link" } }
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="planning_list_id"
|
|
||||||
allow_verify={props.user !== undefined && props.building.planning_list_id !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_list_id")}
|
|
||||||
user_verified_as={props.user_verified.planning_list_id}
|
|
||||||
verified_count={props.building.verified.planning_list_id}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.planning_list_grade.title}
|
|
||||||
slug="planning_list_grade"
|
|
||||||
value={props.building.planning_list_grade}
|
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
disabled={false}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
options={[
|
|
||||||
"I",
|
|
||||||
"II*",
|
|
||||||
"II",
|
|
||||||
"None"
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="planning_list_grade"
|
slug="planning_heritage_at_risk"
|
||||||
allow_verify={props.user !== undefined && props.building.planning_list_grade !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.planning_heritage_at_risk !== null && !props.edited}
|
||||||
onVerify={props.onVerify}
|
onVerify={props.onVerify}
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_list_grade")}
|
user_verified={props.user_verified.hasOwnProperty("planning_heritage_at_risk")}
|
||||||
user_verified_as={props.user_verified.planning_list_grade}
|
user_verified_as={props.user_verified.planning_heritage_at_risk}
|
||||||
verified_count={props.building.verified.planning_list_grade}
|
verified_count={props.building.verified.planning_heritage_at_risk}
|
||||||
/>
|
/>
|
||||||
|
{(props.building.planning_heritage_at_risk == null || props.building.planning_heritage_at_risk == false) ? <></> :
|
||||||
|
<>
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.planning_heritage_at_risk_url.title}
|
title={dataFields.planning_heritage_at_risk_url.title}
|
||||||
slug="planning_heritage_at_risk_url"
|
slug="planning_heritage_at_risk_url"
|
||||||
@ -281,6 +374,28 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.planning_heritage_at_risk_url}
|
user_verified_as={props.user_verified.planning_heritage_at_risk_url}
|
||||||
verified_count={props.building.verified.planning_heritage_at_risk_url}
|
verified_count={props.building.verified.planning_heritage_at_risk_url}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<LogicalDataEntry
|
||||||
|
slug='planning_world_heritage_site'
|
||||||
|
title={dataFields.planning_world_heritage_site.title}
|
||||||
|
tooltip={dataFields.planning_world_heritage_site.tooltip}
|
||||||
|
value={props.building.planning_world_heritage_site}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
mode={props.mode}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_world_heritage_site"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_world_heritage_site !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_world_heritage_site")}
|
||||||
|
user_verified_as={props.user_verified.planning_world_heritage_site}
|
||||||
|
verified_count={props.building.verified.planning_world_heritage_site}
|
||||||
|
/>
|
||||||
|
{(props.building.planning_world_heritage_site == null || props.building.planning_world_heritage_site == false) ? <></> :
|
||||||
|
<>
|
||||||
<NumericDataEntryWithFormattedLink
|
<NumericDataEntryWithFormattedLink
|
||||||
title={dataFields.planning_world_list_id.title}
|
title={dataFields.planning_world_list_id.title}
|
||||||
slug="planning_world_list_id"
|
slug="planning_world_list_id"
|
||||||
@ -300,6 +415,28 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.planning_world_list_id}
|
user_verified_as={props.user_verified.planning_world_list_id}
|
||||||
verified_count={props.building.verified.planning_world_list_id}
|
verified_count={props.building.verified.planning_world_list_id}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<LogicalDataEntry
|
||||||
|
slug='planning_local_list'
|
||||||
|
title={dataFields.planning_local_list.title}
|
||||||
|
tooltip={dataFields.planning_local_list.tooltip}
|
||||||
|
value={props.building.planning_local_list}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
mode={props.mode}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_local_list"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_local_list !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_local_list")}
|
||||||
|
user_verified_as={props.user_verified.planning_local_list}
|
||||||
|
verified_count={props.building.verified.planning_local_list}
|
||||||
|
/>
|
||||||
|
{(props.building.planning_local_list == null || props.building.planning_local_list == false) ? <></> :
|
||||||
|
<>
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.planning_local_list_url.title}
|
title={dataFields.planning_local_list_url.title}
|
||||||
slug="planning_local_list_url"
|
slug="planning_local_list_url"
|
||||||
@ -318,26 +455,28 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.planning_local_list_url}
|
user_verified_as={props.user_verified.planning_local_list_url}
|
||||||
verified_count={props.building.verified.planning_local_list_url}
|
verified_count={props.building.verified.planning_local_list_url}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
{/*
|
}
|
||||||
<DataEntry
|
<hr/>
|
||||||
title={dataFields.planning_in_conservation_area_id.title}
|
<LogicalDataEntry
|
||||||
slug="planning_in_conservation_area_id"
|
slug='planning_in_conservation_area'
|
||||||
value={props.building.planning_in_conservation_area_id}
|
title={dataFields.planning_in_conservation_area.title}
|
||||||
mode={props.mode}
|
tooltip={dataFields.planning_in_conservation_area.tooltip}
|
||||||
|
value={props.building.planning_in_conservation_area}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
placeholder="Please add Conservation Area identifier"
|
mode={props.mode}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="planning_in_conservation_area_id"
|
slug="planning_in_conservation_area"
|
||||||
allow_verify={props.user !== undefined && props.building.planning_in_conservation_area_id !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.planning_in_conservation_area !== null && !props.edited}
|
||||||
onVerify={props.onVerify}
|
onVerify={props.onVerify}
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_in_conservation_area_id")}
|
user_verified={props.user_verified.hasOwnProperty("planning_in_conservation_area")}
|
||||||
user_verified_as={props.user_verified.planning_in_conservation_area_id}
|
user_verified_as={props.user_verified.planning_in_conservation_area}
|
||||||
verified_count={props.building.verified.planning_in_conservation_area_id}
|
verified_count={props.building.verified.planning_in_conservation_area}
|
||||||
/>
|
/>
|
||||||
*/}
|
{(props.building.planning_in_conservation_area == null || props.building.planning_in_conservation_area == false) ? <></> :
|
||||||
|
<>
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.planning_in_conservation_area_url.title}
|
title={dataFields.planning_in_conservation_area_url.title}
|
||||||
slug="planning_in_conservation_area_url"
|
slug="planning_in_conservation_area_url"
|
||||||
@ -358,42 +497,28 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.planning_in_conservation_area_url}
|
user_verified_as={props.user_verified.planning_in_conservation_area_url}
|
||||||
verified_count={props.building.verified.planning_in_conservation_area_url}
|
verified_count={props.building.verified.planning_in_conservation_area_url}
|
||||||
/>
|
/>
|
||||||
{/*
|
</>
|
||||||
<DataEntry
|
}
|
||||||
title={dataFields.planning_conservation_area_name.title}
|
<hr/>
|
||||||
slug="planning_conservation_area_name"
|
<LogicalDataEntry
|
||||||
value={props.building.planning_conservation_area_name}
|
slug='planning_in_apa'
|
||||||
mode={props.mode}
|
title={dataFields.planning_in_apa.title}
|
||||||
|
tooltip={dataFields.planning_in_apa.tooltip}
|
||||||
|
value={props.building.planning_in_apa}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="planning_conservation_area_name"
|
|
||||||
allow_verify={props.user !== undefined && props.building.planning_conservation_area_name !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_conservation_area_name")}
|
|
||||||
user_verified_as={props.user_verified.planning_conservation_area_name}
|
|
||||||
verified_count={props.building.verified.planning_conservation_area_name}
|
|
||||||
/>
|
|
||||||
*/}
|
|
||||||
<DataEntry
|
|
||||||
title={dataFields.planning_historic_area_assessment_url.title}
|
|
||||||
slug="planning_historic_area_assessment_url"
|
|
||||||
value={props.building.planning_historic_area_assessment_url}
|
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
isUrl={true}
|
|
||||||
placeholder="Please add relevant link here"
|
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="planning_historic_area_assessment_url"
|
slug="planning_in_apa"
|
||||||
allow_verify={props.user !== undefined && props.building.planning_historic_area_assessment_url !== null && !props.edited}
|
allow_verify={props.user !== undefined && props.building.planning_in_apa !== null && !props.edited}
|
||||||
onVerify={props.onVerify}
|
onVerify={props.onVerify}
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_historic_area_assessment_url")}
|
user_verified={props.user_verified.hasOwnProperty("planning_in_apa")}
|
||||||
user_verified_as={props.user_verified.planning_historic_area_assessment_url}
|
user_verified_as={props.user_verified.planning_in_apa}
|
||||||
verified_count={props.building.verified.planning_historic_area_assessment_url}
|
verified_count={props.building.verified.planning_in_apa}
|
||||||
/>
|
/>
|
||||||
|
{(props.building.planning_in_apa == null || props.building.planning_in_apa == false) ? <></> :
|
||||||
|
<>
|
||||||
<DataEntry
|
<DataEntry
|
||||||
title={dataFields.planning_in_apa_url.title}
|
title={dataFields.planning_in_apa_url.title}
|
||||||
slug="planning_in_apa_url"
|
slug="planning_in_apa_url"
|
||||||
@ -412,107 +537,109 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.planning_in_apa_url}
|
user_verified_as={props.user_verified.planning_in_apa_url}
|
||||||
verified_count={props.building.verified.planning_in_apa_url}
|
verified_count={props.building.verified.planning_in_apa_url}
|
||||||
/>
|
/>
|
||||||
</DataEntryGroup>
|
</>
|
||||||
<DataEntryGroup name="Forthcoming data (sections to be activated)" collapsed={true} >
|
}
|
||||||
<DataEntryGroup name="Active application info (crowdsourced)" collapsed={true} >
|
<hr/>
|
||||||
{/* will be titled "Other active application info (crowdsourced data)" once active" */}
|
<LogicalDataEntry
|
||||||
<InfoBox type='warning'>
|
slug='planning_scientific_interest'
|
||||||
This category is not yet activated - Until this section is activated please report inaccuracies or problems on the <a href=" https://github.com/colouring-cities/colouring-london/discussions/categories/planning-section-comments">Discussion Forum</a>.
|
title={dataFields.planning_scientific_interest.title}
|
||||||
</InfoBox>
|
tooltip={dataFields.planning_scientific_interest.tooltip}
|
||||||
{/* that is placeholder display, will be replaced by actual code */}
|
value={props.building.planning_scientific_interest}
|
||||||
<div className="data-title">
|
copy={props.copy}
|
||||||
<div className="data-title-text">
|
onChange={props.onChange}
|
||||||
<ul>
|
mode={props.mode}
|
||||||
<li>Year of completion if known</li>
|
/>
|
||||||
<li>If you know of a planning application that has been recently submitted for this site, and is not listed in the blue box above, please enter its planning application ID below:</li>
|
<Verification
|
||||||
<li>If any of the active planning applications are not mapped onto the correct site, please tick here</li>
|
slug="planning_scientific_interest"
|
||||||
</ul>
|
allow_verify={props.user !== undefined && props.building.planning_scientific_interest !== null && !props.edited}
|
||||||
</div>
|
onVerify={props.onVerify}
|
||||||
</div>
|
user_verified={props.user_verified.hasOwnProperty("planning_scientific_interest")}
|
||||||
{
|
user_verified_as={props.user_verified.planning_scientific_interest}
|
||||||
/*
|
verified_count={props.building.verified.planning_scientific_interest}
|
||||||
<NumericDataEntry
|
/>
|
||||||
title={dataFields.planning_crowdsourced_site_completion_year.title}
|
{(props.building.planning_scientific_interest == null || props.building.planning_scientific_interest == false) ? <></> :
|
||||||
slug="planning_crowdsourced_site_completion_year"
|
<>
|
||||||
value={props.building.planning_crowdsourced_site_completion_year}
|
<SelectDataEntry
|
||||||
mode={props.mode}
|
title={dataFields.planning_scientific_interest_source_type.title}
|
||||||
copy={props.copy}
|
slug="planning_scientific_interest_source_type"
|
||||||
onChange={props.onChange}
|
value={props.building.planning_scientific_interest_source_type}
|
||||||
disabled={true}
|
mode={props.mode}
|
||||||
/>
|
copy={props.copy}
|
||||||
<Verification
|
onChange={props.onChange}
|
||||||
slug="planning_crowdsourced_site_completion_year"
|
tooltip={dataFields.planning_scientific_interest_source_type.tooltip}
|
||||||
allow_verify={false}
|
options={dataFields.planning_scientific_interest_source_type.items}
|
||||||
onVerify={props.onVerify}
|
placeholder={dataFields.planning_scientific_interest_source_type.example}
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_site_completion_year")}
|
/>
|
||||||
user_verified_as={props.user_verified.planning_crowdsourced_site_completion_year}
|
{(props.building.planning_scientific_interest_source_type == dataFields.planning_scientific_interest_source_type.items[0] ||
|
||||||
verified_count={props.building.verified.planning_crowdsourced_site_completion_year}
|
props.building.planning_scientific_interest_source_type == dataFields.planning_scientific_interest_source_type.items[1] ||
|
||||||
/>
|
props.building.planning_scientific_interest_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
<DataEntry
|
<MultiDataEntry
|
||||||
title={dataFields.planning_crowdsourced_planning_id.title}
|
title={dataFields.planning_scientific_interest_source_links.title}
|
||||||
slug="planning_crowdsourced_planning_id"
|
slug="planning_scientific_interest_source_links"
|
||||||
value={props.building.planning_crowdsourced_planning_id}
|
value={props.building.planning_scientific_interest_source_links}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
disabled={true}
|
tooltip={dataFields.planning_scientific_interest_source_links.tooltip}
|
||||||
/>
|
placeholder="https://..."
|
||||||
<Verification
|
editableEntries={true}
|
||||||
slug="planning_crowdsourced_planning_id"
|
isUrl={true}
|
||||||
allow_verify={false && props.user !== undefined && props.building.planning_crowdsourced_planning_id !== null && !props.edited}
|
/>
|
||||||
onVerify={props.onVerify}
|
</>
|
||||||
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_planning_id")}
|
}
|
||||||
user_verified_as={props.user_verified.planning_crowdsourced_planning_id}
|
</>
|
||||||
verified_count={props.building.verified.planning_crowdsourced_planning_id}
|
}
|
||||||
/>
|
<hr/>
|
||||||
|
<LogicalDataEntry
|
||||||
<LogicalDataEntry
|
slug='planning_historic_area_assessment'
|
||||||
slug='community_expected_planning_application_is_inaccurate'
|
title={dataFields.planning_historic_area_assessment.title}
|
||||||
title={"If any of the active planning applications are not mapped onto the correct site, please tick here"}
|
tooltip={dataFields.planning_historic_area_assessment.tooltip}
|
||||||
value={null}
|
value={props.building.planning_historic_area_assessment}
|
||||||
|
copy={props.copy}
|
||||||
onChange={props.onSaveChange}
|
onChange={props.onChange}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
/>
|
||||||
disabled={true}
|
<Verification
|
||||||
/>
|
slug="planning_historic_area_assessment"
|
||||||
on enabling switch it to UserOpinionEntry, remove value and restore userValue
|
allow_verify={props.user !== undefined && props.building.planning_historic_area_assessment !== null && !props.edited}
|
||||||
*/
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_historic_area_assessment")}
|
||||||
|
user_verified_as={props.user_verified.planning_historic_area_assessment}
|
||||||
|
verified_count={props.building.verified.planning_historic_area_assessment}
|
||||||
|
/>
|
||||||
|
{(props.building.planning_historic_area_assessment == null || props.building.planning_historic_area_assessment == false) ? <></> :
|
||||||
|
<>
|
||||||
|
<DataEntry
|
||||||
|
title={dataFields.planning_historic_area_assessment_url.title}
|
||||||
|
slug="planning_historic_area_assessment_url"
|
||||||
|
value={props.building.planning_historic_area_assessment_url}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
isUrl={true}
|
||||||
|
placeholder="Please add relevant link here"
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="planning_historic_area_assessment_url"
|
||||||
|
allow_verify={props.user !== undefined && props.building.planning_historic_area_assessment_url !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("planning_historic_area_assessment_url")}
|
||||||
|
user_verified_as={props.user_verified.planning_historic_area_assessment_url}
|
||||||
|
verified_count={props.building.verified.planning_historic_area_assessment_url}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Land ownership type" collapsed={true} >
|
<DataEntryGroup name="Land ownership" collapsed={true} >
|
||||||
<InfoBox type='warning'>
|
|
||||||
This category is not yet activated.
|
|
||||||
</InfoBox>
|
|
||||||
<InfoBox>
|
<InfoBox>
|
||||||
This section is designed to provide information on land parcels and their ownership type. Can you help us to crowdsource this information?
|
This section is designed to provide information on land parcels and their ownership type. Can you help us collect this information?
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
<button className={`map-switcher-inline ${parcel}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={parcelSwitchOnClick}>
|
|
||||||
{(parcel === 'enabled')? 'Click to hide sample of parcel data (in City)' : 'Click to see sample of parcel data (in City) mapped'}
|
|
||||||
</button>
|
|
||||||
<div className="data-title">
|
|
||||||
<div className="data-title-text">
|
|
||||||
<ul>
|
|
||||||
<li>What type of owner owns this land parcel?</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/*
|
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
slug='community_public_ownership'
|
slug='community_public_ownership'
|
||||||
title={"What type of owner owns this land parcel? "}
|
title={dataFields.community_public_ownership.title}
|
||||||
value={props.building.community_public_ownership}
|
value={props.building.community_public_ownership}
|
||||||
options={[
|
options={dataFields.community_public_ownership.items}
|
||||||
'Government-owned',
|
|
||||||
'Charity-owned',
|
|
||||||
'Community-owned/cooperative',
|
|
||||||
'Owned by other non-profit body',
|
|
||||||
'Not in public/community ownership',
|
|
||||||
]}
|
|
||||||
|
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
@ -525,9 +652,39 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.community_public_ownership}
|
user_verified_as={props.user_verified.community_public_ownership}
|
||||||
verified_count={props.building.verified.community_public_ownership}
|
verified_count={props.building.verified.community_public_ownership}
|
||||||
/>
|
/>
|
||||||
*/
|
<DataEntry
|
||||||
}
|
title="Source Type"
|
||||||
</DataEntryGroup>
|
slug=""
|
||||||
|
value=""
|
||||||
|
mode='view'
|
||||||
|
tooltip='Coming Soon'
|
||||||
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
slug='community_public_ownership_sources'
|
||||||
|
title={dataFields.community_public_ownership_sources.title}
|
||||||
|
isUrl={true}
|
||||||
|
placeholder={'https://...'}
|
||||||
|
editableEntries={true}
|
||||||
|
value={props.building.community_public_ownership_sources}
|
||||||
|
onChange={props.onChange}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
/>
|
||||||
|
<hr/>
|
||||||
|
<DataEntry
|
||||||
|
title={dataFields.size_parcel_geometry.title}
|
||||||
|
slug="size_parcel_geometry"
|
||||||
|
value={props.building.size_parcel_geometry}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.size_parcel_geometry.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
<button className={`map-switcher-inline ${parcel}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={parcelSwitchOnClick}>
|
||||||
|
{(parcel === 'enabled')? 'Click to hide sample land parcel data' : 'Click to show sample land parcel data'}
|
||||||
|
</button>
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)};
|
)};
|
||||||
|
@ -15,7 +15,22 @@ import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-e
|
|||||||
/**
|
/**
|
||||||
* Size view/edit section
|
* Size view/edit section
|
||||||
*/
|
*/
|
||||||
const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||||
|
|
||||||
|
// Calculate the total number of floors
|
||||||
|
let total_floors = 0;
|
||||||
|
|
||||||
|
if (props.building.size_storeys_attic != null) {
|
||||||
|
total_floors += props.building.size_storeys_attic;
|
||||||
|
}
|
||||||
|
if (props.building.size_storeys_core != null) {
|
||||||
|
total_floors += props.building.size_storeys_core;
|
||||||
|
}
|
||||||
|
if (props.building.size_storeys_basement != null) {
|
||||||
|
total_floors += props.building.size_storeys_basement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Number of floors/storeys">
|
<DataEntryGroup name="Number of floors/storeys">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
@ -75,6 +90,18 @@ const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
user_verified_as={props.user_verified.size_storeys_basement}
|
user_verified_as={props.user_verified.size_storeys_basement}
|
||||||
verified_count={props.building.verified.size_storeys_basement}
|
verified_count={props.building.verified.size_storeys_basement}
|
||||||
/>
|
/>
|
||||||
|
<NumericDataEntry
|
||||||
|
title="Total number of floors"
|
||||||
|
slug="size_total_floors"
|
||||||
|
value={total_floors}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
tooltip="Total number of floors, calculated from other values."
|
||||||
|
onChange={props.onChange}
|
||||||
|
step={1}
|
||||||
|
min={0}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.size_storeys_source_type.title}
|
title={dataFields.size_storeys_source_type.title}
|
||||||
slug="size_storeys_source_type"
|
slug="size_storeys_source_type"
|
||||||
@ -103,7 +130,7 @@ const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Building height data">
|
<DataEntryGroup name="Height">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.size_height_apex.title}
|
title={dataFields.size_height_apex.title}
|
||||||
slug="size_height_apex"
|
slug="size_height_apex"
|
||||||
@ -196,7 +223,7 @@ const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Floor area data">
|
<DataEntryGroup name="Floor area">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.size_floor_area_ground.title}
|
title={dataFields.size_floor_area_ground.title}
|
||||||
slug="size_floor_area_ground"
|
slug="size_floor_area_ground"
|
||||||
@ -261,7 +288,7 @@ const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Plot size data">
|
<DataEntryGroup name="Plot size">
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.size_width_frontage.title}
|
title={dataFields.size_width_frontage.title}
|
||||||
slug="size_width_frontage"
|
slug="size_width_frontage"
|
||||||
@ -449,7 +476,8 @@ const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
)
|
||||||
|
};
|
||||||
const SizeContainer = withCopyEdit(SizeView);
|
const SizeContainer = withCopyEdit(SizeView);
|
||||||
|
|
||||||
export default SizeContainer;
|
export default SizeContainer;
|
||||||
|
@ -1,28 +1,25 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import InfoBox from '../../components/info-box';
|
|
||||||
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
||||||
import DataEntry from '../data-components/data-entry';
|
import DataEntry from '../data-components/data-entry';
|
||||||
import NumericDataEntry from '../data-components/numeric-data-entry';
|
import NumericDataEntry from '../data-components/numeric-data-entry';
|
||||||
|
|
||||||
import withCopyEdit from '../data-container';
|
import withCopyEdit from '../data-container';
|
||||||
|
|
||||||
import { CategoryViewProps } from './category-view-props';
|
import { CategoryViewProps } from './category-view-props';
|
||||||
import { DataEntryGroup } from '../data-components/data-entry-group';
|
import { DataEntryGroup } from '../data-components/data-entry-group';
|
||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
import SelectDataEntry from '../data-components/select-data-entry';
|
import SelectDataEntry from '../data-components/select-data-entry';
|
||||||
import Verification from '../data-components/verification';
|
import Verification from '../data-components/verification';
|
||||||
|
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Streetscape view/edit section
|
* Street Context view/edit section
|
||||||
*/
|
*/
|
||||||
const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
const StreetContextView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Does the building have a garden?">
|
<DataEntryGroup name="Green Space">
|
||||||
<SelectDataEntry
|
<LogicalDataEntry
|
||||||
title={dataFields.context_front_garden.title}
|
title={dataFields.context_front_garden.title}
|
||||||
slug="context_front_garden"
|
slug="context_front_garden"
|
||||||
value={props.building.context_front_garden}
|
value={props.building.context_front_garden}
|
||||||
options={dataFields.context_front_garden.items}
|
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
@ -36,7 +33,7 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
user_verified_as={props.user_verified.context_front_garden}
|
user_verified_as={props.user_verified.context_front_garden}
|
||||||
verified_count={props.building.verified.context_front_garden}
|
verified_count={props.building.verified.context_front_garden}
|
||||||
/>
|
/>
|
||||||
<SelectDataEntry
|
<LogicalDataEntry
|
||||||
title={dataFields.context_back_garden.title}
|
title={dataFields.context_back_garden.title}
|
||||||
slug="context_back_garden"
|
slug="context_back_garden"
|
||||||
value={props.building.context_back_garden}
|
value={props.building.context_back_garden}
|
||||||
@ -44,8 +41,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.context_back_garden.tooltip}
|
tooltip={dataFields.context_back_garden.tooltip}
|
||||||
//placeholder={dataFields.context_back_garden.example}
|
|
||||||
options={dataFields.context_back_garden.items}
|
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="context_back_garden"
|
slug="context_back_garden"
|
||||||
@ -55,7 +50,7 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
user_verified_as={props.user_verified.context_back_garden}
|
user_verified_as={props.user_verified.context_back_garden}
|
||||||
verified_count={props.building.verified.context_back_garden}
|
verified_count={props.building.verified.context_back_garden}
|
||||||
/>
|
/>
|
||||||
<SelectDataEntry
|
<LogicalDataEntry
|
||||||
title={dataFields.context_flats_garden.title}
|
title={dataFields.context_flats_garden.title}
|
||||||
slug="context_flats_garden"
|
slug="context_flats_garden"
|
||||||
value={props.building.context_flats_garden}
|
value={props.building.context_flats_garden}
|
||||||
@ -63,8 +58,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.context_flats_garden.tooltip}
|
tooltip={dataFields.context_flats_garden.tooltip}
|
||||||
//placeholder={dataFields.context_flats_garden.example}
|
|
||||||
options={dataFields.context_flats_garden.items}
|
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="context_flats_garden"
|
slug="context_flats_garden"
|
||||||
@ -74,7 +67,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
user_verified_as={props.user_verified.context_flats_garden}
|
user_verified_as={props.user_verified.context_flats_garden}
|
||||||
verified_count={props.building.verified.context_flats_garden}
|
verified_count={props.building.verified.context_flats_garden}
|
||||||
/>
|
/>
|
||||||
<hr/>
|
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.context_garden_source_type.title}
|
title={dataFields.context_garden_source_type.title}
|
||||||
slug="context_garden_source_type"
|
slug="context_garden_source_type"
|
||||||
@ -104,8 +96,110 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
<hr/>
|
||||||
|
<NumericDataEntry
|
||||||
|
title={dataFields.context_green_space_distance.title}
|
||||||
|
value={props.building.context_green_space_distance}
|
||||||
|
slug="context_green_space_distance"
|
||||||
|
tooltip={dataFields.context_green_space_distance.tooltip}
|
||||||
|
//placeholder={dataFields.context_green_space_distance.example}
|
||||||
|
mode={props.mode}
|
||||||
|
onChange={props.onChange}
|
||||||
|
step={1}
|
||||||
|
min={0}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="context_green_space_distance"
|
||||||
|
allow_verify={props.user !== undefined && props.building.context_green_space_distance !== null}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("context_green_space_distance")}
|
||||||
|
user_verified_as={props.user_verified.context_green_space_distance}
|
||||||
|
verified_count={props.building.verified.context_green_space_distance}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.context_green_space_distance_source_type.title}
|
||||||
|
slug="context_green_space_distance_source_type"
|
||||||
|
value={props.building.context_green_space_distance_source_type}
|
||||||
|
options={dataFields.context_green_space_distance_source_type.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.context_green_space_distance_source_type.tooltip}
|
||||||
|
/>
|
||||||
|
{(props.building.context_green_space_distance_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.context_green_space_distance_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.context_green_space_distance_source_type == null) ? <></> :
|
||||||
|
<><MultiDataEntry
|
||||||
|
title={dataFields.context_green_space_distance_source_links.title}
|
||||||
|
slug="context_green_space_distance_source_links"
|
||||||
|
value={props.building.context_green_space_distance_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.context_green_space_distance_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
<NumericDataEntry
|
||||||
|
title={dataFields.context_tree_distance.title}
|
||||||
|
value={props.building.context_tree_distance}
|
||||||
|
slug="context_tree_distance"
|
||||||
|
tooltip={dataFields.context_tree_distance.tooltip}
|
||||||
|
//placeholder={dataFields.context_tree_distance.example}
|
||||||
|
mode={props.mode}
|
||||||
|
onChange={props.onChange}
|
||||||
|
step={1}
|
||||||
|
min={0}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="context_tree_distance"
|
||||||
|
allow_verify={props.user !== undefined && props.building.context_tree_distance !== null}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("context_tree_distance")}
|
||||||
|
user_verified_as={props.user_verified.context_tree_distance}
|
||||||
|
verified_count={props.building.verified.context_tree_distance}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.context_tree_distance_source_type.title}
|
||||||
|
slug="context_tree_distance_source_type"
|
||||||
|
value={props.building.context_tree_distance_source_type}
|
||||||
|
options={dataFields.context_tree_distance_source_type.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.context_tree_distance_source_type.tooltip}
|
||||||
|
/>
|
||||||
|
{(props.building.context_tree_distance_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.context_tree_distance_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.context_tree_distance_source_type == null) ? <></> :
|
||||||
|
<><MultiDataEntry
|
||||||
|
title={dataFields.context_tree_distance_source_links.title}
|
||||||
|
slug="context_tree_distance_source_links"
|
||||||
|
value={props.building.context_tree_distance_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.context_tree_distance_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Street/pavement properties">
|
<DataEntryGroup name="Street/pavement">
|
||||||
|
<DataEntry
|
||||||
|
title="Walkability Index"
|
||||||
|
slug=""
|
||||||
|
value=""
|
||||||
|
mode='view'
|
||||||
|
tooltip='Under development'
|
||||||
|
/>
|
||||||
|
<hr/>
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
title={dataFields.context_street_width.title}
|
title={dataFields.context_street_width.title}
|
||||||
value={props.building.context_street_width}
|
value={props.building.context_street_width}
|
||||||
@ -247,103 +341,17 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Access to green space">
|
<DataEntryGroup name="Number of entrances facing street">
|
||||||
<NumericDataEntry
|
<DataEntry
|
||||||
title={dataFields.context_green_space_distance.title}
|
title="Number of entrances facing street"
|
||||||
value={props.building.context_green_space_distance}
|
slug=""
|
||||||
slug="context_green_space_distance"
|
value=""
|
||||||
tooltip={dataFields.context_green_space_distance.tooltip}
|
mode='view'
|
||||||
//placeholder={dataFields.context_green_space_distance.example}
|
tooltip='Under development'
|
||||||
mode={props.mode}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={0}
|
|
||||||
/>
|
/>
|
||||||
<Verification
|
|
||||||
slug="context_green_space_distance"
|
|
||||||
allow_verify={props.user !== undefined && props.building.context_green_space_distance !== null}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("context_green_space_distance")}
|
|
||||||
user_verified_as={props.user_verified.context_green_space_distance}
|
|
||||||
verified_count={props.building.verified.context_green_space_distance}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.context_green_space_distance_source_type.title}
|
|
||||||
slug="context_green_space_distance_source_type"
|
|
||||||
value={props.building.context_green_space_distance_source_type}
|
|
||||||
options={dataFields.context_green_space_distance_source_type.items}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.context_green_space_distance_source_type.tooltip}
|
|
||||||
/>
|
|
||||||
{(props.building.context_green_space_distance_source_type == commonSourceTypes[0] ||
|
|
||||||
props.building.context_green_space_distance_source_type == commonSourceTypes[1] ||
|
|
||||||
props.building.context_green_space_distance_source_type == null) ? <></> :
|
|
||||||
<><MultiDataEntry
|
|
||||||
title={dataFields.context_green_space_distance_source_links.title}
|
|
||||||
slug="context_green_space_distance_source_links"
|
|
||||||
value={props.building.context_green_space_distance_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.context_green_space_distance_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<hr/>
|
|
||||||
<NumericDataEntry
|
|
||||||
title={dataFields.context_tree_distance.title}
|
|
||||||
value={props.building.context_tree_distance}
|
|
||||||
slug="context_tree_distance"
|
|
||||||
tooltip={dataFields.context_tree_distance.tooltip}
|
|
||||||
//placeholder={dataFields.context_tree_distance.example}
|
|
||||||
mode={props.mode}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={0}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="context_tree_distance"
|
|
||||||
allow_verify={props.user !== undefined && props.building.context_tree_distance !== null}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("context_tree_distance")}
|
|
||||||
user_verified_as={props.user_verified.context_tree_distance}
|
|
||||||
verified_count={props.building.verified.context_tree_distance}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.context_tree_distance_source_type.title}
|
|
||||||
slug="context_tree_distance_source_type"
|
|
||||||
value={props.building.context_tree_distance_source_type}
|
|
||||||
options={dataFields.context_tree_distance_source_type.items}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.context_tree_distance_source_type.tooltip}
|
|
||||||
/>
|
|
||||||
{(props.building.context_tree_distance_source_type == commonSourceTypes[0] ||
|
|
||||||
props.building.context_tree_distance_source_type == commonSourceTypes[1] ||
|
|
||||||
props.building.context_tree_distance_source_type == null) ? <></> :
|
|
||||||
<><MultiDataEntry
|
|
||||||
title={dataFields.context_tree_distance_source_links.title}
|
|
||||||
slug="context_tree_distance_source_links"
|
|
||||||
value={props.building.context_tree_distance_source_links}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.context_tree_distance_source_links.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
const StreetscapeContainer = withCopyEdit(StreetscapeView);
|
const StreetContextContainer = withCopyEdit(StreetContextView);
|
||||||
|
|
||||||
export default StreetscapeContainer;
|
export default StreetContextContainer;
|
||||||
|
@ -4,9 +4,9 @@ import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
|||||||
import SelectDataEntry from '../data-components/select-data-entry';
|
import SelectDataEntry from '../data-components/select-data-entry';
|
||||||
import NumericDataEntry from '../data-components/numeric-data-entry';
|
import NumericDataEntry from '../data-components/numeric-data-entry';
|
||||||
import Verification from '../data-components/verification';
|
import Verification from '../data-components/verification';
|
||||||
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
|
||||||
import { LogicalDataEntry, LogicalDataEntryYesOnly } from '../data-components/logical-data-entry/logical-data-entry';
|
import { LogicalDataEntry, LogicalDataEntryYesOnly } from '../data-components/logical-data-entry/logical-data-entry';
|
||||||
import { DataEntryGroup } from '../data-components/data-entry-group';
|
import { DataEntryGroup } from '../data-components/data-entry-group';
|
||||||
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
|
|
||||||
import withCopyEdit from '../data-container';
|
import withCopyEdit from '../data-container';
|
||||||
|
|
||||||
@ -21,57 +21,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
const currentBuildingConstructionYear = building.date_year || undefined;
|
const currentBuildingConstructionYear = building.date_year || undefined;
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
<DataEntryGroup name="Data relating to original building or extension?">
|
<DataEntryGroup name="General info">
|
||||||
<NumericDataEntry
|
|
||||||
slug='date_year'
|
|
||||||
title={dataFields.date_year.title}
|
|
||||||
value={currentBuildingConstructionYear}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
step={1}
|
|
||||||
min={1}
|
|
||||||
max={currentYear}
|
|
||||||
tooltip={dataFields.extension_year.tooltip}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="date_year"
|
|
||||||
allow_verify={props.user !== undefined && props.building.date_year !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("date_year")}
|
|
||||||
user_verified_as={props.user_verified.date_year}
|
|
||||||
verified_count={props.building.verified.date_year}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.date_source.title}
|
|
||||||
slug="date_source"
|
|
||||||
value={props.building.date_source}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.date_source.tooltip}
|
|
||||||
options={dataFields.date_source.items}
|
|
||||||
placeholder={dataFields.date_source.example}
|
|
||||||
/>
|
|
||||||
{(props.building.date_source == dataFields.date_source.items[0] ||
|
|
||||||
props.building.date_source == dataFields.date_source.items[1] ||
|
|
||||||
props.building.date_source == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.date_link.title}
|
|
||||||
slug="date_link"
|
|
||||||
value={props.building.date_link}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.date_link.tooltip}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<hr/>
|
|
||||||
<LogicalDataEntry
|
<LogicalDataEntry
|
||||||
title={dataFields.has_extension.title}
|
title={dataFields.has_extension.title}
|
||||||
slug="has_extension"
|
slug="has_extension"
|
||||||
@ -81,7 +31,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
tooltip={dataFields.has_extension.tooltip}
|
tooltip={dataFields.has_extension.tooltip}
|
||||||
/>
|
/>
|
||||||
{props.building.has_extension ? (
|
{props.building.has_extension!=null && !props.building.has_extension ? (
|
||||||
<>
|
<>
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
slug='extension_year'
|
slug='extension_year'
|
||||||
@ -135,7 +85,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
) : (null)}
|
) : (null)}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Land ownership data">
|
<DataEntryGroup name="Land ownership">
|
||||||
<MultiDataEntry
|
<MultiDataEntry
|
||||||
title={dataFields.landowner.title}
|
title={dataFields.landowner.title}
|
||||||
slug="landowner"
|
slug="landowner"
|
||||||
@ -146,6 +96,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
tooltip={dataFields.landowner.tooltip}
|
tooltip={dataFields.landowner.tooltip}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
editableEntries={true}
|
editableEntries={true}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="landowner"
|
slug="landowner"
|
||||||
@ -155,6 +106,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.landowner}
|
user_verified_as={props.user_verified.landowner}
|
||||||
verified_count={props.building.verified.landowner}
|
verified_count={props.building.verified.landowner}
|
||||||
/>
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.landowner_links.title}
|
||||||
|
slug="landowner_links"
|
||||||
|
value={props.building.landowner_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.landowner_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.landowner_source_type.title}
|
title={dataFields.landowner_source_type.title}
|
||||||
slug="landowner_source_type"
|
slug="landowner_source_type"
|
||||||
@ -185,7 +148,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Developer data">
|
<DataEntryGroup name="Developer">
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
slug='developer_type'
|
slug='developer_type'
|
||||||
title={dataFields.developer_type.title}
|
title={dataFields.developer_type.title}
|
||||||
@ -213,6 +176,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
tooltip={dataFields.developer_name.tooltip}
|
tooltip={dataFields.developer_name.tooltip}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
editableEntries={true}
|
editableEntries={true}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="developer_name"
|
slug="developer_name"
|
||||||
@ -222,6 +186,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.developer_name}
|
user_verified_as={props.user_verified.developer_name}
|
||||||
verified_count={props.building.verified.developer_name}
|
verified_count={props.building.verified.developer_name}
|
||||||
/>
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.developer_links.title}
|
||||||
|
slug="developer_links"
|
||||||
|
value={props.building.developer_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.developer_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.developer_source_type.title}
|
title={dataFields.developer_source_type.title}
|
||||||
slug="developer_source_type"
|
slug="developer_source_type"
|
||||||
@ -252,7 +228,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Designer data">
|
<DataEntryGroup name="Designer">
|
||||||
<MultiDataEntry
|
<MultiDataEntry
|
||||||
title={dataFields.designers.title}
|
title={dataFields.designers.title}
|
||||||
slug="designers"
|
slug="designers"
|
||||||
@ -263,6 +239,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
tooltip={dataFields.designers.tooltip}
|
tooltip={dataFields.designers.tooltip}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
editableEntries={true}
|
editableEntries={true}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
<Verification
|
<Verification
|
||||||
slug="designers"
|
slug="designers"
|
||||||
@ -272,7 +249,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.designers}
|
user_verified_as={props.user_verified.designers}
|
||||||
verified_count={props.building.verified.designers}
|
verified_count={props.building.verified.designers}
|
||||||
/>
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.designers_links.title}
|
||||||
|
slug="designers_links"
|
||||||
|
value={props.building.designers_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.designers_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
slug='lead_designer_type'
|
slug='lead_designer_type'
|
||||||
title={dataFields.lead_designer_type.title}
|
title={dataFields.lead_designer_type.title}
|
||||||
@ -319,7 +307,70 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
<hr/>
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Builder">
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.builder.title}
|
||||||
|
slug="builder"
|
||||||
|
value={props.building.builder}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.builder.tooltip}
|
||||||
|
placeholder=""
|
||||||
|
editableEntries={true}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="builder"
|
||||||
|
allow_verify={props.user !== undefined && props.building.builder !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("builder")}
|
||||||
|
user_verified_as={props.user_verified.builder}
|
||||||
|
verified_count={props.building.verified.builder}
|
||||||
|
/>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.builder_links.title}
|
||||||
|
slug="builder_links"
|
||||||
|
value={props.building.builder_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.builder_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.builder_source_type.title}
|
||||||
|
slug="builder_source_type"
|
||||||
|
value={props.building.builder_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.builder_source_type.tooltip}
|
||||||
|
options={dataFields.builder_source_type.items}
|
||||||
|
placeholder={dataFields.builder_source_type.example}
|
||||||
|
/>
|
||||||
|
{(props.building.builder_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.builder_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.builder_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.builder_source_link.title}
|
||||||
|
slug="builder_source_link"
|
||||||
|
value={props.building.builder_source_link}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Awards">
|
||||||
<LogicalDataEntryYesOnly
|
<LogicalDataEntryYesOnly
|
||||||
slug='designer_awards'
|
slug='designer_awards'
|
||||||
title={dataFields.designer_awards.title}
|
title={dataFields.designer_awards.title}
|
||||||
@ -363,54 +414,6 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
) : (null)
|
) : (null)
|
||||||
}
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Builder data">
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.builder.title}
|
|
||||||
slug="builder"
|
|
||||||
value={props.building.builder}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
placeholder=""
|
|
||||||
editableEntries={true}
|
|
||||||
/>
|
|
||||||
<Verification
|
|
||||||
slug="builder"
|
|
||||||
allow_verify={props.user !== undefined && props.building.builder !== null && !props.edited}
|
|
||||||
onVerify={props.onVerify}
|
|
||||||
user_verified={props.user_verified.hasOwnProperty("builder")}
|
|
||||||
user_verified_as={props.user_verified.builder}
|
|
||||||
verified_count={props.building.verified.builder}
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
|
||||||
title={dataFields.builder_source_type.title}
|
|
||||||
slug="builder_source_type"
|
|
||||||
value={props.building.builder_source_type}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
tooltip={dataFields.builder_source_type.tooltip}
|
|
||||||
options={dataFields.builder_source_type.items}
|
|
||||||
placeholder={dataFields.builder_source_type.example}
|
|
||||||
/>
|
|
||||||
{(props.building.builder_source_type == commonSourceTypes[0] ||
|
|
||||||
props.building.builder_source_type == commonSourceTypes[1] ||
|
|
||||||
props.building.builder_source_type == null) ? <></> :
|
|
||||||
<>
|
|
||||||
<MultiDataEntry
|
|
||||||
title={dataFields.builder_source_link.title}
|
|
||||||
slug="builder_source_link"
|
|
||||||
value={props.building.builder_source_link}
|
|
||||||
mode={props.mode}
|
|
||||||
copy={props.copy}
|
|
||||||
onChange={props.onChange}
|
|
||||||
placeholder="https://..."
|
|
||||||
editableEntries={true}
|
|
||||||
isUrl={true}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</DataEntryGroup>
|
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
import { dataFields } from '../../config/data-fields-config';
|
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
|
||||||
import DataEntry from '../data-components/data-entry';
|
import DataEntry from '../data-components/data-entry';
|
||||||
import NumericDataEntry from '../data-components/numeric-data-entry';
|
import NumericDataEntry from '../data-components/numeric-data-entry';
|
||||||
import SelectDataEntry from '../data-components/select-data-entry';
|
import SelectDataEntry from '../data-components/select-data-entry';
|
||||||
@ -10,27 +10,316 @@ import withCopyEdit from '../data-container';
|
|||||||
import { CategoryViewProps } from './category-view-props';
|
import { CategoryViewProps } from './category-view-props';
|
||||||
import InfoBox from '../../components/info-box';
|
import InfoBox from '../../components/info-box';
|
||||||
import { DataEntryGroup } from '../data-components/data-entry-group';
|
import { DataEntryGroup } from '../data-components/data-entry-group';
|
||||||
|
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
|
||||||
const AttachmentFormOptions = [
|
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||||
"Detached",
|
|
||||||
"Semi-Detached",
|
|
||||||
"End-Terrace",
|
|
||||||
"Mid-Terrace"
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type view/edit section
|
* Type view/edit section
|
||||||
*/
|
*/
|
||||||
const TypeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
const TypeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
||||||
|
const { darkLightTheme } = useDisplayPreferences();
|
||||||
|
|
||||||
|
const switchToClassificationMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('typology_classification')
|
||||||
|
}
|
||||||
|
const switchToStylePeriodMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('typology_style_period')
|
||||||
|
}
|
||||||
|
const switchToDynamicClassificationMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('typology_dynamic_classification')
|
||||||
|
}
|
||||||
|
const switchToAttachmentMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('building_attachment_form')
|
||||||
|
}
|
||||||
|
const switchToLandUseMapStyle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
props.onMapColourScale('original_landuse')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DataEntryGroup name="Adjacency and building use data">
|
<DataEntryGroup name="Basic typology classification">
|
||||||
|
{(props.mapColourScale == "typology_classification") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToStylePeriodMapStyle}>
|
||||||
|
{'Click here to change map to show architectural style/historical period.'}
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToClassificationMapStyle}>
|
||||||
|
{"Click to change map to show typology classification."}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_classification.title}
|
||||||
|
slug="typology_classification"
|
||||||
|
value={props.building.typology_classification}
|
||||||
|
tooltip={dataFields.typology_classification.tooltip}
|
||||||
|
options={dataFields.typology_classification.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="typology_classification"
|
||||||
|
allow_verify={props.user !== undefined && props.building.typology_classification !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("typology_classification")}
|
||||||
|
user_verified_as={props.user_verified.typology_classification}
|
||||||
|
verified_count={props.building.verified.typology_classification}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_classification_source_type.title}
|
||||||
|
slug="typology_classification_source_type"
|
||||||
|
value={props.building.typology_classification_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_classification_source_type.tooltip}
|
||||||
|
placeholder={dataFields.typology_classification_source_type.example}
|
||||||
|
options={dataFields.typology_classification_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.typology_classification_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.typology_classification_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.typology_classification_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_classification_source_links.title}
|
||||||
|
slug="typology_classification_source_links"
|
||||||
|
value={props.building.typology_classification_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_classification_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Architectural style">
|
||||||
|
{/*(props.mapColourScale == "typology_style_period") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToClassificationMapStyle}>
|
||||||
|
{'Click to change map to show typology classification.'}
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToStylePeriodMapStyle}>
|
||||||
|
{"Click here to change map to show architectural style/historical period."}
|
||||||
|
</button>
|
||||||
|
*/}
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_style_period.title}
|
||||||
|
slug="typology_style_period"
|
||||||
|
value={props.building.typology_style_period}
|
||||||
|
tooltip={dataFields.typology_style_period.tooltip}
|
||||||
|
options={dataFields.typology_style_period.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
{/*
|
||||||
|
<Verification
|
||||||
|
slug="typology_style_period"
|
||||||
|
allow_verify={props.user !== undefined && props.building.typology_style_period !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("typology_style_period")}
|
||||||
|
user_verified_as={props.user_verified.typology_style_period}
|
||||||
|
verified_count={props.building.verified.typology_style_period}
|
||||||
|
/> */}
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i className="source-url">To edit the architectural style box, and to see the data mapped, please go to <a href={"/"+props.mode+"/age/"+props.building.building_id}>Age & History</a>.</i>
|
||||||
|
</div>
|
||||||
|
{/* <SelectDataEntry
|
||||||
|
title={dataFields.typology_style_period_source_type.title}
|
||||||
|
slug="typology_style_period_source_type"
|
||||||
|
value={props.building.typology_style_period_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_style_period_source_type.tooltip}
|
||||||
|
placeholder={dataFields.typology_style_period_source_type.example}
|
||||||
|
options={dataFields.typology_style_period_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.typology_style_period_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.typology_style_period_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.typology_style_period_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_style_period_source_links.title}
|
||||||
|
slug="typology_style_period_source_links"
|
||||||
|
value={props.building.typology_style_period_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_style_period_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
} */}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Dynamic tissue classification">
|
||||||
|
{(props.mapColourScale == "typology_dynamic_classification") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToClassificationMapStyle}>
|
||||||
|
{'Click to change map to show typology classification.'}
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToDynamicClassificationMapStyle}>
|
||||||
|
{"Click here to change map to show dynamic classification."}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_dynamic_classification.title}
|
||||||
|
slug="typology_dynamic_classification"
|
||||||
|
value={props.building.typology_dynamic_classification}
|
||||||
|
tooltip={dataFields.typology_dynamic_classification.tooltip}
|
||||||
|
options={dataFields.typology_dynamic_classification.items}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="typology_dynamic_classification"
|
||||||
|
allow_verify={props.user !== undefined && props.building.typology_dynamic_classification !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("typology_dynamic_classification")}
|
||||||
|
user_verified_as={props.user_verified.typology_dynamic_classification}
|
||||||
|
verified_count={props.building.verified.typology_dynamic_classification}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_dynamic_classification_source_type.title}
|
||||||
|
slug="typology_dynamic_classification_source_type"
|
||||||
|
value={props.building.typology_dynamic_classification_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_dynamic_classification_source_type.tooltip}
|
||||||
|
placeholder={dataFields.typology_dynamic_classification_source_type.example}
|
||||||
|
options={dataFields.typology_dynamic_classification_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.typology_dynamic_classification_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.typology_dynamic_classification_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.typology_dynamic_classification_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_dynamic_classification_source_links.title}
|
||||||
|
slug="typology_dynamic_classification_source_links"
|
||||||
|
value={props.building.typology_dynamic_classification_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_dynamic_classification_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Original Use">
|
||||||
|
{(props.mapColourScale == "original_landuse") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToClassificationMapStyle}>
|
||||||
|
{'Click to change map to show typology classification.'}
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToLandUseMapStyle}>
|
||||||
|
{"Click here to change map to original land use."}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_original_use.title}
|
||||||
|
slug="typology_original_use"
|
||||||
|
value={props.building.typology_original_use}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
confirmOnEnter={true}
|
||||||
|
tooltip={dataFields.typology_original_use.tooltip}
|
||||||
|
placeholder="Type new land use group here"
|
||||||
|
copyable={true}
|
||||||
|
autofill={true}
|
||||||
|
showAllOptionsOnEmpty={true}
|
||||||
|
/>
|
||||||
|
<Verification
|
||||||
|
slug="typology_original_use"
|
||||||
|
allow_verify={props.user !== undefined && props.building.typology_original_use !== null && !props.edited}
|
||||||
|
onVerify={props.onVerify}
|
||||||
|
user_verified={props.user_verified.hasOwnProperty("typology_original_use")}
|
||||||
|
user_verified_as={props.user_verified.typology_original_use}
|
||||||
|
verified_count={props.building.verified.typology_original_use}
|
||||||
|
/>
|
||||||
|
<SelectDataEntry
|
||||||
|
title={dataFields.typology_original_use_source_type.title}
|
||||||
|
slug="typology_original_use_source_type"
|
||||||
|
value={props.building.typology_original_use_source_type}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_original_use_source_type.tooltip}
|
||||||
|
placeholder={dataFields.typology_original_use_source_type.example}
|
||||||
|
options={dataFields.typology_original_use_source_type.items}
|
||||||
|
/>
|
||||||
|
{(props.building.typology_original_use_source_type == commonSourceTypes[0] ||
|
||||||
|
props.building.typology_original_use_source_type == commonSourceTypes[1] ||
|
||||||
|
props.building.typology_original_use_source_type == null) ? <></> :
|
||||||
|
<>
|
||||||
|
<MultiDataEntry
|
||||||
|
title={dataFields.typology_original_use_source_links.title}
|
||||||
|
slug="typology_original_use_source_links"
|
||||||
|
value={props.building.typology_original_use_source_links}
|
||||||
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
tooltip={dataFields.typology_original_use_source_links.tooltip}
|
||||||
|
placeholder="https://..."
|
||||||
|
editableEntries={true}
|
||||||
|
isUrl={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
<hr/>
|
||||||
|
{
|
||||||
|
props.mode != 'view' &&
|
||||||
|
<div>
|
||||||
|
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
|
||||||
|
<i>
|
||||||
|
Below is a more general classification for the original land use of this building, automatically derived from the information above.
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<DataEntry
|
||||||
|
title={dataFields.typology_original_use_order.title}
|
||||||
|
tooltip={dataFields.typology_original_use_order.tooltip}
|
||||||
|
slug="typology_original_use_order"
|
||||||
|
value={props.building.typology_original_use_order}
|
||||||
|
mode={props.mode}
|
||||||
|
disabled={true}
|
||||||
|
copy={props.copy}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
</DataEntryGroup>
|
||||||
|
<DataEntryGroup name="Attachment/Adjacency">
|
||||||
|
{(props.mapColourScale == "building_attachment_form") ?
|
||||||
|
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToClassificationMapStyle}>
|
||||||
|
{'Click to change map to show typology classification.'}
|
||||||
|
</button>
|
||||||
|
:
|
||||||
|
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAttachmentMapStyle}>
|
||||||
|
{"Click here to change map to show attachment/adjacency."}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.building_attachment_form.title}
|
title={dataFields.building_attachment_form.title}
|
||||||
slug="building_attachment_form"
|
slug="building_attachment_form"
|
||||||
value={props.building.building_attachment_form}
|
value={props.building.building_attachment_form}
|
||||||
tooltip={dataFields.building_attachment_form.tooltip}
|
tooltip={dataFields.building_attachment_form.tooltip}
|
||||||
options={AttachmentFormOptions}
|
options={dataFields.building_attachment_form.items}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
@ -43,67 +332,38 @@ const TypeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
user_verified_as={props.user_verified.building_attachment_form}
|
user_verified_as={props.user_verified.building_attachment_form}
|
||||||
verified_count={props.building.verified.building_attachment_form}
|
verified_count={props.building.verified.building_attachment_form}
|
||||||
/>
|
/>
|
||||||
<DataEntry
|
<SelectDataEntry
|
||||||
title="Source type"
|
title={dataFields.building_attachment_source_type.title}
|
||||||
slug=""
|
slug="building_attachment_source_type"
|
||||||
value=""
|
value={props.building.building_attachment_source_type}
|
||||||
mode='view'
|
|
||||||
tooltip="Coming Soon"
|
|
||||||
/>
|
|
||||||
<DataEntry
|
|
||||||
title="Source link"
|
|
||||||
slug=""
|
|
||||||
value=""
|
|
||||||
mode='view'
|
|
||||||
tooltip="Coming Soon"
|
|
||||||
/>
|
|
||||||
<hr/>
|
|
||||||
<DataEntry
|
|
||||||
title={dataFields.original_building_use.title}
|
|
||||||
slug="original_building_use" // doesn't exist in database yet
|
|
||||||
tooltip={dataFields.original_building_use.tooltip}
|
|
||||||
value={undefined}
|
|
||||||
copy={props.copy}
|
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
disabled={true}
|
tooltip={dataFields.building_attachment_source_type.tooltip}
|
||||||
|
placeholder={dataFields.building_attachment_source_type.example}
|
||||||
|
options={dataFields.building_attachment_source_type.items}
|
||||||
/>
|
/>
|
||||||
<Verification
|
{(props.building.building_attachment_source_type == commonSourceTypes[0] ||
|
||||||
slug="building_attachment_form"
|
props.building.building_attachment_source_type == commonSourceTypes[1] ||
|
||||||
allow_verify={props.user !== undefined && props.building.building_attachment_form !== null && !props.edited}
|
props.building.building_attachment_source_type == null) ? <></> :
|
||||||
onVerify={props.onVerify}
|
<>
|
||||||
user_verified={props.user_verified.hasOwnProperty("building_attachment_form")}
|
<MultiDataEntry
|
||||||
user_verified_as={props.user_verified.building_attachment_form}
|
title={dataFields.building_attachment_source_links.title}
|
||||||
verified_count={props.building.verified.building_attachment_form}
|
slug="building_attachment_source_links"
|
||||||
/>
|
value={props.building.building_attachment_source_links}
|
||||||
<DataEntry
|
mode={props.mode}
|
||||||
title="Source type"
|
copy={props.copy}
|
||||||
slug=""
|
onChange={props.onChange}
|
||||||
value=""
|
tooltip={dataFields.building_attachment_source_links.tooltip}
|
||||||
mode='view'
|
placeholder="https://..."
|
||||||
tooltip="Coming Soon"
|
editableEntries={true}
|
||||||
/>
|
isUrl={true}
|
||||||
<DataEntry
|
|
||||||
title="Source link"
|
|
||||||
slug=""
|
|
||||||
value=""
|
|
||||||
mode='view'
|
|
||||||
tooltip="Coming Soon"
|
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>
|
||||||
<DataEntryGroup name="Building typology and classification data">
|
{/*}
|
||||||
<DataEntry
|
<DataEntryGroup name="Other fields (in development)">
|
||||||
title="Local typology/architectural style"
|
|
||||||
slug=""
|
|
||||||
value=""
|
|
||||||
mode='view'
|
|
||||||
/>
|
|
||||||
<DataEntry
|
|
||||||
title="Base type classification"
|
|
||||||
slug=""
|
|
||||||
value=""
|
|
||||||
mode='view'
|
|
||||||
/>
|
|
||||||
<SelectDataEntry
|
<SelectDataEntry
|
||||||
title={dataFields.size_roof_shape.title}
|
title={dataFields.size_roof_shape.title}
|
||||||
slug="size_roof_shape"
|
slug="size_roof_shape"
|
||||||
@ -136,6 +396,7 @@ const TypeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
value=""
|
value=""
|
||||||
mode='view'
|
mode='view'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* <NumericDataEntry
|
{/* <NumericDataEntry
|
||||||
title={dataFields.date_change_building_use.title}
|
title={dataFields.date_change_building_use.title}
|
||||||
slug="date_change_building_use"
|
slug="date_change_building_use"
|
||||||
@ -147,8 +408,8 @@ const TypeView: React.FunctionComponent<CategoryViewProps> = (props) => {
|
|||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
copy={props.copy}
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/> */}
|
/>//*}
|
||||||
</DataEntryGroup>
|
</DataEntryGroup>*/}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -184,3 +184,16 @@
|
|||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uprn-list {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uprn-list li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
@ -98,7 +98,7 @@ export const categoriesConfig: {[key in Category]: CategoryDefinition} = {
|
|||||||
slug: 'typology',
|
slug: 'typology',
|
||||||
name: 'Typology',
|
name: 'Typology',
|
||||||
aboutUrl: 'https://pages.colouring.london/buildingtypology',
|
aboutUrl: 'https://pages.colouring.london/buildingtypology',
|
||||||
intro: 'Note: This section is currently under development, we are working to activate it as soon as possible. This section provides open data on the typology of the building.',
|
intro: 'This section provides open data on the typology of the building.',
|
||||||
},
|
},
|
||||||
[Category.LandUse]: {
|
[Category.LandUse]: {
|
||||||
slug: 'land-use',
|
slug: 'land-use',
|
||||||
|
@ -48,6 +48,25 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
mapStyle: 'typology_style_period',
|
||||||
|
legend: {
|
||||||
|
title: 'Architectural style',
|
||||||
|
elements: [
|
||||||
|
{ color: '#FFF739', text: '43AD-410 (Roman)' },
|
||||||
|
{ color: '#C5BD00', text: '410-1485 (Medieval)' },
|
||||||
|
{ color: '#FF9A39', text: '1485-1603 (Tudor)' },
|
||||||
|
{ color: '#C56000', text: '1603-1714 (Stuart)' },
|
||||||
|
{ color: '#EA8072', text: '1714-1837 (Georgian)' },
|
||||||
|
{ color: '#A71200', text: '1837-1901 (Victorian)' },
|
||||||
|
{ color: '#A272D4', text: '1901-1914 (Edwardian)' },
|
||||||
|
{ color: '#3988C5', text: '1914-1945 (WWI-WWII)' },
|
||||||
|
{ color: '#5ADFA2', text: '1946-1979 (Post war)' },
|
||||||
|
{ color: '#C2F47A', text: '1980-1999 (Late C20)' },
|
||||||
|
{ color: '#6FB40A', text: '2000-2025 (Early C21)' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
mapStyle: 'survival_status',
|
mapStyle: 'survival_status',
|
||||||
legend: {
|
legend: {
|
||||||
@ -299,10 +318,82 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
[Category.Typology]: [{
|
[Category.Typology]: [
|
||||||
|
{
|
||||||
|
mapStyle: 'typology_classification',
|
||||||
|
legend: {
|
||||||
|
title: 'Typology classification',
|
||||||
|
elements: [
|
||||||
|
{ color: '#0311AB', text: '1-3 storeys: Detached' },
|
||||||
|
{ color: '#3845D4', text: '1-3 storeys: Tightly grouped' },
|
||||||
|
{ color: '#6D79FD', text: '1-3 storeys: Loosely grouped' },
|
||||||
|
{ color: '#FF5D00', text: '4-7 storeys: Detached' },
|
||||||
|
{ color: '#FF8000', text: '4-7 storeys: Tightly grouped' },
|
||||||
|
{ color: '#FFA200', text: '4-7 storeys: Loosely grouped' },
|
||||||
|
{ color: '#AB1303', text: '8+ storeys: Detached' },
|
||||||
|
{ color: '#D43A29', text: '8+ storeys: Tightly grouped' },
|
||||||
|
{ color: '#FC604F', text: '8+ storeys: Loosely grouped' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*{
|
||||||
|
mapStyle: 'typology_style_period',
|
||||||
|
legend: {
|
||||||
|
title: 'Architectural style',
|
||||||
|
elements: [
|
||||||
|
{ color: '#FFF739', text: '43AD-410 (Roman)' },
|
||||||
|
{ color: '#C5BD00', text: '410-1485 (Medieval)' },
|
||||||
|
{ color: '#FF9A39', text: '1485-1603 (Tudor)' },
|
||||||
|
{ color: '#C56000', text: '1603-1714 (Stuart)' },
|
||||||
|
{ color: '#EA8072', text: '1714-1837 (Georgian)' },
|
||||||
|
{ color: '#A71200', text: '1837-1901 (Victorian)' },
|
||||||
|
{ color: '#A272D4', text: '1901-1914 (Edwardian)' },
|
||||||
|
{ color: '#3988C5', text: '1914-1945 (WWI-WWII)' },
|
||||||
|
{ color: '#5ADFA2', text: '1946-1979 (Post war)' },
|
||||||
|
{ color: '#C2F47A', text: '1980-1999 (Late C20)' },
|
||||||
|
{ color: '#6FB40A', text: '2000-2025 (Early C21)' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},*/
|
||||||
|
{
|
||||||
|
mapStyle: 'typology_dynamic_classification',
|
||||||
|
legend: {
|
||||||
|
title: 'Dynamic classification',
|
||||||
|
elements: [
|
||||||
|
{ color: '#96484A', text: 'Repetitive small, domestic plots' },
|
||||||
|
{ color: '#4B9889', text: 'Linear non-domestic, i.e. high streets' },
|
||||||
|
{ color: '#4F8DA8', text: 'Large plots with internal roads' },
|
||||||
|
{ color: '#897A5D', text: 'Other' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mapStyle: 'original_landuse',
|
||||||
|
legend: {
|
||||||
|
title: 'Original Land Use',
|
||||||
|
elements: [
|
||||||
|
{ color: '#e5050d', text: 'Mixed Use' },
|
||||||
|
{ subtitle: 'Single use:'},
|
||||||
|
{ color: '#252aa6', text: 'Residential (unverified)' },
|
||||||
|
{ color: '#7025a6', text: 'Residential (verified)' },
|
||||||
|
{ color: '#ff8c00', text: 'Retail' },
|
||||||
|
{ color: '#f5f58f', text: 'Industry & Business' },
|
||||||
|
{ color: '#fa667d', text: 'Community Services' },
|
||||||
|
{ color: '#ffbfbf', text: 'Recreation & Leisure' },
|
||||||
|
{ color: '#b3de69', text: 'Transport' },
|
||||||
|
{ color: '#cccccc', text: 'Utilities & Infrastructure' },
|
||||||
|
{ color: '#898944', text: 'Defence' },
|
||||||
|
{ color: '#73ccd1', text: 'Agriculture' },
|
||||||
|
{ color: '#45cce3', text: 'Minerals' },
|
||||||
|
{ color: '#ffffff', text: 'Vacant & Derelict' },
|
||||||
|
{ color: '#6c6f8e', text: 'Unclassified, presumed non-residential' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
mapStyle: 'building_attachment_form',
|
mapStyle: 'building_attachment_form',
|
||||||
legend: {
|
legend: {
|
||||||
title: 'Adjacency/Configuration',
|
title: 'Attachment/Adjacency',
|
||||||
elements: [
|
elements: [
|
||||||
{ color: "#f2a2b9", text: "Detached" },
|
{ color: "#f2a2b9", text: "Detached" },
|
||||||
{ color: "#ab8fb0", text: "Semi-Detached" },
|
{ color: "#ab8fb0", text: "Semi-Detached" },
|
||||||
@ -310,7 +401,8 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
|
|||||||
{ color: "#226291", text: "Mid-Terrace" }
|
{ color: "#226291", text: "Mid-Terrace" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
[Category.LandUse]: [
|
[Category.LandUse]: [
|
||||||
{
|
{
|
||||||
mapStyle: 'landuse',
|
mapStyle: 'landuse',
|
||||||
@ -338,11 +430,11 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
|
|||||||
{
|
{
|
||||||
mapStyle: 'is_domestic',
|
mapStyle: 'is_domestic',
|
||||||
legend: {
|
legend: {
|
||||||
title: 'Domestic building',
|
title: 'Residential building',
|
||||||
elements: [
|
elements: [
|
||||||
{ color: '#f7ec25', text: 'Domestic' },
|
{ color: '#f7ec25', text: 'Residential' },
|
||||||
{ color: '#fc9b2a', text: 'Mixed' },
|
{ color: '#fc9b2a', text: 'Mixed' },
|
||||||
{ color: '#ff2121', text: 'Non-domestic' },
|
{ color: '#ff2121', text: 'Non-residential' },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import ResilienceContainer from '../building/data-containers/resilience';
|
|||||||
import LocationContainer from '../building/data-containers/location';
|
import LocationContainer from '../building/data-containers/location';
|
||||||
import PlanningContainer from '../building/data-containers/planning';
|
import PlanningContainer from '../building/data-containers/planning';
|
||||||
import SizeContainer from '../building/data-containers/size';
|
import SizeContainer from '../building/data-containers/size';
|
||||||
import StreetscapeContainer from '../building/data-containers/street-context';
|
import StreetContextContainer from '../building/data-containers/street-context';
|
||||||
import SustainabilityContainer from '../building/data-containers/energy-performance';
|
import SustainabilityContainer from '../building/data-containers/energy-performance';
|
||||||
import TeamContainer from '../building/data-containers/team';
|
import TeamContainer from '../building/data-containers/team';
|
||||||
import TypeContainer from '../building/data-containers/typology';
|
import TypeContainer from '../building/data-containers/typology';
|
||||||
@ -22,7 +22,7 @@ export const categoryUiConfig: {[key in Category]: DataContainerType} = {
|
|||||||
[Category.Age]: AgeContainer,
|
[Category.Age]: AgeContainer,
|
||||||
[Category.Size]: SizeContainer,
|
[Category.Size]: SizeContainer,
|
||||||
[Category.Construction]: ConstructionContainer,
|
[Category.Construction]: ConstructionContainer,
|
||||||
[Category.StreetContext]: StreetscapeContainer,
|
[Category.StreetContext]: StreetContextContainer,
|
||||||
[Category.Team]: TeamContainer,
|
[Category.Team]: TeamContainer,
|
||||||
[Category.Planning]: PlanningContainer,
|
[Category.Planning]: PlanningContainer,
|
||||||
[Category.EnergyPerformance]: SustainabilityContainer,
|
[Category.EnergyPerformance]: SustainabilityContainer,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,10 +21,14 @@ export type BuildingMapTileset =
|
|||||||
'sust_dec' |
|
'sust_dec' |
|
||||||
'building_attachment_form' |
|
'building_attachment_form' |
|
||||||
'landuse' |
|
'landuse' |
|
||||||
|
'original_landuse' |
|
||||||
'dynamics_demolished_count' |
|
'dynamics_demolished_count' |
|
||||||
'disaster_severity' |
|
'disaster_severity' |
|
||||||
'team' |
|
'team' |
|
||||||
'survival_status';
|
'survival_status'|
|
||||||
|
'typology_classification'|
|
||||||
|
'typology_style_period' |
|
||||||
|
'typology_dynamic_classification';
|
||||||
|
|
||||||
export type SpecialMapTileset = 'base_light' | 'base_night' | 'base_night_outlines' | 'highlight' | 'number_labels' | 'base_boroughs';
|
export type SpecialMapTileset = 'base_light' | 'base_night' | 'base_night_outlines' | 'highlight' | 'number_labels' | 'base_boroughs';
|
||||||
|
|
||||||
|
@ -38,6 +38,10 @@ interface DisplayPreferencesContextState {
|
|||||||
historicDataSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
historicDataSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||||
historicDataSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
historicDataSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
|
||||||
|
historicMap: LayerEnablementState;
|
||||||
|
historicMapSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||||
|
historicMapSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
|
||||||
darkLightTheme: MapTheme;
|
darkLightTheme: MapTheme;
|
||||||
darkLightThemeSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
darkLightThemeSwitch: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||||
darkLightThemeSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
darkLightThemeSwitchOnClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
@ -87,6 +91,10 @@ export const DisplayPreferencesContext = createContext<DisplayPreferencesContext
|
|||||||
historicDataSwitch: stub,
|
historicDataSwitch: stub,
|
||||||
historicDataSwitchOnClick: undefined,
|
historicDataSwitchOnClick: undefined,
|
||||||
|
|
||||||
|
historicMap: undefined,
|
||||||
|
historicMapSwitch: stub,
|
||||||
|
historicMapSwitchOnClick: undefined,
|
||||||
|
|
||||||
darkLightTheme: undefined,
|
darkLightTheme: undefined,
|
||||||
darkLightThemeSwitch: stub,
|
darkLightThemeSwitch: stub,
|
||||||
darkLightThemeSwitchOnClick: undefined,
|
darkLightThemeSwitchOnClick: undefined,
|
||||||
@ -107,6 +115,7 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
const defaultParcel = 'disabled'
|
const defaultParcel = 'disabled'
|
||||||
const defaultConservation = 'disabled'
|
const defaultConservation = 'disabled'
|
||||||
const defaultHistoricData = 'disabled'
|
const defaultHistoricData = 'disabled'
|
||||||
|
const defaultHistoricMap = 'disabled'
|
||||||
const defaultShowLayerSelection = 'disabled'
|
const defaultShowLayerSelection = 'disabled'
|
||||||
const [vista, setVista] = useState<LayerEnablementState>(defaultVista);
|
const [vista, setVista] = useState<LayerEnablementState>(defaultVista);
|
||||||
const [flood, setFlood] = useState<LayerEnablementState>(defaultFlood);
|
const [flood, setFlood] = useState<LayerEnablementState>(defaultFlood);
|
||||||
@ -116,6 +125,7 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
const [parcel, setParcel] = useState<LayerEnablementState>(defaultParcel);
|
const [parcel, setParcel] = useState<LayerEnablementState>(defaultParcel);
|
||||||
const [conservation, setConservation] = useState<LayerEnablementState>(defaultConservation);
|
const [conservation, setConservation] = useState<LayerEnablementState>(defaultConservation);
|
||||||
const [historicData, setHistoricData] = useState<LayerEnablementState>(defaultHistoricData);
|
const [historicData, setHistoricData] = useState<LayerEnablementState>(defaultHistoricData);
|
||||||
|
const [historicMap, setHistoricMap] = useState<LayerEnablementState>(defaultHistoricMap);
|
||||||
const [darkLightTheme, setDarkLightTheme] = useState<MapTheme>('night');
|
const [darkLightTheme, setDarkLightTheme] = useState<MapTheme>('night');
|
||||||
const [showLayerSelection, setShowLayerSelection] = useState<LayerEnablementState>(defaultShowLayerSelection);
|
const [showLayerSelection, setShowLayerSelection] = useState<LayerEnablementState>(defaultShowLayerSelection);
|
||||||
|
|
||||||
@ -136,6 +146,7 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
setParcel(defaultParcel);
|
setParcel(defaultParcel);
|
||||||
setConservation(defaultConservation);
|
setConservation(defaultConservation);
|
||||||
setHistoricData(defaultHistoricData);
|
setHistoricData(defaultHistoricData);
|
||||||
|
setHistoricMap(defaultHistoricMap);
|
||||||
setShowLayerSelection(defaultShowLayerSelection); // reset layers + hiding this panel is integrated into one action
|
setShowLayerSelection(defaultShowLayerSelection); // reset layers + hiding this panel is integrated into one action
|
||||||
//setDarkLightTheme('night'); // reset only layers
|
//setDarkLightTheme('night'); // reset only layers
|
||||||
},
|
},
|
||||||
@ -167,6 +178,9 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
if(historicData != defaultHistoricData) {
|
if(historicData != defaultHistoricData) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(historicMap != defaultHistoricMap) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//darkLightTheme not handled here
|
//darkLightTheme not handled here
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -278,9 +292,12 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
|
|
||||||
const historicDataSwitch = useCallback(
|
const historicDataSwitch = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
flipHistoricData(e)
|
if (historicMap === 'enabled') {
|
||||||
|
fliphistoricMap(e);
|
||||||
|
}
|
||||||
|
flipHistoricData(e);
|
||||||
},
|
},
|
||||||
[historicData],
|
[historicData, historicMap],
|
||||||
)
|
)
|
||||||
const historicDataSwitchOnClick = (e) => {
|
const historicDataSwitchOnClick = (e) => {
|
||||||
flipHistoricData(e)
|
flipHistoricData(e)
|
||||||
@ -291,6 +308,24 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
setHistoricData(newHistoric);
|
setHistoricData(newHistoric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const historicMapSwitch = useCallback(
|
||||||
|
(e) => {
|
||||||
|
if (historicData === 'enabled') {
|
||||||
|
flipHistoricData(e);
|
||||||
|
}
|
||||||
|
fliphistoricMap(e);
|
||||||
|
},
|
||||||
|
[historicMap, historicData],
|
||||||
|
)
|
||||||
|
const historicMapSwitchOnClick = (e) => {
|
||||||
|
fliphistoricMap(e)
|
||||||
|
}
|
||||||
|
function fliphistoricMap(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const newHistoric = (historicMap === 'enabled')? 'disabled' : 'enabled';
|
||||||
|
setHistoricMap(newHistoric);
|
||||||
|
}
|
||||||
|
|
||||||
const darkLightThemeSwitch = useCallback(
|
const darkLightThemeSwitch = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
flipDarkLightTheme(e)
|
flipDarkLightTheme(e)
|
||||||
@ -354,6 +389,10 @@ export const DisplayPreferencesProvider: React.FC<{}> = ({children}) => {
|
|||||||
historicDataSwitch,
|
historicDataSwitch,
|
||||||
historicDataSwitchOnClick,
|
historicDataSwitchOnClick,
|
||||||
|
|
||||||
|
historicMap,
|
||||||
|
historicMapSwitch,
|
||||||
|
historicMapSwitchOnClick,
|
||||||
|
|
||||||
darkLightTheme,
|
darkLightTheme,
|
||||||
darkLightThemeSwitch,
|
darkLightThemeSwitch,
|
||||||
darkLightThemeSwitchOnClick,
|
darkLightThemeSwitchOnClick,
|
||||||
|
@ -57,7 +57,8 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "https://github.com/colouring-cities/manual/wiki",
|
to: "https://github.com/colouring-cities/manual/wiki",
|
||||||
text: "Open Manual - Wiki",
|
text: "Colouring Cities Open Manual/Wiki",
|
||||||
|
disabled: false,
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -65,12 +66,6 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
|
|||||||
text: "Open code",
|
text: "Open code",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
to: "https://github.com/colouring-cities/manual/wiki",
|
|
||||||
text: "Colouring Cities Open Manual/Wiki",
|
|
||||||
disabled: false,
|
|
||||||
external: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
to: "/showcase.html",
|
to: "/showcase.html",
|
||||||
text: "Case Study Showcase",
|
text: "Case Study Showcase",
|
||||||
@ -79,30 +74,35 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
to: "https://pages.colouring.london",
|
to: "https://github.com/colouring-cities/manual/wiki/A.-What-is-the-CCRP%3F",
|
||||||
text: "About",
|
text: "About the Colouring Cities Research Programme",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "https://pages.colouring.london/buildingcategories",
|
to: config.manualURL,
|
||||||
|
text: "About the Colouring " + config.cityName + " Project",
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
to: "https://github.com/colouring-cities/manual/wiki/A2.-How-to%3F-Guides",
|
||||||
|
text: "How to Use",
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
to: "https://github.com/colouring-cities/manual/wiki/I.--DATA",
|
||||||
text: "Data Categories",
|
text: "Data Categories",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "https://pages.colouring.london/whoisinvolved",
|
to: "https://github.com/colouring-cities/manual/wiki/M3.2-Colouring-Britain:-Who's-Involved%3F",
|
||||||
text: "Who's Involved?",
|
text: "Who's Involved?",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "https://pages.colouring.london/data-ethics",
|
to: "https://github.com/colouring-cities/manual/wiki/C.-Ethical-framework-and-ethics-policies",
|
||||||
text: "Data Ethics",
|
text: "Ethical Framework",
|
||||||
external: true
|
external: true
|
||||||
},
|
}
|
||||||
{
|
|
||||||
to: "https://pages.colouring.london/colouring-cities",
|
|
||||||
text: "Colouring Cities Research Programme",
|
|
||||||
external: true
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -110,32 +110,45 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
|
|||||||
text: "Top Contributors"
|
text: "Top Contributors"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "https://discuss.colouring.london",
|
to: config.githubURL+"/discussions",
|
||||||
text: "Discussion Forum",
|
text: "Discussion Forum (GitHub)",
|
||||||
external: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: "https://discuss.colouring.london/c/blog/9",
|
|
||||||
text: "Blog",
|
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// to: "https://discuss.colouring.london/c/blog/9",
|
||||||
|
// text: "Blog",
|
||||||
|
// external: true
|
||||||
|
// },
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
to: "/privacy-policy.html",
|
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor-privacy-statement",
|
||||||
text: "Privacy Policy"
|
text: "Privacy Policy",
|
||||||
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "/contributor-agreement.html",
|
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor--data-user-data-accuracy--ethical-use-agreement",
|
||||||
text: "Contributor Agreement"
|
text: "Contributor Agreement",
|
||||||
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "/code-of-conduct.html",
|
to: "/code-of-conduct.html",
|
||||||
text: "Code of Conduct"
|
text: "Code of Conduct"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "/data-accuracy.html",
|
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor--data-user-data-accuracy--ethical-use-agreement",
|
||||||
text: "Data Accuracy Agreement"
|
text: "Data Accuracy and Use Agreement",
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-equality-diversity-and-inclusion-policy",
|
||||||
|
text: "Equality, Diversity and Inclusion",
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-protocols-for-international-academic-partners",
|
||||||
|
text: "CCRP Academic Partner Protocols",
|
||||||
|
external: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: "/ordnance-survey-uprn.html",
|
to: "/ordnance-survey-uprn.html",
|
||||||
@ -183,7 +196,7 @@ const InternalNavLink: React.FC<{to: string; onClick: () => void}> = ({ to, onCl
|
|||||||
);
|
);
|
||||||
|
|
||||||
const ExternalNavLink: React.FC<{to: string}> = ({ to, children }) => (
|
const ExternalNavLink: React.FC<{to: string}> = ({ to, children }) => (
|
||||||
<a className="nav-link" href={to}>
|
<a className="nav-link" href={to} target="_blank">
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
@ -5,11 +5,12 @@ import { useDisplayPreferences } from '../displayPreferences-context';
|
|||||||
|
|
||||||
export const HistoricDataSwitcher: React.FC<{}> = (props) => {
|
export const HistoricDataSwitcher: React.FC<{}> = (props) => {
|
||||||
const { historicData, historicDataSwitch, darkLightTheme } = useDisplayPreferences();
|
const { historicData, historicDataSwitch, darkLightTheme } = useDisplayPreferences();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={`historic-data-switcher map-button ${historicData}-state ${darkLightTheme}`} onSubmit={historicDataSwitch}>
|
<form className={`historic-data-switcher map-button ${historicData}-state ${darkLightTheme}`} onSubmit={historicDataSwitch}>
|
||||||
<button className="btn btn-outline btn-outline-dark"
|
<button className="btn btn-outline btn-outline-dark"
|
||||||
type="submit">
|
type="submit">
|
||||||
{(historicData === 'enabled')? 'The OS 1890s Historical Map on' : 'The OS 1890s Historical Map off'}
|
{(historicData === 'enabled')? 'OS 1890s Historical Map + Footprints on' : 'OS 1890s Historical Map + Footprints off'}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
17
app/src/frontend/map/historic-map-switcher.tsx
Normal file
17
app/src/frontend/map/historic-map-switcher.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import './map-button.css';
|
||||||
|
import { useDisplayPreferences } from '../displayPreferences-context';
|
||||||
|
|
||||||
|
export const HistoricMapSwitcher: React.FC<{}> = (props) => {
|
||||||
|
const { historicMap, historicMapSwitch, darkLightTheme } = useDisplayPreferences();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className={`historic-map-switcher map-button ${historicMap}-state ${darkLightTheme}`} onSubmit={historicMapSwitch}>
|
||||||
|
<button className="btn btn-outline btn-outline-dark"
|
||||||
|
type="submit">
|
||||||
|
{(historicMap === 'enabled')? 'OS 1890s Historical Map on' : 'OS 1890s Historical Map off'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
21
app/src/frontend/map/layers/historic-map-layer.tsx
Normal file
21
app/src/frontend/map/layers/historic-map-layer.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { TileLayer } from 'react-leaflet';
|
||||||
|
import { LayerEnablementState } from '../../config/map-config';
|
||||||
|
import { BuildingBaseLayerAllZoom } from './building-base-layer-all-zoom';
|
||||||
|
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||||
|
import { BuildingDataLayer } from './building-data-layer';
|
||||||
|
|
||||||
|
export function HistoricMapLayer({revisionId}: {revisionId: string}) {
|
||||||
|
const { historicMap } = useDisplayPreferences();
|
||||||
|
if(historicMap == "enabled") {
|
||||||
|
return <>
|
||||||
|
<TileLayer
|
||||||
|
url="https://mapseries-tilesets.s3.amazonaws.com/london_1890s/{z}/{x}/{y}.png"
|
||||||
|
attribution='© CC BY 4.0 - Reproduced with the permission of the <a href="https://maps.nls.uk/">National Library of Scotland</a>'
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,7 +57,7 @@
|
|||||||
padding: 0.5rem 0.25rem;
|
padding: 0.5rem 0.25rem;
|
||||||
margin: 0.25rem 0.5rem;
|
margin: 0.25rem 0.5rem;
|
||||||
width: auto;
|
width: auto;
|
||||||
font-size: 18px;
|
font-size: 17px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
@ -111,11 +111,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.historic-data-switcher {
|
.historic-data-switcher {
|
||||||
|
top: 437px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.historic-map-switcher {
|
||||||
top: 397px;
|
top: 397px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.parcel-switcher {
|
.parcel-switcher {
|
||||||
top: 437px;
|
top: 477px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-switcher-inline {
|
.map-switcher-inline {
|
||||||
|
@ -15,6 +15,7 @@ import { BoroughBoundaryLayer } from './layers/borough-boundary-layer';
|
|||||||
import { BoroughLabelLayer } from './layers/borough-label-layer';
|
import { BoroughLabelLayer } from './layers/borough-label-layer';
|
||||||
import { ParcelBoundaryLayer } from './layers/parcel-boundary-layer';
|
import { ParcelBoundaryLayer } from './layers/parcel-boundary-layer';
|
||||||
import { HistoricDataLayer } from './layers/historic-data-layer';
|
import { HistoricDataLayer } from './layers/historic-data-layer';
|
||||||
|
import { HistoricMapLayer } from './layers/historic-map-layer';
|
||||||
import { FloodBoundaryLayer } from './layers/flood-boundary-layer';
|
import { FloodBoundaryLayer } from './layers/flood-boundary-layer';
|
||||||
import { ConservationAreaBoundaryLayer } from './layers/conservation-boundary-layer';
|
import { ConservationAreaBoundaryLayer } from './layers/conservation-boundary-layer';
|
||||||
import { VistaBoundaryLayer } from './layers/vista-boundary-layer';
|
import { VistaBoundaryLayer } from './layers/vista-boundary-layer';
|
||||||
@ -34,6 +35,7 @@ import { ParcelSwitcher } from './parcel-switcher';
|
|||||||
import { FloodSwitcher } from './flood-switcher';
|
import { FloodSwitcher } from './flood-switcher';
|
||||||
import { ConservationAreaSwitcher } from './conservation-switcher';
|
import { ConservationAreaSwitcher } from './conservation-switcher';
|
||||||
import { HistoricDataSwitcher } from './historic-data-switcher';
|
import { HistoricDataSwitcher } from './historic-data-switcher';
|
||||||
|
import { HistoricMapSwitcher } from './historic-map-switcher';
|
||||||
import { VistaSwitcher } from './vista-switcher';
|
import { VistaSwitcher } from './vista-switcher';
|
||||||
import { CreativeSwitcher } from './creative-switcher';
|
import { CreativeSwitcher } from './creative-switcher';
|
||||||
import { HousingSwitcher } from './housing-switcher';
|
import { HousingSwitcher } from './housing-switcher';
|
||||||
@ -129,6 +131,7 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
|||||||
>
|
>
|
||||||
<CityBoundaryLayer/>
|
<CityBoundaryLayer/>
|
||||||
<HistoricDataLayer revisionId={revisionId} />
|
<HistoricDataLayer revisionId={revisionId} />
|
||||||
|
<HistoricMapLayer revisionId={revisionId} />
|
||||||
<BoroughBoundaryLayer/>
|
<BoroughBoundaryLayer/>
|
||||||
<ParcelBoundaryLayer/>
|
<ParcelBoundaryLayer/>
|
||||||
<FloodBoundaryLayer/>
|
<FloodBoundaryLayer/>
|
||||||
@ -167,10 +170,12 @@ export const ColouringMap : FC<ColouringMapProps> = ({
|
|||||||
<ParcelSwitcher/>
|
<ParcelSwitcher/>
|
||||||
<FloodSwitcher/>
|
<FloodSwitcher/>
|
||||||
<ConservationAreaSwitcher/>
|
<ConservationAreaSwitcher/>
|
||||||
|
<HistoricMapSwitcher/>
|
||||||
<HistoricDataSwitcher/>
|
<HistoricDataSwitcher/>
|
||||||
<VistaSwitcher />
|
<VistaSwitcher />
|
||||||
<HousingSwitcher />
|
<HousingSwitcher />
|
||||||
<CreativeSwitcher />
|
<CreativeSwitcher />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
: <></>
|
: <></>
|
||||||
}
|
}
|
||||||
|
@ -266,6 +266,15 @@ const LAYER_QUERIES = {
|
|||||||
buildings
|
buildings
|
||||||
WHERE
|
WHERE
|
||||||
current_landuse_order IS NOT NULL`,
|
current_landuse_order IS NOT NULL`,
|
||||||
|
original_landuse: `
|
||||||
|
SELECT
|
||||||
|
geometry_id,
|
||||||
|
typology_original_use_order,
|
||||||
|
typology_original_use[1] as typology_original_use,
|
||||||
|
typology_original_use_verified
|
||||||
|
FROM
|
||||||
|
buildings
|
||||||
|
WHERE typology_original_use IS NOT NULL`,
|
||||||
disaster_severity: `
|
disaster_severity: `
|
||||||
SELECT
|
SELECT
|
||||||
geometry_id,
|
geometry_id,
|
||||||
@ -281,6 +290,27 @@ const LAYER_QUERIES = {
|
|||||||
FROM
|
FROM
|
||||||
buildings
|
buildings
|
||||||
WHERE jsonb_array_length(demolished_buildings) > 0 OR dynamics_has_demolished_buildings = FALSE`,
|
WHERE jsonb_array_length(demolished_buildings) > 0 OR dynamics_has_demolished_buildings = FALSE`,
|
||||||
|
typology_classification: `
|
||||||
|
SELECT
|
||||||
|
geometry_id,
|
||||||
|
typology_classification
|
||||||
|
FROM
|
||||||
|
buildings
|
||||||
|
WHERE typology_classification IS NOT NULL`,
|
||||||
|
typology_style_period: `
|
||||||
|
SELECT
|
||||||
|
geometry_id,
|
||||||
|
typology_style_period
|
||||||
|
FROM
|
||||||
|
buildings
|
||||||
|
WHERE typology_style_period IS NOT NULL`,
|
||||||
|
typology_dynamic_classification: `
|
||||||
|
SELECT
|
||||||
|
geometry_id,
|
||||||
|
typology_dynamic_classification
|
||||||
|
FROM
|
||||||
|
buildings
|
||||||
|
WHERE typology_dynamic_classification IS NOT NULL`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const GEOMETRY_FIELD = 'geometry_geom';
|
const GEOMETRY_FIELD = 'geometry_geom';
|
||||||
|
@ -326,6 +326,8 @@ pip install -r requirements.txt
|
|||||||
|
|
||||||
To help test the Colouring Cities application, `get_test_polygons.py` will attempt to save a small (1.5km²) extract from OpenStreetMap to a format suitable for loading to the database.
|
To help test the Colouring Cities application, `get_test_polygons.py` will attempt to save a small (1.5km²) extract from OpenStreetMap to a format suitable for loading to the database.
|
||||||
|
|
||||||
|
**NOTE:** You can edit the file by [changing this line](https://github.com/colouring-cities/colouring-core/blob/df651521983665056d442603a329a37d966aede1/etl/get_test_polygons.py#L22) to specify the latitude and longitude used to define the centre of the sample data area, as well as the distance from that point, which are used to generate the sample data. (i.e. you could change it to match the cc-config.json file - as discussed in [configuring-colouring-cities.md](https://github.com/colouring-cities/colouring-core/blob/master/docs/configuring-colouring-cities.md).
|
||||||
|
|
||||||
Download the test data.
|
Download the test data.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -1 +1,3 @@
|
|||||||
from .filter_mastermap import filter_mastermap
|
from .filter_mastermap import filter_mastermap
|
||||||
|
|
||||||
|
__all__ = ["filter_mastermap"]
|
||||||
|
@ -20,24 +20,24 @@ def main(mastermap_path):
|
|||||||
def filter_mastermap(mm_path):
|
def filter_mastermap(mm_path):
|
||||||
output_path = str(mm_path).replace(".gml.csv", "")
|
output_path = str(mm_path).replace(".gml.csv", "")
|
||||||
output_path = "{}.filtered.csv".format(output_path)
|
output_path = "{}.filtered.csv".format(output_path)
|
||||||
output_fieldnames = ('WKT', 'fid', 'descriptiveGroup')
|
output_fieldnames = ("WKT", "fid", "descriptiveGroup")
|
||||||
# Open the input csv with all polygons, buildings and others
|
# Open the input csv with all polygons, buildings and others
|
||||||
with open(mm_path, 'r') as fh:
|
with open(mm_path, "r") as fh:
|
||||||
r = csv.DictReader(fh)
|
r = csv.DictReader(fh)
|
||||||
# Open a new output csv that will contain just buildings
|
# Open a new output csv that will contain just buildings
|
||||||
with open(output_path, 'w') as output_fh:
|
with open(output_path, "w") as output_fh:
|
||||||
w = csv.DictWriter(output_fh, fieldnames=output_fieldnames)
|
w = csv.DictWriter(output_fh, fieldnames=output_fieldnames)
|
||||||
w.writeheader()
|
w.writeheader()
|
||||||
for line in r:
|
for line in r:
|
||||||
try:
|
try:
|
||||||
if 'Building' in line['descriptiveGroup']:
|
if "Building" in line["descriptiveGroup"]:
|
||||||
w.writerow(line)
|
w.writerow(line)
|
||||||
# when descriptiveGroup is missing, ignore this Polygon
|
# when descriptiveGroup is missing, ignore this Polygon
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print("Usage: filter_mastermap.py ./path/to/mastermap/dir")
|
print("Usage: filter_mastermap.py ./path/to/mastermap/dir")
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
@ -21,43 +21,49 @@ size = 256
|
|||||||
# load buildings from about 1.5km² around UCL
|
# load buildings from about 1.5km² around UCL
|
||||||
point = (51.524498, -0.133874)
|
point = (51.524498, -0.133874)
|
||||||
dist = 612
|
dist = 612
|
||||||
gdf = osmnx.footprints_from_point(point=point, dist=dist)
|
tags = {"building": True}
|
||||||
|
gdf = osmnx.features_from_point(point, tags, dist=dist)
|
||||||
|
|
||||||
# preview image
|
# preview image
|
||||||
gdf_proj = osmnx.projection.project_gdf(gdf, to_crs={'init': 'epsg:3857'})
|
gdf_proj = osmnx.projection.project_gdf(gdf, to_crs={"init": "epsg:3857"})
|
||||||
gdf_proj = gdf_proj[gdf_proj.geometry.apply(lambda g: g.geom_type != 'MultiPolygon')] # noqa
|
gdf_proj = gdf_proj[gdf_proj.geometry.type == "Polygon"]
|
||||||
|
|
||||||
fig, ax = osmnx.plot_footprints(gdf_proj, bgcolor='#333333',
|
fig, ax = osmnx.plot_footprints(
|
||||||
color='w', figsize=(4, 4),
|
gdf_proj,
|
||||||
save=True, show=False, close=True,
|
bgcolor="#333333",
|
||||||
filename='test_buildings_preview', dpi=600)
|
color="w",
|
||||||
|
figsize=(4, 4),
|
||||||
|
save=True,
|
||||||
|
show=False,
|
||||||
|
close=True,
|
||||||
|
filepath="test_buildings_preview.png",
|
||||||
|
dpi=600,
|
||||||
|
)
|
||||||
|
|
||||||
# save
|
# save
|
||||||
test_dir = os.path.dirname(__file__)
|
test_dir = os.path.dirname(__file__)
|
||||||
test_data_geojson = str(os.path.join(test_dir, 'test_buildings.geojson'))
|
test_data_geojson = str(os.path.join(test_dir, "test_buildings.geojson"))
|
||||||
subprocess.run(["rm", test_data_geojson])
|
subprocess.run(["rm", test_data_geojson])
|
||||||
|
gdf_to_save = gdf_proj.reset_index()[["osmid", "geometry"]]
|
||||||
|
|
||||||
gdf_to_save = gdf_proj.reset_index(
|
gdf_to_save.rename(columns={"osmid": "fid"}).to_file(
|
||||||
)[
|
test_data_geojson, driver="GeoJSON"
|
||||||
['index', 'geometry']
|
|
||||||
]
|
|
||||||
|
|
||||||
gdf_to_save.rename(
|
|
||||||
columns={'index': 'fid'}
|
|
||||||
).to_file(
|
|
||||||
test_data_geojson, driver='GeoJSON'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# convert to CSV
|
# convert to CSV
|
||||||
test_data_csv = str(os.path.join(test_dir, 'test_buildings.3857.csv'))
|
test_data_csv = str(os.path.join(test_dir, "test_buildings.3857.csv"))
|
||||||
subprocess.run(["rm", test_data_csv])
|
subprocess.run(["rm", test_data_csv])
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["ogr2ogr", "-f", "CSV", test_data_csv,
|
[
|
||||||
test_data_geojson, "-lco", "GEOMETRY=AS_WKT"]
|
"ogr2ogr",
|
||||||
|
"-f",
|
||||||
|
"CSV",
|
||||||
|
test_data_csv,
|
||||||
|
test_data_geojson,
|
||||||
|
"-lco",
|
||||||
|
"GEOMETRY=AS_WKT",
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# add SRID for ease of loading to PostgreSQL
|
# add SRID for ease of loading to PostgreSQL
|
||||||
subprocess.run(
|
subprocess.run(["sed", "-i", 's/^"POLYGON/"SRID=3857;POLYGON/', test_data_csv])
|
||||||
["sed", "-i", "s/^\"POLYGON/\"SRID=3857;POLYGON/",
|
|
||||||
test_data_csv]
|
|
||||||
)
|
|
||||||
|
@ -17,7 +17,6 @@ Then with this script:
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import json
|
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -28,50 +27,49 @@ from tqdm import tqdm
|
|||||||
|
|
||||||
|
|
||||||
def main(base_url, api_key, source_file):
|
def main(base_url, api_key, source_file):
|
||||||
"""Read from file, update buildings
|
"""Read from file, update buildings"""
|
||||||
"""
|
with open(source_file, "r") as source_fh:
|
||||||
with open(source_file, 'r') as source_fh:
|
|
||||||
source = csv.DictReader(source_fh)
|
source = csv.DictReader(source_fh)
|
||||||
for feature in tqdm(source, total=line_count(source_file)):
|
for feature in tqdm(source, total=line_count(source_file)):
|
||||||
building_id, data = process_ca(feature)
|
building_id, data = process_ca(feature)
|
||||||
if building_id and building_id != 'building_id':
|
if building_id and building_id != "building_id":
|
||||||
save_data(building_id, data, api_key, base_url)
|
save_data(building_id, data, api_key, base_url)
|
||||||
|
|
||||||
|
|
||||||
def line_count(fname):
|
def line_count(fname):
|
||||||
"""Count lines - relies on 'wc'
|
"""Count lines - relies on 'wc'"""
|
||||||
"""
|
p = subprocess.run(["wc", "-l", fname], stdout=subprocess.PIPE)
|
||||||
p = subprocess.run(['wc', '-l', fname], stdout=subprocess.PIPE)
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise IOError(err)
|
raise IOError(p.returncode)
|
||||||
return int(p.stdout.strip().split()[0])
|
return int(p.stdout.strip().split()[0])
|
||||||
|
|
||||||
|
|
||||||
def process_ca(props):
|
def process_ca(props):
|
||||||
building_id = props['building_id']
|
building_id = props["building_id"]
|
||||||
data = {
|
data = {
|
||||||
'planning_in_conservation_area': True,
|
"planning_in_conservation_area": True,
|
||||||
'planning_conservation_area_name': props['conservation_area_name']
|
"planning_conservation_area_name": props["conservation_area_name"],
|
||||||
}
|
}
|
||||||
return building_id, data
|
return building_id, data
|
||||||
|
|
||||||
|
|
||||||
def save_data(building_id, data, api_key, base_url):
|
def save_data(building_id, data, api_key, base_url):
|
||||||
"""Save data to a building
|
"""Save data to a building"""
|
||||||
"""
|
requests.post(
|
||||||
r = requests.post(
|
|
||||||
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
||||||
json=data
|
json=data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
url, api_key, filename = sys.argv[1], sys.argv[2], sys.argv[3]
|
url, api_key, filename = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print(
|
print(
|
||||||
"Usage: {} <URL> <api_key> ./path/to/conservation_areas.csv".format(
|
"Usage: {} <URL> <api_key> ./path/to/conservation_areas.csv".format(
|
||||||
os.path.basename(__file__)
|
os.path.basename(__file__)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
main(url, api_key, filename)
|
main(url, api_key, filename)
|
||||||
|
@ -44,8 +44,6 @@ TODO extend to allow latitude,longitude or easting,northing columns and lookup b
|
|||||||
"""
|
"""
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
@ -53,9 +51,8 @@ from retrying import retry
|
|||||||
|
|
||||||
|
|
||||||
def main(base_url, api_key, source_file, json_columns, no_overwrite=False, debug=False):
|
def main(base_url, api_key, source_file, json_columns, no_overwrite=False, debug=False):
|
||||||
"""Read from file, update buildings
|
"""Read from file, update buildings"""
|
||||||
"""
|
with open(source_file, "r") as source:
|
||||||
with open(source_file, 'r') as source:
|
|
||||||
reader = csv.DictReader(source)
|
reader = csv.DictReader(source)
|
||||||
for line in reader:
|
for line in reader:
|
||||||
building_id = find_building(line, base_url)
|
building_id = find_building(line, base_url)
|
||||||
@ -64,78 +61,86 @@ def main(base_url, api_key, source_file, json_columns, no_overwrite=False, debug
|
|||||||
if building_id is None:
|
if building_id is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if 'sust_dec' in line and line['sust_dec'] == '':
|
if "sust_dec" in line and line["sust_dec"] == "":
|
||||||
del line['sust_dec']
|
del line["sust_dec"]
|
||||||
|
|
||||||
if no_overwrite:
|
if no_overwrite:
|
||||||
try:
|
try:
|
||||||
if check_data_present(building_id, line.keys(), base_url):
|
if check_data_present(building_id, line.keys(), base_url):
|
||||||
print(f'Building {building_id}: Not updating to avoid overwriting existing data')
|
print(
|
||||||
|
f"Building {building_id}: Not updating to avoid overwriting existing data"
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
except ApiRequestError as e:
|
except ApiRequestError as e:
|
||||||
print(f'Error checking existing data for building {building_id}: status {e.code}, data: {e.data}')
|
print(
|
||||||
|
f"Error checking existing data for building {building_id}: status {e.code}, data: {e.data}"
|
||||||
|
)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
response_code, response_data = update_building(building_id, line, api_key, base_url)
|
response_code, response_data = update_building(
|
||||||
|
building_id, line, api_key, base_url
|
||||||
|
)
|
||||||
if response_code != 200:
|
if response_code != 200:
|
||||||
print('ERROR', building_id, response_code, response_data)
|
print("ERROR", building_id, response_code, response_data)
|
||||||
elif debug:
|
elif debug:
|
||||||
print('DEBUG', building_id, response_code, response_data)
|
print("DEBUG", building_id, response_code, response_data)
|
||||||
|
|
||||||
|
|
||||||
class ApiRequestError(Exception):
|
class ApiRequestError(Exception):
|
||||||
def __init__(self, code, data, message=''):
|
def __init__(self, code, data, message=""):
|
||||||
self.code = code
|
self.code = code
|
||||||
self.data = data
|
self.data = data
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
def check_data_present(building_id, fields, base_url):
|
def check_data_present(building_id, fields, base_url):
|
||||||
response_code, current_state = get_building(building_id, base_url)
|
response_code, current_state = get_building(building_id, base_url)
|
||||||
if response_code != 200:
|
if response_code != 200:
|
||||||
raise ApiRequestError(response_code, current_state)
|
raise ApiRequestError(response_code, current_state)
|
||||||
else:
|
else:
|
||||||
id_fields = set(['building_id', 'toid', 'uprn'])
|
id_fields = set(["building_id", "toid", "uprn"])
|
||||||
field_names_without_ids = [k for k in fields if k not in id_fields]
|
field_names_without_ids = [k for k in fields if k not in id_fields]
|
||||||
|
|
||||||
return any([current_state.get(k, None) != None for k in field_names_without_ids])
|
return any(
|
||||||
|
[current_state.get(k, None) is not None for k in field_names_without_ids]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
||||||
def get_building(building_id, base_url):
|
def get_building(building_id, base_url):
|
||||||
"""Get data for a building
|
"""Get data for a building"""
|
||||||
"""
|
|
||||||
r = requests.get(f"{base_url}/api/buildings/{building_id}.json")
|
r = requests.get(f"{base_url}/api/buildings/{building_id}.json")
|
||||||
return r.status_code, r.json()
|
return r.status_code, r.json()
|
||||||
|
|
||||||
|
|
||||||
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
||||||
def update_building(building_id, data, api_key, base_url):
|
def update_building(building_id, data, api_key, base_url):
|
||||||
"""Save data to a building
|
"""Save data to a building"""
|
||||||
"""
|
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
"{}/api/buildings/{}.json".format(base_url, building_id),
|
"{}/api/buildings/{}.json".format(base_url, building_id),
|
||||||
params={'api_key': api_key},
|
params={"api_key": api_key},
|
||||||
json=data
|
json=data,
|
||||||
)
|
)
|
||||||
return r.status_code, r.json()
|
return r.status_code, r.json()
|
||||||
|
|
||||||
|
|
||||||
def find_building(data, base_url):
|
def find_building(data, base_url):
|
||||||
if 'building_id' in data:
|
if "building_id" in data:
|
||||||
building_id = data['building_id']
|
building_id = data["building_id"]
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_building_id", building_id)
|
print("match_by_building_id", building_id)
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
if 'toid' in data:
|
if "toid" in data:
|
||||||
building_id = find_by_reference(base_url, 'toid', data['toid'])
|
building_id = find_by_reference(base_url, "toid", data["toid"])
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_toid", data['toid'], building_id)
|
print("match_by_toid", data["toid"], building_id)
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
if 'uprn' in data:
|
if "uprn" in data:
|
||||||
building_id = find_by_reference(base_url, 'uprn', data['uprn'])
|
building_id = find_by_reference(base_url, "uprn", data["uprn"])
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_uprn", data['uprn'], building_id)
|
print("match_by_uprn", data["uprn"], building_id)
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
print("no_match", data)
|
print("no_match", data)
|
||||||
@ -144,21 +149,21 @@ def find_building(data, base_url):
|
|||||||
|
|
||||||
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
|
||||||
def find_by_reference(base_url, ref_key, ref_id):
|
def find_by_reference(base_url, ref_key, ref_id):
|
||||||
"""Find building_id by TOID or UPRN
|
"""Find building_id by TOID or UPRN"""
|
||||||
"""
|
r = requests.get(
|
||||||
r = requests.get("{}/api/buildings/reference".format(base_url), params={
|
"{}/api/buildings/reference".format(base_url),
|
||||||
'key': ref_key,
|
params={"key": ref_key, "id": ref_id},
|
||||||
'id': ref_id
|
)
|
||||||
})
|
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
|
|
||||||
if buildings and 'error' not in buildings and len(buildings) == 1:
|
if buildings and "error" not in buildings and len(buildings) == 1:
|
||||||
building_id = buildings[0]['building_id']
|
building_id = buildings[0]["building_id"]
|
||||||
else:
|
else:
|
||||||
building_id = None
|
building_id = None
|
||||||
|
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
|
|
||||||
def parse_json_columns(row, json_columns):
|
def parse_json_columns(row, json_columns):
|
||||||
for col in json_columns:
|
for col in json_columns:
|
||||||
row[col] = json.loads(row[col])
|
row[col] = json.loads(row[col])
|
||||||
@ -167,28 +172,41 @@ def parse_json_columns(row, json_columns):
|
|||||||
|
|
||||||
|
|
||||||
def list_str(values):
|
def list_str(values):
|
||||||
return values.split(',')
|
return values.split(",")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('url', help='URL for the app')
|
parser.add_argument("url", help="URL for the app")
|
||||||
parser.add_argument('api_key', help='API key for the user')
|
parser.add_argument("api_key", help="API key for the user")
|
||||||
parser.add_argument('path', help='Path to data CSV file')
|
parser.add_argument("path", help="Path to data CSV file")
|
||||||
parser.add_argument('json_columns',
|
parser.add_argument(
|
||||||
nargs='?',
|
"json_columns",
|
||||||
|
nargs="?",
|
||||||
type=list_str,
|
type=list_str,
|
||||||
default=[],
|
default=[],
|
||||||
help='A comma-separated list of columns which should be parsed as JSON')
|
help="A comma-separated list of columns which should be parsed as JSON",
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument('--no-overwrite', '-n',
|
parser.add_argument(
|
||||||
action='store_true',
|
"--no-overwrite",
|
||||||
dest='no_overwrite',
|
"-n",
|
||||||
help='Don\'t overwrite building data if any of the fields supplied is already set')
|
action="store_true",
|
||||||
|
dest="no_overwrite",
|
||||||
|
help="Don't overwrite building data if any of the fields supplied is already set",
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument('--debug', '-d',
|
parser.add_argument(
|
||||||
action='store_true',
|
"--debug", "-d", action="store_true", help="Print debug messages"
|
||||||
help='Print debug messages')
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
main(args.url, args.api_key, args.path, args.json_columns, args.no_overwrite, args.debug)
|
main(
|
||||||
|
args.url,
|
||||||
|
args.api_key,
|
||||||
|
args.path,
|
||||||
|
args.json_columns,
|
||||||
|
args.no_overwrite,
|
||||||
|
args.debug,
|
||||||
|
)
|
||||||
|
@ -23,18 +23,18 @@ The process:
|
|||||||
TODO extend to allow latitude,longitude or easting,northing columns and lookup by location.
|
TODO extend to allow latitude,longitude or easting,northing columns and lookup by location.
|
||||||
"""
|
"""
|
||||||
import csv
|
import csv
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.verify = False
|
session.verify = False
|
||||||
|
|
||||||
|
|
||||||
def main(base_url, api_key, source_file):
|
def main(base_url, api_key, source_file):
|
||||||
"""Read from file, update buildings
|
"""Read from file, update buildings"""
|
||||||
"""
|
with open(source_file, "r") as source:
|
||||||
with open(source_file, 'r') as source:
|
|
||||||
reader = csv.DictReader(source)
|
reader = csv.DictReader(source)
|
||||||
for line in reader:
|
for line in reader:
|
||||||
building_id = find_building(line, base_url)
|
building_id = find_building(line, base_url)
|
||||||
@ -42,40 +42,41 @@ def main(base_url, api_key, source_file):
|
|||||||
if building_id is None:
|
if building_id is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
response_code, response_data = update_building(building_id, line, api_key, base_url)
|
response_code, response_data = update_building(
|
||||||
|
building_id, line, api_key, base_url
|
||||||
|
)
|
||||||
if response_code != 200:
|
if response_code != 200:
|
||||||
print('ERROR', building_id, response_code, response_data)
|
print("ERROR", building_id, response_code, response_data)
|
||||||
|
|
||||||
|
|
||||||
def update_building(building_id, data, api_key, base_url):
|
def update_building(building_id, data, api_key, base_url):
|
||||||
"""Save data to a building
|
"""Save data to a building"""
|
||||||
"""
|
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
"{}/api/buildings/{}.json".format(base_url, building_id),
|
"{}/api/buildings/{}.json".format(base_url, building_id),
|
||||||
params={'api_key': api_key},
|
params={"api_key": api_key},
|
||||||
json=data,
|
json=data,
|
||||||
verify=False
|
verify=False,
|
||||||
)
|
)
|
||||||
print(r)
|
print(r)
|
||||||
return r.status_code, r.json()
|
return r.status_code, r.json()
|
||||||
|
|
||||||
|
|
||||||
def find_building(data, base_url):
|
def find_building(data, base_url):
|
||||||
if 'building_id' in data:
|
if "building_id" in data:
|
||||||
building_id = data['building_id']
|
building_id = data["building_id"]
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_building_id", building_id)
|
print("match_by_building_id", building_id)
|
||||||
return building_id
|
return building_id
|
||||||
if 'toid' in data:
|
if "toid" in data:
|
||||||
building_id = find_by_reference(base_url, 'toid', data['toid'])
|
building_id = find_by_reference(base_url, "toid", data["toid"])
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_toid", data['toid'], building_id)
|
print("match_by_toid", data["toid"], building_id)
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
if 'uprn' in data:
|
if "uprn" in data:
|
||||||
building_id = find_by_reference(base_url, 'uprn', data['uprn'])
|
building_id = find_by_reference(base_url, "uprn", data["uprn"])
|
||||||
if building_id is not None:
|
if building_id is not None:
|
||||||
print("match_by_uprn", data['uprn'], building_id)
|
print("match_by_uprn", data["uprn"], building_id)
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
print("no_match", data)
|
print("no_match", data)
|
||||||
@ -83,32 +84,34 @@ def find_building(data, base_url):
|
|||||||
|
|
||||||
|
|
||||||
def find_by_reference(base_url, ref_key, ref_id):
|
def find_by_reference(base_url, ref_key, ref_id):
|
||||||
"""Find building_id by TOID or UPRN
|
"""Find building_id by TOID or UPRN"""
|
||||||
"""
|
r = requests.get(
|
||||||
r = requests.get("{}/api/buildings/reference".format(base_url), params={
|
"{}/api/buildings/reference".format(base_url),
|
||||||
'key': ref_key,
|
params={
|
||||||
'id': ref_id,
|
"key": ref_key,
|
||||||
|
"id": ref_id,
|
||||||
},
|
},
|
||||||
verify=False
|
verify=False,
|
||||||
)
|
)
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
|
|
||||||
if buildings and 'error' not in buildings and len(buildings) == 1:
|
if buildings and "error" not in buildings and len(buildings) == 1:
|
||||||
building_id = buildings[0]['building_id']
|
building_id = buildings[0]["building_id"]
|
||||||
else:
|
else:
|
||||||
building_id = None
|
building_id = None
|
||||||
|
|
||||||
return building_id
|
return building_id
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
url, api_key, filename = sys.argv[1], sys.argv[2], sys.argv[3]
|
url, api_key, filename = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print(
|
print(
|
||||||
"Usage: {} <URL> <api_key> ./path/to/data.csv".format(
|
"Usage: {} <URL> <api_key> ./path/to/data.csv".format(
|
||||||
os.path.basename(__file__)
|
os.path.basename(__file__)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
main(url, api_key, filename)
|
main(url, api_key, filename)
|
||||||
|
@ -8,7 +8,6 @@ datasets for Camden (age data) and Fitzrovia (number of storeys).
|
|||||||
- else locate building by representative point
|
- else locate building by representative point
|
||||||
- update building with data
|
- update building with data
|
||||||
"""
|
"""
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -21,18 +20,15 @@ from shapely.ops import transform
|
|||||||
|
|
||||||
|
|
||||||
osgb_to_ll = partial(
|
osgb_to_ll = partial(
|
||||||
pyproj.transform,
|
pyproj.transform, pyproj.Proj(init="epsg:27700"), pyproj.Proj(init="epsg:4326")
|
||||||
pyproj.Proj(init='epsg:27700'),
|
|
||||||
pyproj.Proj(init='epsg:4326')
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def main(base_url, api_key, process, source_file):
|
def main(base_url, api_key, process, source_file):
|
||||||
"""Read from file, update buildings
|
"""Read from file, update buildings"""
|
||||||
"""
|
with fiona.open(source_file, "r") as source:
|
||||||
with fiona.open(source_file, 'r') as source:
|
|
||||||
for feature in source:
|
for feature in source:
|
||||||
props = feature['properties']
|
props = feature["properties"]
|
||||||
|
|
||||||
if process == "camden":
|
if process == "camden":
|
||||||
toid, data = process_camden(props)
|
toid, data = process_camden(props)
|
||||||
@ -42,7 +38,7 @@ def main(base_url, api_key, process, source_file):
|
|||||||
if data is None:
|
if data is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
building_id = find_building(toid, feature['geometry'], base_url)
|
building_id = find_building(toid, feature["geometry"], base_url)
|
||||||
if not building_id:
|
if not building_id:
|
||||||
print("no_match", toid, "-")
|
print("no_match", toid, "-")
|
||||||
continue
|
continue
|
||||||
@ -51,31 +47,22 @@ def main(base_url, api_key, process, source_file):
|
|||||||
|
|
||||||
|
|
||||||
def process_camden(props):
|
def process_camden(props):
|
||||||
toid = osgb_toid(props['TOID'])
|
toid = osgb_toid(props["TOID"])
|
||||||
data = {
|
data = {"date_year": props["Year_C"], "date_source_detail": props["Date_sou_1"]}
|
||||||
'date_year': props['Year_C'],
|
|
||||||
'date_source_detail': props['Date_sou_1']
|
|
||||||
}
|
|
||||||
return toid, data
|
return toid, data
|
||||||
|
|
||||||
|
|
||||||
def process_fitzrovia(props):
|
def process_fitzrovia(props):
|
||||||
toid = osgb_toid(props['TOID'])
|
toid = osgb_toid(props["TOID"])
|
||||||
storeys = props['Storeys']
|
storeys = props["Storeys"]
|
||||||
|
|
||||||
if storeys is None:
|
if storeys is None:
|
||||||
return toid, None
|
return toid, None
|
||||||
|
|
||||||
if props['Basement'] == 'Yes':
|
if props["Basement"] == "Yes":
|
||||||
data = {
|
data = {"size_storeys_core": int(storeys) - 1, "size_storeys_basement": 1}
|
||||||
'size_storeys_core': int(storeys) - 1,
|
|
||||||
'size_storeys_basement': 1
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
data = {
|
data = {"size_storeys_core": int(storeys), "size_storeys_basement": 0}
|
||||||
'size_storeys_core': int(storeys),
|
|
||||||
'size_storeys_basement': 0
|
|
||||||
}
|
|
||||||
return toid, data
|
return toid, data
|
||||||
|
|
||||||
|
|
||||||
@ -86,24 +73,21 @@ def osgb_toid(toid):
|
|||||||
|
|
||||||
|
|
||||||
def save_data(building_id, data, api_key, base_url):
|
def save_data(building_id, data, api_key, base_url):
|
||||||
"""Save data to a building
|
"""Save data to a building"""
|
||||||
"""
|
requests.post(
|
||||||
r = requests.post(
|
|
||||||
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
||||||
json=data
|
json=data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def find_building(toid, geom, base_url):
|
def find_building(toid, geom, base_url):
|
||||||
"""Find building_id by TOID or location
|
"""Find building_id by TOID or location"""
|
||||||
"""
|
r = requests.get(
|
||||||
r = requests.get(base_url + "/buildings/reference", params={
|
base_url + "/buildings/reference", params={"key": "toid", "id": toid}
|
||||||
'key': 'toid',
|
)
|
||||||
'id': toid
|
|
||||||
})
|
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
if buildings and len(buildings) == 1:
|
if buildings and len(buildings) == 1:
|
||||||
bid = buildings[0]['building_id']
|
bid = buildings[0]["building_id"]
|
||||||
print("match_by_toid", toid, bid)
|
print("match_by_toid", toid, bid)
|
||||||
return bid
|
return bid
|
||||||
|
|
||||||
@ -114,27 +98,32 @@ def find_building(toid, geom, base_url):
|
|||||||
point_osgb = poly.representative_point()
|
point_osgb = poly.representative_point()
|
||||||
|
|
||||||
point_ll = transform(osgb_to_ll, point_osgb)
|
point_ll = transform(osgb_to_ll, point_osgb)
|
||||||
r = requests.get(base_url + "/buildings/locate", params={
|
r = requests.get(
|
||||||
'lng': point_ll.x,
|
base_url + "/buildings/locate", params={"lng": point_ll.x, "lat": point_ll.y}
|
||||||
'lat': point_ll.y
|
)
|
||||||
})
|
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
if buildings and len(buildings) == 1:
|
if buildings and len(buildings) == 1:
|
||||||
bid = buildings[0]['building_id']
|
bid = buildings[0]["building_id"]
|
||||||
print("match_by_location", toid, bid)
|
print("match_by_location", toid, bid)
|
||||||
return bid
|
return bid
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
url, api_key, process, filename = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
|
url, api_key, process, filename = (
|
||||||
|
sys.argv[1],
|
||||||
|
sys.argv[2],
|
||||||
|
sys.argv[3],
|
||||||
|
sys.argv[4],
|
||||||
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print(
|
print(
|
||||||
"Usage: {} <URL> <api_key> <camden|fitzrovia> ./path/to/camden.shp".format(
|
"Usage: {} <URL> <api_key> <camden|fitzrovia> ./path/to/camden.shp".format(
|
||||||
os.path.basename(__file__)
|
os.path.basename(__file__)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
main(url, api_key, process, filename)
|
main(url, api_key, process, filename)
|
||||||
|
@ -8,7 +8,6 @@ datasets for Camden (age data) and Fitzrovia (number of storeys).
|
|||||||
- else locate building by representative point
|
- else locate building by representative point
|
||||||
- update building with data
|
- update building with data
|
||||||
"""
|
"""
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -21,18 +20,15 @@ from shapely.ops import transform
|
|||||||
|
|
||||||
|
|
||||||
osgb_to_ll = partial(
|
osgb_to_ll = partial(
|
||||||
pyproj.transform,
|
pyproj.transform, pyproj.Proj(init="epsg:27700"), pyproj.Proj(init="epsg:4326")
|
||||||
pyproj.Proj(init='epsg:27700'),
|
|
||||||
pyproj.Proj(init='epsg:4326')
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def main(base_url, api_key, process, source_file):
|
def main(base_url, api_key, process, source_file):
|
||||||
"""Read from file, update buildings
|
"""Read from file, update buildings"""
|
||||||
"""
|
with fiona.open(source_file, "r") as source:
|
||||||
with fiona.open(source_file, 'r') as source:
|
|
||||||
for feature in source:
|
for feature in source:
|
||||||
props = feature['properties']
|
props = feature["properties"]
|
||||||
|
|
||||||
if process == "camden":
|
if process == "camden":
|
||||||
toid, data = process_camden(props)
|
toid, data = process_camden(props)
|
||||||
@ -42,7 +38,7 @@ def main(base_url, api_key, process, source_file):
|
|||||||
if data is None:
|
if data is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
building_id = find_building(toid, feature['geometry'], base_url)
|
building_id = find_building(toid, feature["geometry"], base_url)
|
||||||
if not building_id:
|
if not building_id:
|
||||||
print("no_match", toid, "-")
|
print("no_match", toid, "-")
|
||||||
continue
|
continue
|
||||||
@ -51,31 +47,22 @@ def main(base_url, api_key, process, source_file):
|
|||||||
|
|
||||||
|
|
||||||
def process_camden(props):
|
def process_camden(props):
|
||||||
toid = osgb_toid(props['TOID'])
|
toid = osgb_toid(props["TOID"])
|
||||||
data = {
|
data = {"date_year": props["Year_C"], "date_source_detail": props["Date_sou_1"]}
|
||||||
'date_year': props['Year_C'],
|
|
||||||
'date_source_detail': props['Date_sou_1']
|
|
||||||
}
|
|
||||||
return toid, data
|
return toid, data
|
||||||
|
|
||||||
|
|
||||||
def process_fitzrovia(props):
|
def process_fitzrovia(props):
|
||||||
toid = osgb_toid(props['TOID'])
|
toid = osgb_toid(props["TOID"])
|
||||||
storeys = props['Storeys']
|
storeys = props["Storeys"]
|
||||||
|
|
||||||
if storeys is None:
|
if storeys is None:
|
||||||
return toid, None
|
return toid, None
|
||||||
|
|
||||||
if props['Basement'] == 'Yes':
|
if props["Basement"] == "Yes":
|
||||||
data = {
|
data = {"size_storeys_core": int(storeys) - 1, "size_storeys_basement": 1}
|
||||||
'size_storeys_core': int(storeys) - 1,
|
|
||||||
'size_storeys_basement': 1
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
data = {
|
data = {"size_storeys_core": int(storeys), "size_storeys_basement": 0}
|
||||||
'size_storeys_core': int(storeys),
|
|
||||||
'size_storeys_basement': 0
|
|
||||||
}
|
|
||||||
return toid, data
|
return toid, data
|
||||||
|
|
||||||
|
|
||||||
@ -86,24 +73,21 @@ def osgb_toid(toid):
|
|||||||
|
|
||||||
|
|
||||||
def save_data(building_id, data, api_key, base_url):
|
def save_data(building_id, data, api_key, base_url):
|
||||||
"""Save data to a building
|
"""Save data to a building"""
|
||||||
"""
|
requests.post(
|
||||||
r = requests.post(
|
|
||||||
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
"{}/buildings/{}.json?api_key={}".format(base_url, building_id, api_key),
|
||||||
json=data
|
json=data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def find_building(toid, geom, base_url):
|
def find_building(toid, geom, base_url):
|
||||||
"""Find building_id by TOID or location
|
"""Find building_id by TOID or location"""
|
||||||
"""
|
r = requests.get(
|
||||||
r = requests.get(base_url + "/buildings/reference", params={
|
base_url + "/buildings/reference", params={"key": "toid", "id": toid}
|
||||||
'key': 'toid',
|
)
|
||||||
'id': toid
|
|
||||||
})
|
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
if buildings and len(buildings) == 1:
|
if buildings and len(buildings) == 1:
|
||||||
bid = buildings[0]['building_id']
|
bid = buildings[0]["building_id"]
|
||||||
print("match_by_toid", toid, bid)
|
print("match_by_toid", toid, bid)
|
||||||
return bid
|
return bid
|
||||||
|
|
||||||
@ -114,27 +98,32 @@ def find_building(toid, geom, base_url):
|
|||||||
point_osgb = poly.representative_point()
|
point_osgb = poly.representative_point()
|
||||||
|
|
||||||
point_ll = transform(osgb_to_ll, point_osgb)
|
point_ll = transform(osgb_to_ll, point_osgb)
|
||||||
r = requests.get(base_url + "/buildings/locate", params={
|
r = requests.get(
|
||||||
'lng': point_ll.x,
|
base_url + "/buildings/locate", params={"lng": point_ll.x, "lat": point_ll.y}
|
||||||
'lat': point_ll.y
|
)
|
||||||
})
|
|
||||||
buildings = r.json()
|
buildings = r.json()
|
||||||
if buildings and len(buildings) == 1:
|
if buildings and len(buildings) == 1:
|
||||||
bid = buildings[0]['building_id']
|
bid = buildings[0]["building_id"]
|
||||||
print("match_by_location", toid, bid)
|
print("match_by_location", toid, bid)
|
||||||
return bid
|
return bid
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
url, api_key, process, filename = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
|
url, api_key, process, filename = (
|
||||||
|
sys.argv[1],
|
||||||
|
sys.argv[2],
|
||||||
|
sys.argv[3],
|
||||||
|
sys.argv[4],
|
||||||
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print(
|
print(
|
||||||
"Usage: {} <URL> <api_key> <camden|fitzrovia> ./path/to/camden.shp".format(
|
"Usage: {} <URL> <api_key> <camden|fitzrovia> ./path/to/camden.shp".format(
|
||||||
os.path.basename(__file__)
|
os.path.basename(__file__)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
main(url, api_key, process, filename)
|
main(url, api_key, process, filename)
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
def planning_data_entry_to_address(element):
|
def planning_data_entry_to_address(element):
|
||||||
site_name = element["_source"].get("site_name")
|
site_name = element["_source"].get("site_name")
|
||||||
site_number = element["_source"].get("site_number")
|
site_number = element["_source"].get("site_number")
|
||||||
street_name = element["_source"].get("street_name") # seems often misused - say "31 COPTHALL ROAD EAST" site_name getting Ickenham street_name
|
street_name = element["_source"].get("street_name")
|
||||||
|
# seems often misused - say "31 COPTHALL ROAD EAST" site_name
|
||||||
|
# getting Ickenham street_name
|
||||||
secondary_street_name = element["_source"].get("secondary_street_name")
|
secondary_street_name = element["_source"].get("secondary_street_name")
|
||||||
return generate_address(site_name, site_number, street_name, secondary_street_name)['result']
|
return generate_address(site_name, site_number, street_name, secondary_street_name)[
|
||||||
|
"result"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def generate_address(site_name, site_number, street_name, secondary_street_name):
|
def generate_address(site_name, site_number, street_name, secondary_street_name):
|
||||||
"""
|
"""
|
||||||
@ -11,13 +16,13 @@ def generate_address(site_name, site_number, street_name, secondary_street_name)
|
|||||||
sadly it does not always works well and relies on many heursitics as data quality is limited
|
sadly it does not always works well and relies on many heursitics as data quality is limited
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if site_name != None:
|
if site_name is not None:
|
||||||
site_name = site_name.strip()
|
site_name = site_name.strip()
|
||||||
if site_number != None:
|
if site_number is not None:
|
||||||
site_number = site_number.strip()
|
site_number = site_number.strip()
|
||||||
if street_name != None:
|
if street_name is not None:
|
||||||
street_name = street_name.strip()
|
street_name = street_name.strip()
|
||||||
if secondary_street_name != None:
|
if secondary_street_name is not None:
|
||||||
secondary_street_name = secondary_street_name.strip()
|
secondary_street_name = secondary_street_name.strip()
|
||||||
|
|
||||||
if site_name == "":
|
if site_name == "":
|
||||||
@ -29,68 +34,80 @@ def generate_address(site_name, site_number, street_name, secondary_street_name)
|
|||||||
if secondary_street_name == "":
|
if secondary_street_name == "":
|
||||||
secondary_street_name = None
|
secondary_street_name = None
|
||||||
data = {
|
data = {
|
||||||
'site_name': site_name,
|
"site_name": site_name,
|
||||||
'site_number': site_number,
|
"site_number": site_number,
|
||||||
'street_name': street_name,
|
"street_name": street_name,
|
||||||
'secondary_street_name': secondary_street_name,
|
"secondary_street_name": secondary_street_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if site_name == site_number == street_name == secondary_street_name == None:
|
if site_name == site_number == street_name == secondary_street_name is None:
|
||||||
return {'result': None, 'data': data}
|
return {"result": None, "data": data}
|
||||||
|
|
||||||
if secondary_street_name != None:
|
if secondary_street_name is not None:
|
||||||
if street_name == None:
|
if street_name is None:
|
||||||
print('"secondary_street_name != None, street_name == None"')
|
print('"secondary_street_name is not None, street_name is None"')
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, "???????")
|
show_data(
|
||||||
|
site_name, site_number, street_name, secondary_street_name, "???????"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
street_name += " - with secondary road name: " + secondary_street_name
|
street_name += " - with secondary road name: " + secondary_street_name
|
||||||
|
|
||||||
if site_number != None and street_name != None:
|
if site_number is not None and street_name is not None:
|
||||||
address = site_number + " " + street_name
|
address = site_number + " " + street_name
|
||||||
if site_name != None:
|
if site_name is not None:
|
||||||
print('"site_name != None and site_number != None and street_name != None"')
|
print(
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, address)
|
'"site_name is not None and site_number is not None and street_name is not None"'
|
||||||
|
)
|
||||||
|
show_data(
|
||||||
|
site_name, site_number, street_name, secondary_street_name, address
|
||||||
|
)
|
||||||
|
|
||||||
return {'result': address, 'data': data}
|
return {"result": address, "data": data}
|
||||||
|
|
||||||
if site_name != None:
|
if site_name is not None:
|
||||||
if street_name != None:
|
if street_name is not None:
|
||||||
try:
|
try:
|
||||||
if site_number == None and int(site_name):
|
if site_number is None and int(site_name):
|
||||||
return {'result': site_name + " " + street_name, 'data': data}
|
return {"result": site_name + " " + street_name, "data": data}
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if street_name in site_name:
|
if street_name in site_name:
|
||||||
site_name_without_street_name = site_name.replace(street_name, "").strip()
|
site_name_without_street_name = site_name.replace(
|
||||||
|
street_name, ""
|
||||||
|
).strip()
|
||||||
try:
|
try:
|
||||||
house_number = int(site_name_without_street_name)
|
_ = int(site_name_without_street_name)
|
||||||
# so it appears to be case like
|
# so it appears to be case like
|
||||||
# site_name: 5 Warwick Road
|
# site_name: 5 Warwick Road
|
||||||
# street_name: Warwick Road
|
# street_name: Warwick Road
|
||||||
# no other info provided
|
# no other info provided
|
||||||
# in such case just returning site_name will work fine...
|
# in such case just returning site_name will work fine...
|
||||||
return {'result': site_name, 'data': data}
|
return {"result": site_name, "data": data}
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
print('"site_name != None and street_name != None"')
|
print('"site_name is not None and street_name is not None"')
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, site_name)
|
show_data(
|
||||||
if site_number != None:
|
site_name, site_number, street_name, secondary_street_name, site_name
|
||||||
print('"site_name != None and site_number != None"')
|
)
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, site_name)
|
if site_number is not None:
|
||||||
return {'result': site_name, 'data': data}
|
print('"site_name is not None and site_number is not None"')
|
||||||
|
show_data(
|
||||||
|
site_name, site_number, street_name, secondary_street_name, site_name
|
||||||
|
)
|
||||||
|
return {"result": site_name, "data": data}
|
||||||
else:
|
else:
|
||||||
if street_name != None:
|
if street_name is not None:
|
||||||
if site_number != None:
|
if site_number is not None:
|
||||||
return {'result': site_number + " " + street_name, 'data': data}
|
return {"result": site_number + " " + street_name, "data": data}
|
||||||
if street_name != None and site_number == None:
|
if street_name is not None and site_number is None:
|
||||||
print('"street_name != None or site_number == None"')
|
print('"street_name is not None or site_number is None"')
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, None)
|
show_data(site_name, site_number, street_name, secondary_street_name, None)
|
||||||
return {'result': None, 'data': data}
|
return {"result": None, "data": data}
|
||||||
if street_name == None and site_number != None:
|
if street_name is None and site_number is not None:
|
||||||
print('"street_name == None or site_number != None"')
|
print('"street_name is None or site_number is not None"')
|
||||||
show_data(site_name, site_number, street_name, secondary_street_name, None)
|
show_data(site_name, site_number, street_name, secondary_street_name, None)
|
||||||
return {'result': None, 'data': data}
|
return {"result": None, "data": data}
|
||||||
return {'result': None, 'data': data}
|
return {"result": None, "data": data}
|
||||||
|
|
||||||
|
|
||||||
def show_data(site_name, site_number, street_name, secondary_street_name, address):
|
def show_data(site_name, site_number, street_name, secondary_street_name, address):
|
||||||
|
@ -5,6 +5,7 @@ import requests
|
|||||||
import psycopg2
|
import psycopg2
|
||||||
import address_data
|
import address_data
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
connection = get_connection()
|
connection = get_connection()
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
@ -16,10 +17,12 @@ def main():
|
|||||||
while True:
|
while True:
|
||||||
data = query(search_after).json()
|
data = query(search_after).json()
|
||||||
load_data_into_database(cursor, data)
|
load_data_into_database(cursor, data)
|
||||||
for entry in data['hits']['hits']:
|
for entry in data["hits"]["hits"]:
|
||||||
downloaded += 1
|
downloaded += 1
|
||||||
last_sort = entry['sort']
|
last_sort = entry["sort"]
|
||||||
print("downloaded", downloaded, "last_sort", last_sort, "previous", search_after)
|
print(
|
||||||
|
"downloaded", downloaded, "last_sort", last_sort, "previous", search_after
|
||||||
|
)
|
||||||
if search_after == last_sort:
|
if search_after == last_sort:
|
||||||
break
|
break
|
||||||
search_after = last_sort
|
search_after = last_sort
|
||||||
@ -31,24 +34,30 @@ def load_data_into_database(cursor, data):
|
|||||||
print(json.dumps(data, indent=4))
|
print(json.dumps(data, indent=4))
|
||||||
print("timed_out field missing in provided data")
|
print("timed_out field missing in provided data")
|
||||||
else:
|
else:
|
||||||
if data['timed_out']:
|
if data["timed_out"]:
|
||||||
raise Exception("query getting livestream data has failed")
|
raise Exception("query getting livestream data has failed")
|
||||||
for entry in data['hits']['hits']:
|
for entry in data["hits"]["hits"]:
|
||||||
try:
|
try:
|
||||||
description = None
|
description = None
|
||||||
if entry['_source']['description'] != None:
|
if entry["_source"]["description"] is not None:
|
||||||
description = entry['_source']['description'].strip()
|
description = entry["_source"]["description"].strip()
|
||||||
application_id = entry['_source']['lpa_app_no']
|
application_id = entry["_source"]["lpa_app_no"]
|
||||||
application_id_with_borough_identifier = entry['_source']['id']
|
application_id_with_borough_identifier = entry["_source"]["id"]
|
||||||
decision_date = parse_date_string_into_date_object(entry['_source']['decision_date'])
|
decision_date = parse_date_string_into_date_object(
|
||||||
last_synced_date = parse_date_string_into_date_object(entry['_source']['last_synced'])
|
entry["_source"]["decision_date"]
|
||||||
uprn = entry['_source']['uprn']
|
)
|
||||||
status_before_aliasing = entry['_source']['status']
|
last_synced_date = parse_date_string_into_date_object(
|
||||||
|
entry["_source"]["last_synced"]
|
||||||
|
)
|
||||||
|
uprn = entry["_source"]["uprn"]
|
||||||
|
status_before_aliasing = entry["_source"]["status"]
|
||||||
status_info = process_status(status_before_aliasing, decision_date)
|
status_info = process_status(status_before_aliasing, decision_date)
|
||||||
status = status_info["status"]
|
status = status_info["status"]
|
||||||
status_explanation_note = status_info["status_explanation_note"]
|
status_explanation_note = status_info["status_explanation_note"]
|
||||||
planning_url = obtain_entry_link(entry['_source']['url_planning_app'], application_id)
|
planning_url = obtain_entry_link(
|
||||||
if uprn == None:
|
entry["_source"]["url_planning_app"], application_id
|
||||||
|
)
|
||||||
|
if uprn is None:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
uprn = int(uprn)
|
uprn = int(uprn)
|
||||||
@ -61,7 +70,9 @@ def load_data_into_database(cursor, data):
|
|||||||
"last_synced_date": last_synced_date,
|
"last_synced_date": last_synced_date,
|
||||||
"application_id": application_id,
|
"application_id": application_id,
|
||||||
"application_url": planning_url,
|
"application_url": planning_url,
|
||||||
"registered_with_local_authority_date": parse_date_string_into_date_object(entry['_source']['valid_date']),
|
"registered_with_local_authority_date": parse_date_string_into_date_object(
|
||||||
|
entry["_source"]["valid_date"]
|
||||||
|
),
|
||||||
"uprn": uprn,
|
"uprn": uprn,
|
||||||
"status": status,
|
"status": status,
|
||||||
"status_before_aliasing": status_before_aliasing,
|
"status_before_aliasing": status_before_aliasing,
|
||||||
@ -70,13 +81,16 @@ def load_data_into_database(cursor, data):
|
|||||||
"data_source_link": "https://www.london.gov.uk/programmes-strategies/planning/digital-planning/planning-london-datahub",
|
"data_source_link": "https://www.london.gov.uk/programmes-strategies/planning/digital-planning/planning-london-datahub",
|
||||||
"address": address_data.planning_data_entry_to_address(entry),
|
"address": address_data.planning_data_entry_to_address(entry),
|
||||||
}
|
}
|
||||||
if entry["address"] != None:
|
if entry["address"] is not None:
|
||||||
maximum_address_length = 300
|
maximum_address_length = 300
|
||||||
if len(entry["address"]) > maximum_address_length:
|
if len(entry["address"]) > maximum_address_length:
|
||||||
print("address is too long, shortening", entry["address"])
|
print("address is too long, shortening", entry["address"])
|
||||||
entry["address"] = entry["address"][0:maximum_address_length]
|
entry["address"] = entry["address"][0:maximum_address_length]
|
||||||
if date_in_future(entry["registered_with_local_authority_date"]):
|
if date_in_future(entry["registered_with_local_authority_date"]):
|
||||||
print("registered_with_local_authority_date is treated as invalid:", entry["registered_with_local_authority_date"])
|
print(
|
||||||
|
"registered_with_local_authority_date is treated as invalid:",
|
||||||
|
entry["registered_with_local_authority_date"],
|
||||||
|
)
|
||||||
# Brent-87_0946 has "valid_date": "23/04/9187"
|
# Brent-87_0946 has "valid_date": "23/04/9187"
|
||||||
entry["registered_with_local_authority_date"] = None
|
entry["registered_with_local_authority_date"] = None
|
||||||
|
|
||||||
@ -85,13 +99,17 @@ def load_data_into_database(cursor, data):
|
|||||||
entry["decision_date"] = None
|
entry["decision_date"] = None
|
||||||
|
|
||||||
if date_in_future(entry["last_synced_date"]):
|
if date_in_future(entry["last_synced_date"]):
|
||||||
print("last_synced_date is treated as invalid:", entry["last_synced_date"])
|
print(
|
||||||
|
"last_synced_date is treated as invalid:", entry["last_synced_date"]
|
||||||
|
)
|
||||||
entry["last_synced_date"] = None
|
entry["last_synced_date"] = None
|
||||||
|
|
||||||
if "Hackney" in application_id_with_borough_identifier:
|
if "Hackney" in application_id_with_borough_identifier:
|
||||||
if entry["application_url"] != None:
|
if entry["application_url"] is not None:
|
||||||
if "https://" not in entry["application_url"]:
|
if "https://" not in entry["application_url"]:
|
||||||
entry["application_url"] = "https://developmentandhousing.hackney.gov.uk" + entry["application_url"]
|
entry[
|
||||||
|
"application_url"
|
||||||
|
] = f"https://developmentandhousing.hackney.gov.uk{entry['application_url']}"
|
||||||
insert_entry(cursor, entry)
|
insert_entry(cursor, entry)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
print()
|
print()
|
||||||
@ -104,40 +122,40 @@ def load_data_into_database(cursor, data):
|
|||||||
|
|
||||||
|
|
||||||
def date_in_future(date):
|
def date_in_future(date):
|
||||||
if date == None:
|
if date is None:
|
||||||
return False
|
return False
|
||||||
return date > datetime.datetime.now()
|
return date > datetime.datetime.now()
|
||||||
|
|
||||||
|
|
||||||
def query(search_after):
|
def query(search_after):
|
||||||
headers = {
|
headers = {
|
||||||
'X-API-AllowRequest': os.environ['PLANNNING_DATA_API_ALLOW_REQUEST_CODE'],
|
"X-API-AllowRequest": os.environ["PLANNNING_DATA_API_ALLOW_REQUEST_CODE"],
|
||||||
# Already added when you pass json= but not when you pass data=
|
# Already added when you pass json= but not when you pass data=
|
||||||
# 'Content-Type': 'application/json',
|
# 'Content-Type': 'application/json',
|
||||||
}
|
}
|
||||||
json_data = {
|
json_data = {
|
||||||
'size': 10000,
|
"size": 10000,
|
||||||
'sort': [
|
"sort": [
|
||||||
{
|
{
|
||||||
'last_updated': {
|
"last_updated": {
|
||||||
'order': 'desc',
|
"order": "desc",
|
||||||
'unmapped_type': 'boolean',
|
"unmapped_type": "boolean",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'stored_fields': [
|
"stored_fields": [
|
||||||
'*',
|
"*",
|
||||||
],
|
],
|
||||||
'_source': {
|
"_source": {
|
||||||
'excludes': [],
|
"excludes": [],
|
||||||
},
|
},
|
||||||
'query': {
|
"query": {
|
||||||
'bool': {
|
"bool": {
|
||||||
'must': [
|
"must": [
|
||||||
{
|
{
|
||||||
'range': {
|
"range": {
|
||||||
'valid_date': {
|
"valid_date": {
|
||||||
'gte': '01/01/1021',
|
"gte": "01/01/1021",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -147,18 +165,22 @@ def query(search_after):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if search_after != []:
|
if search_after != []:
|
||||||
json_data['search_after'] = search_after
|
json_data["search_after"] = search_after
|
||||||
|
|
||||||
print(json_data)
|
print(json_data)
|
||||||
return requests.post('https://planningdata.london.gov.uk/api-guest/applications/_search', headers=headers, json=json_data)
|
return requests.post(
|
||||||
|
"https://planningdata.london.gov.uk/api-guest/applications/_search",
|
||||||
|
headers=headers,
|
||||||
|
json=json_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_connection():
|
def get_connection():
|
||||||
return psycopg2.connect(
|
return psycopg2.connect(
|
||||||
host=os.environ['PGHOST'],
|
host=os.environ["PGHOST"],
|
||||||
dbname=os.environ['PGDATABASE'],
|
dbname=os.environ["PGDATABASE"],
|
||||||
user=os.environ['PGUSER'],
|
user=os.environ["PGUSER"],
|
||||||
password=os.environ['PGPASSWORD']
|
password=os.environ["PGPASSWORD"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -170,15 +192,18 @@ def insert_entry(cursor, e):
|
|||||||
try:
|
try:
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
application_url = None
|
application_url = None
|
||||||
if e["application_url"] != None:
|
if e["application_url"] is not None:
|
||||||
application_url = e["application_url"]
|
application_url = e["application_url"]
|
||||||
cursor.execute('''INSERT INTO
|
cursor.execute(
|
||||||
|
"""INSERT INTO
|
||||||
planning_data (planning_application_id, planning_application_link, description, registered_with_local_authority_date, days_since_registration_cached, decision_date, days_since_decision_date_cached, last_synced_date, status, status_before_aliasing, status_explanation_note, data_source, data_source_link, address, uprn)
|
planning_data (planning_application_id, planning_application_link, description, registered_with_local_authority_date, days_since_registration_cached, decision_date, days_since_decision_date_cached, last_synced_date, status, status_before_aliasing, status_explanation_note, data_source, data_source_link, address, uprn)
|
||||||
VALUES
|
VALUES
|
||||||
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
''', (
|
""",
|
||||||
|
(
|
||||||
e["application_id"],
|
e["application_id"],
|
||||||
application_url, e["description"],
|
application_url,
|
||||||
|
e["description"],
|
||||||
date_object_into_date_string(e["registered_with_local_authority_date"]),
|
date_object_into_date_string(e["registered_with_local_authority_date"]),
|
||||||
days_since(e["registered_with_local_authority_date"], now),
|
days_since(e["registered_with_local_authority_date"], now),
|
||||||
date_object_into_date_string(e["decision_date"]),
|
date_object_into_date_string(e["decision_date"]),
|
||||||
@ -191,7 +216,7 @@ def insert_entry(cursor, e):
|
|||||||
e["data_source_link"],
|
e["data_source_link"],
|
||||||
e["address"],
|
e["address"],
|
||||||
e["uprn"],
|
e["uprn"],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
except psycopg2.errors.Error as error:
|
except psycopg2.errors.Error as error:
|
||||||
show_dictionary(e)
|
show_dictionary(e)
|
||||||
@ -204,30 +229,32 @@ def show_dictionary(data):
|
|||||||
|
|
||||||
|
|
||||||
def days_since(date, now):
|
def days_since(date, now):
|
||||||
if(date == None):
|
if date is None:
|
||||||
return None
|
return None
|
||||||
return (now - date).days
|
return (now - date).days
|
||||||
|
|
||||||
|
|
||||||
def date_object_into_date_string(date):
|
def date_object_into_date_string(date):
|
||||||
if(date == None):
|
if date is None:
|
||||||
return None
|
return None
|
||||||
return datetime.datetime.strftime(date, "%Y-%m-%d")
|
return datetime.datetime.strftime(date, "%Y-%m-%d")
|
||||||
|
|
||||||
|
|
||||||
def parse_date_string_into_date_object(incoming):
|
def parse_date_string_into_date_object(incoming):
|
||||||
if incoming == None:
|
if incoming is None:
|
||||||
return None
|
return None
|
||||||
date = None
|
date = None
|
||||||
try:
|
try:
|
||||||
date = datetime.datetime.strptime(incoming, "%d/%m/%Y") # '21/07/2022'
|
date = datetime.datetime.strptime(incoming, "%d/%m/%Y") # '21/07/2022'
|
||||||
except ValueError:
|
except ValueError:
|
||||||
date = datetime.datetime.strptime(incoming, "%Y-%m-%dT%H:%M:%S.%fZ") # '2022-08-08T20:07:22.238Z'
|
date = datetime.datetime.strptime(
|
||||||
|
incoming, "%Y-%m-%dT%H:%M:%S.%fZ"
|
||||||
|
) # '2022-08-08T20:07:22.238Z'
|
||||||
return date
|
return date
|
||||||
|
|
||||||
|
|
||||||
def obtain_entry_link(provided_link, application_id):
|
def obtain_entry_link(provided_link, application_id):
|
||||||
if provided_link != None:
|
if provided_link is not None:
|
||||||
if "Ealing" in application_id:
|
if "Ealing" in application_id:
|
||||||
if ";" == provided_link[-1]:
|
if ";" == provided_link[-1]:
|
||||||
return provided_link[:-1]
|
return provided_link[:-1]
|
||||||
@ -237,7 +264,7 @@ def obtain_entry_link(provided_link, application_id):
|
|||||||
# Planning application ID: Hackney-2021_2491
|
# Planning application ID: Hackney-2021_2491
|
||||||
# https://developmentandhousing.hackney.gov.uk/planning/index.html?fa=getApplication&reference=2021/2491
|
# https://developmentandhousing.hackney.gov.uk/planning/index.html?fa=getApplication&reference=2021/2491
|
||||||
ref_for_link = application_id.replace("Hackney-", "").replace("_", "/")
|
ref_for_link = application_id.replace("Hackney-", "").replace("_", "/")
|
||||||
return "https://developmentandhousing.hackney.gov.uk/planning/index.html?fa=getApplication&reference=" + ref_for_link
|
return f"https://developmentandhousing.hackney.gov.uk/planning/index.html?fa=getApplication&reference={ref_for_link}"
|
||||||
if "Lambeth" in application_id:
|
if "Lambeth" in application_id:
|
||||||
# sadly, specific links seems impossible
|
# sadly, specific links seems impossible
|
||||||
return "https://planning.lambeth.gov.uk/online-applications/refineSearch.do?action=refine"
|
return "https://planning.lambeth.gov.uk/online-applications/refineSearch.do?action=refine"
|
||||||
@ -282,9 +309,16 @@ def obtain_entry_link(provided_link, application_id):
|
|||||||
def process_status(status, decision_date):
|
def process_status(status, decision_date):
|
||||||
status_length_limit = 50 # see migrations/034.planning_livestream_data.up.sql
|
status_length_limit = 50 # see migrations/034.planning_livestream_data.up.sql
|
||||||
if status in ["Application Under Consideration", "Application Received"]:
|
if status in ["Application Under Consideration", "Application Received"]:
|
||||||
if decision_date == None:
|
if decision_date is None:
|
||||||
status = "Submitted"
|
status = "Submitted"
|
||||||
if status in ["Refused", "Refusal", "Refusal (P)", "Application Invalid", "Insufficient Fee", "Dismissed"]:
|
if status in [
|
||||||
|
"Refused",
|
||||||
|
"Refusal",
|
||||||
|
"Refusal (P)",
|
||||||
|
"Application Invalid",
|
||||||
|
"Insufficient Fee",
|
||||||
|
"Dismissed",
|
||||||
|
]:
|
||||||
status = "Rejected"
|
status = "Rejected"
|
||||||
if status == "Appeal Received":
|
if status == "Appeal Received":
|
||||||
status = "Appeal In Progress"
|
status = "Appeal In Progress"
|
||||||
@ -296,16 +330,39 @@ def process_status(status, decision_date):
|
|||||||
status = "Withdrawn"
|
status = "Withdrawn"
|
||||||
if len(status) > status_length_limit:
|
if len(status) > status_length_limit:
|
||||||
print("Status was too long and was skipped:", status)
|
print("Status was too long and was skipped:", status)
|
||||||
return {"status": "Processing failed", "status_explanation_note": "status was unusally long and it was imposible to save it"}
|
return {
|
||||||
if (status in ["Submitted", "Approved", "Rejected", "Appeal In Progress", "Withdrawn", "Unknown"]):
|
"status": "Processing failed",
|
||||||
|
"status_explanation_note": "status was unusally long and it was imposible to save it",
|
||||||
|
}
|
||||||
|
if status in [
|
||||||
|
"Submitted",
|
||||||
|
"Approved",
|
||||||
|
"Rejected",
|
||||||
|
"Appeal In Progress",
|
||||||
|
"Withdrawn",
|
||||||
|
"Unknown",
|
||||||
|
]:
|
||||||
return {"status": status, "status_explanation_note": None}
|
return {"status": status, "status_explanation_note": None}
|
||||||
if status in ["No Objection to Proposal (OBS only)", "Objection Raised to Proposal (OBS only)"]:
|
if status in [
|
||||||
return {"status": "Approved", "status_explanation_note": "preapproved application, local authority is unable to reject it"}
|
"No Objection to Proposal (OBS only)",
|
||||||
|
"Objection Raised to Proposal (OBS only)",
|
||||||
|
]:
|
||||||
|
return {
|
||||||
|
"status": "Approved",
|
||||||
|
"status_explanation_note": "preapproved application, local authority is unable to reject it",
|
||||||
|
}
|
||||||
print("Unexpected status " + status)
|
print("Unexpected status " + status)
|
||||||
if status not in ["Not Required", "SECS", "Comment Issued", "ALL DECISIONS ISSUED", "Closed", "Declined to Determine"]:
|
if status not in [
|
||||||
|
"Not Required",
|
||||||
|
"SECS",
|
||||||
|
"Comment Issued",
|
||||||
|
"ALL DECISIONS ISSUED",
|
||||||
|
"Closed",
|
||||||
|
"Declined to Determine",
|
||||||
|
]:
|
||||||
print("New unexpected status " + status)
|
print("New unexpected status " + status)
|
||||||
return {"status": status, "status_explanation_note": None}
|
return {"status": status, "status_explanation_note": None}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# Python packages for planning data import
|
# Python packages for planning data import
|
||||||
psycopg2==2.8.6
|
psycopg2-binary==2.9.7
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Python packages for etl
|
# Python packages for etl
|
||||||
fiona==1.7.13
|
fiona
|
||||||
osmnx==0.13
|
osmnx==1.6.0
|
||||||
psycopg2==2.7.5
|
psycopg2-binary==2.9.7
|
||||||
shapely==1.7
|
|
||||||
retrying==1.3.3
|
retrying==1.3.3
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
shapely
|
||||||
|
@ -4,6 +4,7 @@ COPY (SELECT
|
|||||||
ref_osm_id,
|
ref_osm_id,
|
||||||
revision_id,
|
revision_id,
|
||||||
location_name,
|
location_name,
|
||||||
|
location_name_link,
|
||||||
location_number,
|
location_number,
|
||||||
location_street,
|
location_street,
|
||||||
location_line_two,
|
location_line_two,
|
||||||
@ -13,6 +14,7 @@ COPY (SELECT
|
|||||||
location_address_links,
|
location_address_links,
|
||||||
location_latitude,
|
location_latitude,
|
||||||
location_longitude,
|
location_longitude,
|
||||||
|
location_alternative_footprint_links
|
||||||
current_landuse_group,
|
current_landuse_group,
|
||||||
current_landuse_order,
|
current_landuse_order,
|
||||||
building_attachment_form,
|
building_attachment_form,
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
psycopg2==2.8.3
|
psycopg2-binary==2.9.7
|
||||||
requests==2.31.0
|
requests==2.31.0
|
34
migrations/041.ui_revamp_tweaks.down.sql
Normal file
34
migrations/041.ui_revamp_tweaks.down.sql
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS location_name_link;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS location_alternative_footprint_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS age_historical_raster_map_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS age_historical_vectorised_footprint_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS landowner_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS designers_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS builder_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS developer_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar_source_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_crowdsourced_site_completion_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_crowdsourced_site_completion_source_links;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_missing_data;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_missing_data_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS date_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS date_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_heritage_at_risk;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_world_heritage_site;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_local_list;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_in_conservation_area;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_in_apa;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_historic_area_assessment;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_scientific_interest;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_scientific_interest_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_scientific_interest_source_links;
|
34
migrations/041.ui_revamp_tweaks.up.sql
Normal file
34
migrations/041.ui_revamp_tweaks.up.sql
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS location_name_link text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS location_alternative_footprint_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS age_historical_raster_map_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS age_historical_vectorised_footprint_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS landowner_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS designers_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS builder_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS developer_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar_source_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_crowdsourced_site_completion_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_crowdsourced_site_completion_source_links text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_missing_data boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_missing_data_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS date_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS date_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_heritage_at_risk boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_world_heritage_site boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_local_list boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_in_conservation_area boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_in_apa boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_historic_area_assessment boolean;
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_scientific_interest boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_scientific_interest_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_scientific_interest_source_links text[];
|
14
migrations/042.ui_revamp_tweaks.refactor.sql
Normal file
14
migrations/042.ui_revamp_tweaks.refactor.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS context_front_garden;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS context_back_garden;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS context_flats_garden;
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_front_garden boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_back_garden boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_flats_garden boolean;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_crowdsourced_site_completion_status;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_crowdsourced_site_completion_status boolean;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS planning_crowdsourced_site_completion_year;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS planning_crowdsourced_site_completion_year smallint;
|
18
migrations/043.typology_updates.down.sql
Normal file
18
migrations/043.typology_updates.down.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_classification;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_classification_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_classification_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_style_period;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_style_period_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_style_period_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_dynamic_classification;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_dynamic_classification_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_dynamic_classification_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_original_use;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_original_use_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_original_use_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS building_attachment_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS building_attachment_source_links;
|
18
migrations/043.typology_updates_up.sql
Normal file
18
migrations/043.typology_updates_up.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_classification text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_classification_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_classification_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_style_period text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_style_period_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_style_period_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_dynamic_classification text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_dynamic_classification_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_dynamic_classification_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_original_use text[];
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_original_use_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_original_use_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS building_attachment_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS building_attachment_source_links text[];
|
38
migrations/044.construction_updates.down.sql
Normal file
38
migrations/044.construction_updates.down.sql
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_structural_system;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_structural_system_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_structural_system_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_foundation;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_foundation_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_foundation_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_roof_shape;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_roof_shape_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_roof_shape_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_irregularities;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_irregularities_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_irregularities_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_roof_covering_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_roof_covering_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_decorative_features;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_decorative_feature_materials;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_decorative_feature_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_decorative_feature_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_internal_wall;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_internal_wall_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_internal_wall_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_external_wall;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_external_wall_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_external_wall_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_ground_floor;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_ground_floor_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_ground_floor_source_links;
|
||||||
|
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_core_material_source_type;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS construction_core_material_source_links;
|
38
migrations/044.construction_updates.up.sql
Normal file
38
migrations/044.construction_updates.up.sql
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_structural_system text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_structural_system_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_structural_system_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_foundation text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_foundation_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_foundation_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_roof_shape text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_roof_shape_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_roof_shape_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_irregularities text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_irregularities_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_irregularities_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_roof_covering_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_roof_covering_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_decorative_features boolean;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_decorative_feature_materials text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_decorative_feature_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_decorative_feature_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_internal_wall text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_internal_wall_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_internal_wall_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_external_wall text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_external_wall_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_external_wall_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_ground_floor text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_ground_floor_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_ground_floor_source_links text[];
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_core_material_source_type text;
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS construction_core_material_source_links text[];
|
2
migrations/045.typology_changes.down.sql
Normal file
2
migrations/045.typology_changes.down.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE buildings DROP COLUMN IF EXISTS typology_original_use_order;
|
||||||
|
ALTER TABLE buildings DROP COLUMN IF NOT EXISTS typology_original_use_verified;
|
9
migrations/045.typology_changes.up.sql
Normal file
9
migrations/045.typology_changes.up.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_original_use_order text;
|
||||||
|
|
||||||
|
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS typology_original_use_verified BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
|
|
||||||
|
UPDATE buildings as b
|
||||||
|
SET typology_original_use_verified = TRUE
|
||||||
|
FROM building_verification as v
|
||||||
|
WHERE b.building_id = v.building_id
|
||||||
|
AND v.attribute = 'current_landuse_group';
|
Loading…
Reference in New Issue
Block a user