Skip to content

Commit

Permalink
topojson simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
nyurik committed Jan 8, 2018
1 parent 2e46ecb commit aa896b7
Showing 1 changed file with 70 additions and 16 deletions.
86 changes: 70 additions & 16 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,42 +76,96 @@ async function handleRequest(req, resp) {
}
}

async function processQueryRequest(req, resp) {
// Allowed params (per topojson code)
const NUMERIC_PARAMS = {
// 'planarArea': { 'desc': 'minimum planar triangle area (absolute)' },
// 'planarQuantile': { 'desc': 'minimum planar triangle area (quantile)', max: 1 },
'sphericalArea': {'desc': 'minimum spherical excess (absolute)'},
'sphericalQuantile': {'desc': 'minimum spherical excess (quantile)', max: 1},
};

function parseParams(req) {

const sparql = req.query.sparql;
if (!sparql) {
throw new MyError(400, `bad sparql parameter`);
}

const type = req.params.type;
if (type !== `geojson.json` && type !== `topojson.json`) {
throw new MyError(400, `bad type parameter`);
throw new MyError(400, `bad type parameter. Allows "geojson.json" and "topojson.json"`);
}

const qres = await sparqlService.query(sparql, `id`);
let param, value;
for (const name of Object.keys(NUMERIC_PARAMS)) {
if (req.query.hasOwnProperty(name)) {
if (param) {
throw new Error(`${name} parameter cannot be used together with ${param}`);
}
value = parseFloat(req.query[name]);
const info = NUMERIC_PARAMS[name];
param = name;
if (!(value.toString() === req.query[name] && value >= 0 && value <= (info.max || Number.MAX_VALUE))) {
throw new Error(`${name} parameter, ${info.desc}, must be a non-negative number` +
(info.max ? ` not larger than ${info.max}` : ''));
}
}
}

const pres = await postgresService.query(secrets.table, Object.keys(qres));
const filter = req.params.filter;
if (filter !== undefined && filter !== `all` && filter !== `detached`) {
throw new MyError(400, `bad filter parameter. Allows "all" and "detached"`);
}

return {sparql, param, value, type, filter};
}

async function processQueryRequest(req, resp) {
let {sparql, param, value, type, filter} = parseParams(req);

const qres = await sparqlService.query(sparql, `id`);
const pres = await postgresService.query(secrets.table, Object.keys(qres));
let result = PostgresService.toGeoJSON(pres, qres);

switch (type) {
case `geojson.json`:
resp.status(200).type(`application/geo+json`).send(result);
break;
console.log(new Date().toISOString(), type, param || 'noSimpl', value || 0, filter || 'noFilter', result.length, req.headers[`x-real-ip`], sparql);

case `topojson.json`:
if (param || type === `topojson.json`) {

result = topojson.topology({data: JSON.parse(result)}, {
// preserve all properties
"property-transform": feature => feature.properties
'property-transform': feature => feature.properties
});
result = JSON.stringify(result);

resp.status(200).type(`application/topo+json`).send(result);
break;
if (param) {
const system = (param === 'sphericalArea' || param === 'sphericalQuantile') ? `spherical` : `planar`;

default:
throw new Error();
result = topojson.presimplify(result, topojson[system + `TriangleArea`]);

if (param === 'planarQuantile' || param === 'sphericalQuantile') {
value = topojson.quantile(result, value);
param = system + `Area`;
res.header(`X-Equivalent-${param}`, value.toString());
}

result = topojson.simplify(result, value);

if (filter) {
const filterFunc = filter === 'all' ? topojson.filterWeight : topojson.filterAttachedWeight;
result = topojson.filter(result, filterFunc(result, value, topojson[system + `RingArea`]));
}

const transform = result.transform;
if (transform) {
result = topojson.quantize(result, transform);
}

if (type === `geojson.json`) {
result = topojson.feature(result, result.objects.data);
}
}
}

console.log(new Date().toISOString(), type, result.length, req.headers[`x-real-ip`], sparql);
const contentType = type === 'geojson.json' ? 'application/geo+json' : 'application/topo+json';

resp.status(200).type(contentType).send(result);
}

0 comments on commit aa896b7

Please sign in to comment.