Skip to content

Commit

Permalink
adds dynamic column name selection and groups results by geographic l…
Browse files Browse the repository at this point in the history
…evel
  • Loading branch information
jspeis committed Mar 8, 2018
1 parent e018a74 commit ee10c90
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions src/api/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {Router} from "express";

import levels from "config/levels.json";
import {version} from "package";
import dbgeo from "dbgeo";

const levels = require("config/acs_levels.json");


function topofy(data, httpResult) {
const precision = 5;
const quantization = 100000;
Expand All @@ -23,13 +25,30 @@ const levelLookup = geoId => {
"140": "tract",
"050": "county",
"040": "state",
"310": "msa",
"160": "place",
"860": "zip",
"795": "puma",
"970": "school-district"
};
return levelMap[prefix];
};


const groupByLevel = dataArr => {
const result = {};
dataArr.forEach(row => {
const geoId = row.geoid;
const myPrefix = geoId.slice(0, 3);
const lvl = levelLookup(myPrefix);
if (!Object.keys(result).includes(lvl)) {
result[lvl] = [];
}
result[lvl].push(row);
});
return result;
}

export default ({db}) => {
const api = new Router();

Expand All @@ -48,8 +67,8 @@ export default ({db}) => {
}

const targetTable = `${levels[level].schema}.${levels[level].table}`;

const qry = `SELECT * from ${targetTable} s1,
const cols = levels[level].columns.map(x => `s2."${x}"`).join(",") || "*";
const qry = `SELECT ${cols} from ${targetTable} s1,
${targetTable} s2
WHERE ST_Touches(s1.geom, s2.geom)
AND s1.geoid = $1;`;
Expand Down Expand Up @@ -131,29 +150,32 @@ export default ({db}) => {
});
});

api.get("/related", (req, httpResult) => {
const geoId = req.query.target;
// const gisCmd = req.params.op === "within" ? "ST_Within" : "ST_Intersects";
api.get("/related/:geoId", (req, httpResult) => {
const geoId = req.params.geoId || req.query.target;
const level1 = levelLookup(geoId);
const includeGeom = req.query.includeGeom ? ", s2.geom" : "";

const targetTable1 = `${levels[level1].schema}.${levels[level1].table}`;
const targetId1 = levels[level1].id;

const queries = [];

Object.keys(levels).forEach(level => {
const targetTable2 = `${levels[level].schema}.${levels[level].table}`;

const qry = `SELECT s2.geoid, s2.name ${includeGeom} from ${targetTable1} s1,
${targetTable2} s2
WHERE (ST_Area(st_intersection(s2.geom, s1.geom)) / st_area(s1.geom)) > 0.001
AND s1.${targetId1} = $1`;
queries.push(qry);
if (level !== level1) {
const targetTable2 = `${levels[level].schema}.${levels[level].table}`;
const nameColumn2 = levels[level].nameColumn || "name";
const gidColumn2 = levels[level].geoColumn || "geoid";
const qry = `SELECT s2."${gidColumn2}", s2."${nameColumn2}" as name ${includeGeom} from ${targetTable1} s1,
${targetTable2} s2
WHERE ST_Intersects(s2.geom, s1.geom)
AND s1.${targetId1} = $1`;
queries.push(qry);
}
});

Promise.all(queries.map(q => db.query(q, geoId)))
.then(values => values.reduce((acc, x) => [...acc, ...x], []))
.then(results => topofy(results, httpResult))
.then(groupByLevel)
.then(results => httpResult.json(results))
.catch(error => {
console.error("An error occured", error);
httpResult.json({error});
Expand Down

0 comments on commit ee10c90

Please sign in to comment.