Query buildings by location or reference

This commit is contained in:
Tom Russell 2018-09-29 19:09:48 +01:00
parent 2a1902f6ce
commit 3e4beb5423
2 changed files with 107 additions and 69 deletions

View File

@ -1,6 +1,6 @@
import { query } from './db'; import { query } from './db';
function queryBuildingAtPoint(lng, lat) { function queryBuildingsAtPoint(lng, lat) {
return query( return query(
`SELECT `SELECT
b.building_id as id, b.building_id as id,
@ -17,26 +17,52 @@ function queryBuildingAtPoint(lng, lat) {
), ),
g.geometry_geom g.geometry_geom
) )
LIMIT 1
`, `,
[lng, lat] [lng, lat]
).then(function(data){ ).then(buildingRowsToDocs).catch(function(error){
const rows = data.rows
if (rows.length){
const id = rows[0].id
const doc = rows[0].doc
const geometry_id = rows[0].geometry_id
doc.id = id
doc.geometry_id = geometry_id
return doc
}
return undefined;
}).catch(function(error){
console.error(error); console.error(error);
return undefined; return undefined;
}); });
} }
function queryBuildingsByReference(key, id) {
if (key === 'toid'){
return query(
`SELECT
b.building_id as id,
b.building_doc as doc,
g.geometry_id as geometry_id
FROM buildings as b, geometries as g
WHERE
b.geometry_id = g.geometry_id
AND
b.ref_toid = $1
`,
[id]
).then(buildingRowsToDocs).catch(function(error){
console.error(error);
return undefined;
});
}
if (key === 'uprn') {
return query(
`SELECT
b.building_id as id,
b.building_doc as doc,
g.geometry_id as geometry_id
FROM buildings as b, geometries as g
WHERE
b.geometry_id = g.geometry_id
AND
b.ref_uprn = $1
`,
[id]
).then(buildingRowsToDocs).catch(function(error){
console.error(error);
return undefined;
});
}
return {error: 'Key must be UPRN or TOID'};
}
function getBuildingById(id) { function getBuildingById(id) {
return query( return query(
@ -50,24 +76,26 @@ function getBuildingById(id) {
building_id = $1 building_id = $1
`, `,
[ id ] [ id ]
).then(function(data){ ).then(buildingRowsToDocs).catch(function(error){
const rows = data.rows
if (rows.length){
const id = rows[0].id
const doc = rows[0].doc
const geometry_id = rows[0].geometry_id
doc.id = id
doc.geometry_id = geometry_id
return doc
}
return undefined;
}).catch(function(error){
console.error(error); console.error(error);
return undefined; return undefined;
}); });
} }
function buildingRowsToDocs(data){
const rows = data.rows
const data = rows.map(function(row){
const id = row.id
const doc = row.doc
const geometry_id = row.geometry_id
doc.id = id
doc.geometry_id = geometry_id
return doc
});
return data;
}
function saveBuilding(id, building_doc) { function saveBuilding(id, building_doc) {
// don't save id or geometry_id into doc // don't save id or geometry_id into doc
delete building_doc.id; delete building_doc.id;
@ -88,4 +116,4 @@ function saveBuilding(id, building_doc) {
}); });
} }
export { queryBuildingAtPoint, getBuildingById, saveBuilding }; export { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById, saveBuilding };

View File

