+
);
+Sidebar.propTypes = {
+ back: PropTypes.string,
+ title: PropTypes.string.isRequired,
+ children: PropTypes.node
+}
+
export default Sidebar;
diff --git a/app/src/frontend/signup.js b/app/src/frontend/signup.js
index 2dc83054..06575812 100644
--- a/app/src/frontend/signup.js
+++ b/app/src/frontend/signup.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { Redirect, Link } from 'react-router-dom';
+import PropTypes from 'prop-types';
import ErrorBox from './error-box';
import InfoBox from './info-box';
@@ -156,4 +157,9 @@ class SignUp extends Component {
}
}
+SignUp.propTypes = {
+ login: PropTypes.func.isRequired,
+ user: PropTypes.object
+}
+
export default SignUp;
diff --git a/app/src/frontend/theme-switcher.js b/app/src/frontend/theme-switcher.js
index 6252a999..3d87478d 100644
--- a/app/src/frontend/theme-switcher.js
+++ b/app/src/frontend/theme-switcher.js
@@ -1,4 +1,5 @@
import React from 'react';
+import PropTypes from 'prop-types';
import './theme-switcher.css';
@@ -11,4 +12,9 @@ const ThemeSwitcher = (props) => (
);
+ThemeSwitcher.propTypes = {
+ currentTheme: PropTypes.string,
+ onSubmit: PropTypes.func.isRequired
+}
+
export default ThemeSwitcher;
diff --git a/app/src/frontend/tooltip.js b/app/src/frontend/tooltip.js
index fd4c1821..6bc30601 100644
--- a/app/src/frontend/tooltip.js
+++ b/app/src/frontend/tooltip.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
+import PropTypes from 'prop-types';
import './tooltip.css';
import { InfoIcon } from './icons';
@@ -42,4 +43,9 @@ class Tooltip extends Component {
);
}
}
+
+Tooltip.propTypes = {
+ text: PropTypes.string
+}
+
export default Tooltip;
diff --git a/app/src/parse.js b/app/src/parse.js
index 7eaedce8..87a20ff0 100644
--- a/app/src/parse.js
+++ b/app/src/parse.js
@@ -39,12 +39,12 @@ function parseBuildingURL(url) {
* @returns {String} [age]
*/
function parseCategoryURL(url) {
- const default_cat = 'age';
+ const defaultCat = 'age';
if (url === '/') {
- return default_cat
+ return defaultCat;
}
const matches = /^\/(view|edit)\/([^/.]+)/.exec(url);
- const cat = (matches && matches.length >= 3) ? matches[2] : default_cat;
+ const cat = (matches && matches.length >= 3) ? matches[2] : defaultCat;
return cat;
}
diff --git a/app/src/server.js b/app/src/server.js
index 889f0055..c02f2188 100644
--- a/app/src/server.js
+++ b/app/src/server.js
@@ -76,29 +76,29 @@ function frontendRoute(req, res) {
const data = {};
context.status = 200;
- const user_id = req.session.user_id;
- const building_id = parseBuildingURL(req.url);
- const is_building = (typeof (building_id) !== 'undefined');
- if (is_building && isNaN(building_id)) {
+ const userId = req.session.user_id;
+ const buildingId = parseBuildingURL(req.url);
+ const isBuilding = (typeof (buildingId) !== 'undefined');
+ if (isBuilding && isNaN(buildingId)) {
context.status = 404;
}
Promise.all([
- user_id ? getUserById(user_id) : undefined,
- is_building ? getBuildingById(building_id) : undefined,
- is_building ? getBuildingUPRNsById(building_id) : undefined,
- (is_building && user_id) ? getBuildingLikeById(building_id, user_id) : false
+ userId ? getUserById(userId) : undefined,
+ isBuilding ? getBuildingById(buildingId) : undefined,
+ isBuilding ? getBuildingUPRNsById(buildingId) : undefined,
+ (isBuilding && userId) ? getBuildingLikeById(buildingId, userId) : false
]).then(function (values) {
const user = values[0];
const building = values[1];
const uprns = values[2];
- const building_like = values[3];
- if (is_building && typeof (building) === 'undefined') {
+ const buildingLike = values[3];
+ if (isBuilding && typeof (building) === 'undefined') {
context.status = 404
}
data.user = user;
data.building = building;
- data.building_like = building_like;
+ data.building_like = buildingLike;
if (data.building != null) {
data.building.uprns = uprns;
}
@@ -218,10 +218,10 @@ server.route('/building/:building_id.json')
}
})
-function updateBuilding(req, res, user_id) {
+function updateBuilding(req, res, userId) {
const { building_id } = req.params;
const building = req.body;
- saveBuilding(building_id, building, user_id).then(building => {
+ saveBuilding(building_id, building, userId).then(building => {
if (building.error) {
res.send(building)
return
@@ -384,8 +384,8 @@ server.post('/api/key', function (req, res) {
return
}
- getNewUserAPIKey(req.session.user_id).then(function (api_key) {
- res.send(api_key);
+ getNewUserAPIKey(req.session.user_id).then(function (apiKey) {
+ res.send(apiKey);
}).catch(function (error) {
res.send(error);
});
@@ -393,14 +393,14 @@ server.post('/api/key', function (req, res) {
// GET search
server.get('/search', function (req, res) {
- const search_term = req.query.q;
- if (!search_term) {
+ const searchTerm = req.query.q;
+ if (!searchTerm) {
res.send({
error: 'Please provide a search term'
})
return
}
- queryLocation(search_term).then((results) => {
+ queryLocation(searchTerm).then((results) => {
if (typeof (results) === 'undefined') {
res.send({
error: 'Database error'
diff --git a/app/src/tiles/cache.js b/app/src/tiles/cache.js
index c76b3f2e..f018e444 100644
--- a/app/src/tiles/cache.js
+++ b/app/src/tiles/cache.js
@@ -18,7 +18,7 @@
// and then use stdlib `import fs from 'fs';`
import fs from 'node-fs';
-import { get_xyz } from './tile';
+import { getXYZ } from './tile';
// Use an environment variable to configure the cache location, somewhere we can read/write to.
const CACHE_PATH = process.env.TILECACHE_PATH
@@ -32,10 +32,10 @@ const CACHE_PATH = process.env.TILECACHE_PATH
* @param {number} y
*/
function get(tileset, z, x, y) {
- if (!should_try_cache(tileset, z)) {
+ if (!shouldTryCache(tileset, z)) {
return Promise.reject(`Skip cache get ${tileset}/${z}/${x}/${y}`);
}
- const location = cache_location(tileset, z, x, y);
+ const location = cacheLocation(tileset, z, x, y);
return new Promise((resolve, reject) => {
fs.readFile(location.fname, (err, data) => {
if (err) {
@@ -57,10 +57,10 @@ function get(tileset, z, x, y) {
* @param {number} y
*/
function put(im, tileset, z, x, y) {
- if (!should_try_cache(tileset, z)) {
+ if (!shouldTryCache(tileset, z)) {
return Promise.reject(`Skip cache put ${tileset}/${z}/${x}/${y}`);
}
- const location = cache_location(tileset, z, x, y);
+ const location = cacheLocation(tileset, z, x, y);
return new Promise((resolve, reject) => {
fs.writeFile(location.fname, im, 'binary', (err) => {
if (err && err.code === 'ENOENT') {
@@ -91,7 +91,7 @@ function put(im, tileset, z, x, y) {
* @param {number} y
*/
function remove(tileset, z, x, y) {
- const location = cache_location(tileset, z, x, y)
+ const location = cacheLocation(tileset, z, x, y)
return new Promise(resolve => {
fs.unlink(location.fname, (err) => {
if(err){
@@ -111,26 +111,26 @@ function remove(tileset, z, x, y) {
* @param {String} tileset
* @param {Array} bbox [w, s, e, n] in EPSG:3857 coordinates
*/
-function remove_all_at_bbox(bbox) {
+function removeAllAtBbox(bbox) {
// magic numbers for min/max zoom
- const min_zoom = 9;
- const max_zoom = 18;
+ const minZoom = 9;
+ const maxZoom = 18;
// magic list of tilesets - see tileserver, other cache rules
const tilesets = ['date_year', 'size_storeys', 'location', 'likes', 'conservation_area'];
- let tile_bounds;
- const remove_promises = [];
+ let tileBounds;
+ const removePromises = [];
for (let ti = 0; ti < tilesets.length; ti++) {
const tileset = tilesets[ti];
- for (let z = min_zoom; z <= max_zoom; z++) {
- tile_bounds = get_xyz(bbox, z)
- for (let x = tile_bounds.minX; x <= tile_bounds.maxX; x++){
- for (let y = tile_bounds.minY; y <= tile_bounds.maxY; y++){
- remove_promises.push(remove(tileset, z, x, y))
+ for (let z = minZoom; z <= maxZoom; z++) {
+ tileBounds = getXYZ(bbox, z)
+ for (let x = tileBounds.minX; x <= tileBounds.maxX; x++){
+ for (let y = tileBounds.minY; y <= tileBounds.maxY; y++){
+ removePromises.push(remove(tileset, z, x, y))
}
}
}
}
- Promise.all(remove_promises)
+ Promise.all(removePromises)
}
/**
@@ -142,7 +142,7 @@ function remove_all_at_bbox(bbox) {
* @param {number} y
* @returns {object} { dir:
, fname: }
*/
-function cache_location(tileset, z, x, y) {
+function cacheLocation(tileset, z, x, y) {
const dir = `${CACHE_PATH}/${tileset}/${z}/${x}`
const fname = `${dir}/${y}.png`
return {dir, fname}
@@ -155,7 +155,7 @@ function cache_location(tileset, z, x, y) {
* @param {number} z zoom level
* @returns {boolean} whether to use the cache (or not)
*/
-function should_try_cache(tileset, z) {
+function shouldTryCache(tileset, z) {
if (tileset === 'date_year') {
// cache high zoom because of front page hits
return z <= 16
@@ -168,4 +168,4 @@ function should_try_cache(tileset, z) {
return z <= 13
}
-export { get, put, remove, remove_all_at_bbox };
+export { get, put, remove, removeAllAtBbox };
diff --git a/app/src/tiles/tile.js b/app/src/tiles/tile.js
index 99beb819..1ff3d1b2 100644
--- a/app/src/tiles/tile.js
+++ b/app/src/tiles/tile.js
@@ -33,11 +33,11 @@ const PROJ4_STRING = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x
// Mapnik uses table definitions to query geometries and attributes from PostGIS.
// The queries here are eventually used as subqueries when Mapnik fetches data to render a
-// tile - so given a table_definition like:
-// (SELECT geometry_geom FROM geometries) as my_table_definition
+// tile - so given a table definition like:
+// (SELECT geometry_geom FROM geometries) as def
// Mapnik will wrap it in a bbox query and PostGIS will eventually see something like:
// SELECT AsBinary("geometry") AS geom from
-// (SELECT geometry_geom FROM geometries) as my_table_definition
+// (SELECT geometry_geom FROM geometries) as def
// WHERE "geometry" && SetSRID('BOX3D(0,1,2,3)'::box3d, 3857)
// see docs: https://github.com/mapnik/mapnik/wiki/OptimizeRenderingWithPostGIS
const MAP_STYLE_TABLE_DEFINITIONS = {
@@ -139,26 +139,26 @@ const mercator = new SphericalMercator({
size: TILE_SIZE
});
-function get_bbox(z, x, y) {
+function getBbox(z, x, y) {
return mercator.bbox(x, y, z, false, '900913');
}
-function get_xyz(bbox, z) {
+function getXYZ(bbox, z) {
return mercator.xyz(bbox, z, false, '900913')
}
-function render_tile(tileset, z, x, y, geometry_id, cb) {
- const bbox = get_bbox(z, x, y)
+function renderTile(tileset, z, x, y, geometryId, cb) {
+ const bbox = getBbox(z, x, y)
const map = new mapnik.Map(TILE_SIZE, TILE_SIZE, PROJ4_STRING);
map.bufferSize = TILE_BUFFER_SIZE;
const layer = new mapnik.Layer('tile', PROJ4_STRING);
- const table_def = (tileset === 'highlight') ?
- get_highlight_table_def(geometry_id)
+ const tableDefinition = (tileset === 'highlight') ?
+ getHighlightTableDefinition(geometryId)
: MAP_STYLE_TABLE_DEFINITIONS[tileset];
- const conf = Object.assign({ table: table_def }, DATASOURCE_CONFIG)
+ const conf = Object.assign({ table: tableDefinition }, DATASOURCE_CONFIG)
var postgis;
try {
@@ -186,17 +186,17 @@ function render_tile(tileset, z, x, y, geometry_id, cb) {
}
}
-// highlight single geometry, requires geometry_id in the table query
-function get_highlight_table_def(geometry_id) {
+// highlight single geometry, requires geometryId in the table query
+function getHighlightTableDefinition(geometryId) {
return `(
SELECT
g.geometry_geom
FROM
geometries as g
WHERE
- g.geometry_id = ${geometry_id}
+ g.geometry_id = ${geometryId}
) as highlight`
}
-export { get_bbox, get_xyz, render_tile, TILE_SIZE };
+export { getBbox, getXYZ, renderTile, TILE_SIZE };
diff --git a/app/src/tiles/tileserver.js b/app/src/tiles/tileserver.js
index 96d29dba..dd9a5ac3 100644
--- a/app/src/tiles/tileserver.js
+++ b/app/src/tiles/tileserver.js
@@ -9,7 +9,7 @@ import express from 'express';
import sharp from 'sharp';
import { get, put } from './cache';
-import { render_tile, get_bbox, get_xyz, TILE_SIZE } from './tile';
+import { renderTile, getBbox, getXYZ, TILE_SIZE } from './tile';
import { strictParseInt } from '../parse';
// zoom level when we switch from rendering direct from database to instead composing tiles
@@ -23,48 +23,48 @@ const EXTENT_BBOX = [-61149.622628, 6667754.851372, 28128.826409, 6744803.375884
// tiles router
const router = express.Router()
-router.get('/highlight/:z/:x/:y.png', handle_highlight_tile_request);
+router.get('/highlight/:z/:x/:y.png', handleHighlightTileRequest);
router.get('/base_light/:z/:x/:y.png', (req, res) => {
- handle_tile_request('base_light', req, res)
+ handleTileRequest('base_light', req, res)
});
router.get('/base_night/:z/:x/:y.png', (req, res) => {
- handle_tile_request('base_night', req, res)
+ handleTileRequest('base_night', req, res)
});
router.get('/date_year/:z/:x/:y.png', (req, res) => {
- handle_tile_request('date_year', req, res)
+ handleTileRequest('date_year', req, res)
});
router.get('/size_storeys/:z/:x/:y.png', (req, res) => {
- handle_tile_request('size_storeys', req, res)
+ handleTileRequest('size_storeys', req, res)
});
router.get('/location/:z/:x/:y.png', (req, res) => {
- handle_tile_request('location', req, res)
+ handleTileRequest('location', req, res)
});
router.get('/likes/:z/:x/:y.png', (req, res) => {
- handle_tile_request('likes', req, res)
+ handleTileRequest('likes', req, res)
});
router.get('/conservation_area/:z/:x/:y.png', (req, res) => {
- handle_tile_request('conservation_area', req, res)
+ handleTileRequest('conservation_area', req, res)
});
-function handle_tile_request(tileset, req, res) {
+function handleTileRequest(tileset, req, res) {
const { z, x, y } = req.params
- const int_z = strictParseInt(z);
- const int_x = strictParseInt(x);
- const int_y = strictParseInt(y);
+ const intZ = strictParseInt(z);
+ const intX = strictParseInt(x);
+ const intY = strictParseInt(y);
- if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)) {
+ if (isNaN(intX) || isNaN(intY) || isNaN(intZ)) {
console.error('Missing x or y or z')
return { error: 'Bad parameter' }
}
- load_tile(tileset, int_z, int_x, int_y).then((im) => {
+ loadTile(tileset, intZ, intX, intY).then((im) => {
res.writeHead(200, { 'Content-Type': 'image/png' })
res.end(im)
}).catch((err) => {
@@ -73,21 +73,21 @@ function handle_tile_request(tileset, req, res) {
})
}
-function load_tile(tileset, z, x, y) {
- if (outside_extent(z, x, y)) {
- return empty_tile()
+function loadTile(tileset, z, x, y) {
+ if (outsideExtent(z, x, y)) {
+ return emptyTile()
}
return get(tileset, z, x, y).then((im) => {
console.log(`From cache ${tileset}/${z}/${x}/${y}`)
return im
}).catch(() => {
- return render_or_stitch_tile(tileset, z, x, y)
+ return renderOrStitchTile(tileset, z, x, y)
})
}
-function render_or_stitch_tile(tileset, z, x, y) {
+function renderOrStitchTile(tileset, z, x, y) {
if (z <= STITCH_THRESHOLD) {
- return stitch_tile(tileset, z, x, y).then(im => {
+ return StitchTile(tileset, z, x, y).then(im => {
return put(im, tileset, z, x, y).then(() => {
console.log(`Stitch ${tileset}/${z}/${x}/${y}`)
return im
@@ -99,7 +99,7 @@ function render_or_stitch_tile(tileset, z, x, y) {
} else {
return new Promise((resolve, reject) => {
- render_tile(tileset, z, x, y, undefined, (err, im) => {
+ renderTile(tileset, z, x, y, undefined, (err, im) => {
if (err) {
reject(err)
return
@@ -116,12 +116,12 @@ function render_or_stitch_tile(tileset, z, x, y) {
}
}
-function outside_extent(z, x, y) {
- const xy = get_xyz(EXTENT_BBOX, z);
+function outsideExtent(z, x, y) {
+ const xy = getXYZ(EXTENT_BBOX, z);
return xy.minY > y || xy.maxY < y || xy.minX > x || xy.maxX < x;
}
-function empty_tile() {
+function emptyTile() {
return sharp({
create: {
width: 1,
@@ -132,22 +132,22 @@ function empty_tile() {
}).png().toBuffer()
}
-function stitch_tile(tileset, z, x, y) {
- const bbox = get_bbox(z, x, y)
- const next_z = z + 1
- const next_xy = get_xyz(bbox, next_z)
+function StitchTile(tileset, z, x, y) {
+ const bbox = getBbox(z, x, y)
+ const nextZ = z + 1
+ const nextXY = getXYZ(bbox, nextZ)
return Promise.all([
// recurse down through zoom levels, using cache if available...
- load_tile(tileset, next_z, next_xy.minX, next_xy.minY),
- load_tile(tileset, next_z, next_xy.maxX, next_xy.minY),
- load_tile(tileset, next_z, next_xy.minX, next_xy.maxY),
- load_tile(tileset, next_z, next_xy.maxX, next_xy.maxY)
+ loadTile(tileset, nextZ, nextXY.minX, nextXY.minY),
+ loadTile(tileset, nextZ, nextXY.maxX, nextXY.minY),
+ loadTile(tileset, nextZ, nextXY.minX, nextXY.maxY),
+ loadTile(tileset, nextZ, nextXY.maxX, nextXY.maxY)
]).then(([
- top_left,
- top_right,
- bottom_left,
- bottom_right
+ topLeft,
+ topRight,
+ bottomLeft,
+ bottomRight
]) => {
// not possible to chain overlays in a single pipeline, but there may still be a better
// way to create image buffer here (four tiles resize to one at the next zoom level)
@@ -160,18 +160,18 @@ function stitch_tile(tileset, z, x, y) {
background: { r: 0, g: 0, b: 0, alpha: 0 }
}
}).overlayWith(
- top_left, { gravity: sharp.gravity.northwest }
+ topLeft, { gravity: sharp.gravity.northwest }
).png().toBuffer().then((buf) => {
return sharp(buf).overlayWith(
- top_right, { gravity: sharp.gravity.northeast }
+ topRight, { gravity: sharp.gravity.northeast }
).png().toBuffer()
}).then((buf) => {
return sharp(buf).overlayWith(
- bottom_left, { gravity: sharp.gravity.southwest }
+ bottomLeft, { gravity: sharp.gravity.southwest }
).png().toBuffer()
}).then((buf) => {
return sharp(buf).overlayWith(
- bottom_right, { gravity: sharp.gravity.southeast }
+ bottomRight, { gravity: sharp.gravity.southeast }
).png().toBuffer()
}).then((buf) => {
return sharp(buf
@@ -182,30 +182,30 @@ function stitch_tile(tileset, z, x, y) {
}
-function handle_highlight_tile_request(req, res) {
+function handleHighlightTileRequest(req, res) {
const { z, x, y } = req.params
- const int_z = strictParseInt(z);
- const int_x = strictParseInt(x);
- const int_y = strictParseInt(y);
+ const intZ = strictParseInt(z);
+ const intX = strictParseInt(x);
+ const intY = strictParseInt(y);
- if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)) {
+ if (isNaN(intX) || isNaN(intY) || isNaN(intZ)) {
console.error('Missing x or y or z')
return { error: 'Bad parameter' }
}
// highlight layer uses geometry_id to outline a single building
const { highlight } = req.query
- const geometry_id = strictParseInt(highlight);
- if (isNaN(geometry_id)) {
+ const geometryId = strictParseInt(highlight);
+ if (isNaN(geometryId)) {
res.status(400).send({ error: 'Bad parameter' })
return
}
- if (outside_extent(z, x, y)) {
- return empty_tile()
+ if (outsideExtent(z, x, y)) {
+ return emptyTile()
}
- render_tile('highlight', int_z, int_x, int_y, geometry_id, function (err, im) {
+ renderTile('highlight', intZ, intX, intY, geometryId, function (err, im) {
if (err) {throw err}
res.writeHead(200, { 'Content-Type': 'image/png' })