Merge branch 'develop' into feature/sort-imports
This commit is contained in:
commit
529d535b6d
@ -117,10 +117,12 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
|
|||||||
const baseLayer = <TileLayer
|
const baseLayer = <TileLayer
|
||||||
url={baseUrl}
|
url={baseUrl}
|
||||||
attribution={attribution}
|
attribution={attribution}
|
||||||
|
maxNativeZoom={18}
|
||||||
|
maxZoom={19}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
const buildingsBaseUrl = `/tiles/base_${this.state.theme}/{z}/{x}/{y}{r}.png`;
|
const buildingsBaseUrl = `/tiles/base_${this.state.theme}/{z}/{x}/{y}{r}.png`;
|
||||||
const buildingBaseLayer = <TileLayer url={buildingsBaseUrl} minZoom={14} />;
|
const buildingBaseLayer = <TileLayer url={buildingsBaseUrl} minZoom={14} maxZoom={19}/>;
|
||||||
|
|
||||||
|
|
||||||
const boundaryStyleFn = () => ({color: '#bbb', fill: false});
|
const boundaryStyleFn = () => ({color: '#bbb', fill: false});
|
||||||
@ -146,6 +148,7 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
|
|||||||
key={tileset}
|
key={tileset}
|
||||||
url={`/tiles/${tileset}/{z}/{x}/{y}{r}.png?rev=${rev}`}
|
url={`/tiles/${tileset}/{z}/{x}/{y}{r}.png?rev=${rev}`}
|
||||||
minZoom={9}
|
minZoom={9}
|
||||||
|
maxZoom={19}
|
||||||
/>
|
/>
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
@ -154,7 +157,8 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
|
|||||||
<TileLayer
|
<TileLayer
|
||||||
key={this.props.building.building_id}
|
key={this.props.building.building_id}
|
||||||
url={`/tiles/highlight/{z}/{x}/{y}{r}.png?highlight=${this.props.building.geometry_id}&base=${tileset}`}
|
url={`/tiles/highlight/{z}/{x}/{y}{r}.png?highlight=${this.props.building.geometry_id}&base=${tileset}`}
|
||||||
minZoom={14}
|
minZoom={13}
|
||||||
|
maxZoom={19}
|
||||||
zIndex={100}
|
zIndex={100}
|
||||||
/>
|
/>
|
||||||
: null;
|
: null;
|
||||||
@ -167,7 +171,7 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
|
|||||||
center={position}
|
center={position}
|
||||||
zoom={this.state.zoom}
|
zoom={this.state.zoom}
|
||||||
minZoom={9}
|
minZoom={9}
|
||||||
maxZoom={18}
|
maxZoom={19}
|
||||||
doubleClickZoom={false}
|
doubleClickZoom={false}
|
||||||
zoomControl={false}
|
zoomControl={false}
|
||||||
attributionControl={false}
|
attributionControl={false}
|
||||||
|
@ -9,14 +9,25 @@ const ContactPage = () => (
|
|||||||
</h1>
|
</h1>
|
||||||
<p> Colouring London has been designed as a sustainable, low-cost model for knowledge exchange/open data platforms able to be reproduced by other towns and cities using our open platform code.</p>
|
<p> Colouring London has been designed as a sustainable, low-cost model for knowledge exchange/open data platforms able to be reproduced by other towns and cities using our open platform code.</p>
|
||||||
|
|
||||||
<p> It is being developed by a small, dedicated team at UCL. We are unable to answer individual queries but welcome constructive comments on how to improve the site, and on other types of data and new features you might like to see.</p>
|
<p> It is being developed by a small, dedicated team at UCL. We are unable to answer individual queries but welcome constructive comments on how to improve the site, and on other types of data and new features you might like to see.</p>
|
||||||
|
|
||||||
<p> You can send us comments or ask questions on our discussion threads at <a href="https://discuss.colouring.london/">https://discuss.colouring.london/</a>.</p>
|
<p> You can send us comments or ask questions on our discussion threads at <a href="https://discuss.colouring.london/">https://discuss.colouring.london/</a>.</p>
|
||||||
|
|
||||||
<p> To view our technical site and platform code please visit Github at: <a href="https://github.com/tomalrussell/colouring-london">https://github.com/tomalrussell/colouring-london</a>.</p>
|
<p> To view our technical site and platform code please visit Github at: <a href="https://github.com/tomalrussell/colouring-london">https://github.com/tomalrussell/colouring-london</a>.</p>
|
||||||
|
|
||||||
<p>For press enquiries please contact the Bartlett Press and Communications team at architecture@ucl.ac.uk.</p>
|
<p>For press enquiries please contact the Bartlett Press and Communications team at <a href="mailto:architecture@ucl.ac.uk">architecture@ucl.ac.uk</a></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you capture images from the maps on Colouring London, please credit our
|
||||||
|
contributors (who collected the data) and Ordnance Survey
|
||||||
|
(who provided the basemaps and building geometries) as follows:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<pre><code>
|
||||||
|
Colouring London https://colouring.london Building attribute data is © Colouring London contributors. Maps contain OS data © Crown copyright: OS Maps baselayers and building outlines.
|
||||||
|
</code></pre>
|
||||||
|
</p>
|
||||||
|
<hr />
|
||||||
<p>
|
<p>
|
||||||
<img className="d-block mx-auto" src="images/logo-cl.png"></img>
|
<img className="d-block mx-auto" src="images/logo-cl.png"></img>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { dateReviver } from '../../helpers';
|
import { dateReviver } from '../../helpers';
|
||||||
|
|
||||||
|
|
||||||
interface ExtractViewModel {
|
interface ExtractViewModel {
|
||||||
extract_id: number;
|
extract_id: number;
|
||||||
extracted_on: Date;
|
extracted_on: Date;
|
||||||
@ -44,8 +45,22 @@ export default class DataExtracts extends React.Component<{}, DataExtractsState>
|
|||||||
<article>
|
<article>
|
||||||
<section className="main-col">
|
<section className="main-col">
|
||||||
<h1 className="h2">Open data extracts</h1>
|
<h1 className="h2">Open data extracts</h1>
|
||||||
<p>Choose one of the links below to download an archive containing the open data collected on the Colouring London platform</p>
|
<p>
|
||||||
<p>By downloading data extracts from this site, you agree to the <NavLink to="/data-accuracy.html">data accuracy agreement </NavLink> and the <NavLink to="/ordnance-survey-uprn.html">Ordnance Survey terms of UPRN usage</NavLink>.</p>
|
Choose one of the links below to download an archive containing the open data collected on the Colouring London platform
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Colouring London contributions are open data, licensed under the <a href="http://opendatacommons.org/licenses/odbl/">Open Data Commons Open Database License</a> (ODbL) by Colouring London contributors.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You are free to copy, distribute, transmit and adapt our data, as long as you credit Colouring London and our contributors. If you alter or build upon our data, you may distribute the result only under the same licence.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Choose one of the links below to download an archive containing the open data collected on the Colouring London platform.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
By downloading data extracts from this site, you agree to the <Link to="/data-accuracy.html">data accuracy agreement</Link> and the <Link to="/ordnance-survey-uprn.html">Ordnance Survey terms of UPRN usage</Link>.
|
||||||
|
</p>
|
||||||
|
|
||||||
{
|
{
|
||||||
this.state.extracts == undefined ?
|
this.state.extracts == undefined ?
|
||||||
<p>Loading extracts...</p> :
|
<p>Loading extracts...</p> :
|
||||||
|
@ -17,11 +17,18 @@ const Welcome = () => (
|
|||||||
volunteers of all ages and abilities to test and provide feedback on the site as we
|
volunteers of all ages and abilities to test and provide feedback on the site as we
|
||||||
build it.
|
build it.
|
||||||
</p>
|
</p>
|
||||||
|
<p className="lead">
|
||||||
|
All of the data we collect is made <Link to="/data-extracts.html">openly available</Link> –
|
||||||
|
please read our <a href="https://www.pages.colouring.london/data-ethics">data ethics policy</a> and
|
||||||
|
credit Colouring London if you use or share our maps or data.
|
||||||
|
</p>
|
||||||
<Link to="/view/categories"
|
<Link to="/view/categories"
|
||||||
className="btn btn-outline-dark btn-lg btn-block">
|
className="btn btn-outline-dark btn-lg btn-block">
|
||||||
Start Colouring Here!
|
Start Colouring Here!
|
||||||
</Link>
|
</Link>
|
||||||
|
<p>
|
||||||
<img src="images/supporter-logos.png" alt="Colouring London collaborating organisations: The Bartlett UCL, Ordnance Survey, Historic England, Greater London Authority" />
|
<img src="images/supporter-logos.png" alt="Colouring London collaborating organisations: The Bartlett UCL, Ordnance Survey, Historic England, Greater London Authority" />
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -107,11 +107,17 @@ class MyAccountPage extends Component<MyAccountPageProps, MyAccountPageState> {
|
|||||||
<h1 className="h1">Welcome, {this.props.user.username}!</h1>
|
<h1 className="h1">Welcome, {this.props.user.username}!</h1>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
Colouring London is under active development, Please <a href="https://discuss.colouring.london/">discuss
|
Colouring London is under active development. Please <a href="https://discuss.colouring.london/">discuss
|
||||||
suggestions for improvements</a> and <a
|
suggestions for improvements</a> and <a
|
||||||
href="https://github.com/tomalrussell/colouring-london/issues">
|
href="https://github.com/tomalrussell/colouring-london/issues">
|
||||||
report issues or problems</a>.
|
report issues or problems</a>.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For reference, here are the <Link
|
||||||
|
to="/privacy-policy.html">privacy policy</Link>, <Link
|
||||||
|
to="/contributor-agreement.html">contributor agreement</Link> and <Link
|
||||||
|
to="/data-accuracy.html">data accuracy agreement</Link>.
|
||||||
</p>
|
</p>
|
||||||
<ErrorBox msg={this.state.error} />
|
<ErrorBox msg={this.state.error} />
|
||||||
<form onSubmit={this.handleLogout}>
|
<form onSubmit={this.handleLogout}>
|
||||||
|
@ -29,7 +29,7 @@ const tileCache = new TileCache(
|
|||||||
{
|
{
|
||||||
tilesets: getBuildingLayerNames(),
|
tilesets: getBuildingLayerNames(),
|
||||||
minZoom: 9,
|
minZoom: 9,
|
||||||
maxZoom: 18,
|
maxZoom: 19,
|
||||||
scales: [1, 2]
|
scales: [1, 2]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
109
etl/join_building_data/load_csv_to_staging.py
Normal file
109
etl/join_building_data/load_csv_to_staging.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
"""Join csv data to buildings
|
||||||
|
Example usage (replace URL with test/staging/localhost as necessary, API key with real key for
|
||||||
|
the appropriate site):
|
||||||
|
python load_csv_to_staging.py \
|
||||||
|
https://clstaging.casa.ucl.ac.uk \
|
||||||
|
a0a00000-0a00-0aaa-a0a0-0000aaaa0000 \
|
||||||
|
data.csv
|
||||||
|
This script uses the HTTP API, and can process CSV files which identify buildings by id, TOID,
|
||||||
|
UPRN.
|
||||||
|
The process:
|
||||||
|
- assume first line of the CSV is a header, where column names are either
|
||||||
|
- building identifiers - one of:
|
||||||
|
- building_id
|
||||||
|
- toid
|
||||||
|
- uprn
|
||||||
|
- building data field names
|
||||||
|
- read through lines of CSV:
|
||||||
|
- use building id if provided
|
||||||
|
- else lookup by toid
|
||||||
|
- else lookup by uprn
|
||||||
|
- else locate building by representative point
|
||||||
|
- update building
|
||||||
|
TODO extend to allow latitude,longitude or easting,northing columns and lookup by location.
|
||||||
|
"""
|
||||||
|
import csv
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
session = requests.Session()
|
||||||
|
session.verify = False
|
||||||
|
|
||||||
|
def main(base_url, api_key, source_file):
|
||||||
|
"""Read from file, update buildings
|
||||||
|
"""
|
||||||
|
with open(source_file, 'r') as source:
|
||||||
|
reader = csv.DictReader(source)
|
||||||
|
for line in reader:
|
||||||
|
building_id = find_building(line, base_url)
|
||||||
|
|
||||||
|
if building_id is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
response_code, response_data = update_building(building_id, line, api_key, base_url)
|
||||||
|
if response_code != 200:
|
||||||
|
print('ERROR', building_id, response_code, response_data)
|
||||||
|
|
||||||
|
|
||||||
|
def update_building(building_id, data, api_key, base_url):
|
||||||
|
"""Save data to a building
|
||||||
|
"""
|
||||||
|
r = requests.post(
|
||||||
|
"{}/api/buildings/{}.json".format(base_url, building_id),
|
||||||
|
params={'api_key': api_key},
|
||||||
|
json=data,
|
||||||
|
verify=False
|
||||||
|
)
|
||||||
|
print(r)
|
||||||
|
return r.status_code, r.json()
|
||||||
|
|
||||||
|
|
||||||
|
def find_building(data, base_url):
|
||||||
|
if 'toid' in data:
|
||||||
|
building_id = find_by_reference(base_url, 'toid', data['toid'])
|
||||||
|
if building_id is not None:
|
||||||
|
print("match_by_toid", data['toid'], building_id)
|
||||||
|
return building_id
|
||||||
|
|
||||||
|
if 'uprn' in data:
|
||||||
|
building_id = find_by_reference(base_url, 'uprn', data['uprn'])
|
||||||
|
if building_id is not None:
|
||||||
|
print("match_by_uprn", data['uprn'], building_id)
|
||||||
|
return building_id
|
||||||
|
|
||||||
|
print("no_match", data)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def find_by_reference(base_url, ref_key, ref_id):
|
||||||
|
"""Find building_id by TOID or UPRN
|
||||||
|
"""
|
||||||
|
r = requests.get("{}/api/buildings/reference".format(base_url), params={
|
||||||
|
'key': ref_key,
|
||||||
|
'id': ref_id,
|
||||||
|
},
|
||||||
|
verify=False
|
||||||
|
)
|
||||||
|
buildings = r.json()
|
||||||
|
|
||||||
|
if buildings and 'error' not in buildings and len(buildings) == 1:
|
||||||
|
building_id = buildings[0]['building_id']
|
||||||
|
else:
|
||||||
|
building_id = None
|
||||||
|
|
||||||
|
return building_id
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
url, api_key, filename = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||||
|
except IndexError:
|
||||||
|
print(
|
||||||
|
"Usage: {} <URL> <api_key> ./path/to/data.csv".format(
|
||||||
|
os.path.basename(__file__)
|
||||||
|
))
|
||||||
|
exit()
|
||||||
|
|
||||||
|
main(url, api_key, filename)
|
Loading…
Reference in New Issue
Block a user