@ -11,7 +11,8 @@ import pgConnect from 'connect-pg-simple';
import App from './frontend/app'; import App from './frontend/app';
import { pool } from './db'; import { pool } from './db';
import { authUser, createUser, getUserById } from './user'; import { authUser, createUser, getUserById } from './user';
import { queryBuildingAtPoint, getBuildingById, saveBuilding } from './building'; import { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById,
saveBuilding } from './building';
import tileserver from './tileserver'; import tileserver from './tileserver';
import { parseBuildingURL } from './parse'; import { parseBuildingURL } from './parse';
@ -33,21 +34,21 @@ server.use(bodyParser.json());
// handle user sessions // handle user sessions
const pgSession = pgConnect(session); const pgSession = pgConnect(session);
const sess = { const sess = {
name: 'cl.session', name: 'cl.session',
store: new pgSession({ store: new pgSession({
pool: pool, pool: pool,
tableName : 'user_sessions' tableName : 'user_sessions'
}), }),
secret: process.env.APP_COOKIE_SECRET, secret: process.env.APP_COOKIE_SECRET,
saveUninitialized: false, saveUninitialized: false,
resave: false, resave: false,
cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 } // 30 days cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 } // 30 days
}; };
if (server.get('env') === 'production') { if (server.get('env') === 'production') {
// trust first proxy // trust first proxy
server.set('trust proxy', 1) server.set('trust proxy', 1)
// serve secure cookies // serve secure cookies
sess.cookie.secure = true sess.cookie.secure = true
} }
server.use(session(sess)); server.use(session(sess));
@ -84,16 +85,16 @@ function frontendRoute(req, res) {
function renderHTML(context, data, req, res){ function renderHTML(context, data, req, res){
const markup = renderToString( const markup = renderToString(
<StaticRouter context={context} location={req.url}> <StaticRouter context={context} location={req.url}>
<App user={data.user} building={data.building} /> <App user={data.user} building={data.building} />
</StaticRouter> </StaticRouter>
); );
if (context.url) { if (context.url) {
res.redirect(context.url); res.redirect(context.url);
} else { } else {
res.status(context.status).send( res.status(context.status).send(
`<!doctype html> `<!doctype html>
<html lang=""> <html lang="">
<head> <head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
@ -127,34 +128,44 @@ function renderHTML(context, data, req, res){
</script> </script>
</body> </body>
</html>` </html>`
); );
} }
} }
// GET tiles // GET tiles
server.use('/tiles', tileserver); server.use('/tiles', tileserver);
// GET buildings
// not implemented - may be useful to GET all buildings, paginated
// GET building at point // GET buildings at point
server.get('/buildings.json', function(req, res){ server.get('/buildings/locate', function(req, res){
const { lng, lat } = req.query const { lng, lat } = req.query;
queryBuildingAtPoint(lng, lat).then(function(result){ queryBuildingsAtPoint(lng, lat).then(function(result){
if (result) { res.send(result);
res.send(result) }).catch(function(error){
} else { console.error(error);
res.status(404).send({error:'Not Found'}) res.send({error:'Database error'})
} })
}).catch(function(error){ });
res.send({error:'Database error'})
})
})
// Building routes // GET buildings by reference (UPRN/TOID or other identifier)
server.get('/buildings/reference', function(req, res){
const { key, id } = req.query;
queryBuildingsByReference(key, id).then(function(result){
res.send(result);
}).catch(function(error){
console.error(error);
res.send({error:'Database error'})
})
});
// GET individual building, POST building updates
server.route('/building/:building_id.json') server.route('/building/:building_id.json')
.get(function (req, res) { .get(function (req, res) {
const { building_id } = req.params; const { building_id } = req.params;
getBuildingById(building_id).then(function(result){ getBuildingById(building_id).then(function(result){
if (result) { if (result && result.length) {
res.send(result) res.send(result)
} else { } else {
res.status(404).send({error:'Not Found'}) res.status(404).send({error:'Not Found'})
@ -173,7 +184,6 @@ server.route('/building/:building_id.json')
) )
}) })
// POST new user // POST new user
server.post('/users', function(req, res){ server.post('/users', function(req, res){
const user = req.body; const user = req.body;
@ -184,8 +194,8 @@ server.post('/users', function(req, res){
if (user.email){ if (user.email){
if (user.email != user.confirm_email) { if (user.email != user.confirm_email) {
res.send({error: "Email did not match confirmation."}); res.send({error: "Email did not match confirmation."});
return return
} }
} else { } else {
user.email = null; user.email = null;
@ -221,6 +231,7 @@ server.post('/login', function(req, res){
// POST user logout // POST user logout
server.post('/logout', function(req, res){ server.post('/logout', function(req, res){
req.session.user_id = undefined;
req.session.destroy(function(err){ req.session.destroy(function(err){
if (err) { if (err) {
console.error(err); console.error(err);
@ -244,5 +255,4 @@ server.get('/users/me', function(req, res){
}); });
}); });
export default server; export default server;