mod_workspace_templates_cluster.js
/**
### /workspace/templates/cluster
The cluster layer query template returns aggregated cluster features.
@module /workspace/templates/cluster
*/
export default (_) => {
_.qID ??= _.layer.qID || null;
_.geom ??= _.layer.geom;
const fields = [];
const aggFields = [];
_.fieldsMap &&
Array.from(_.fieldsMap.entries()).forEach((entry) => {
const [key, value] = entry;
fields.push(`(${value}) as ${key}`);
aggFields.push(`
CASE WHEN count(*)::int = 1
THEN (array_agg(${value}))[1]
END as ${key}`);
});
const where = _.viewport || `AND ${_.geom} IS NOT NULL`;
// Calculate grid resolution (r) based on zoom level and resolution parameter.
const r = parseInt((40075016.68 / Math.pow(2, _.z)) * _.resolution);
return `
SELECT
ARRAY[x_round, y_round],
count(*)::int,
CASE
WHEN count(*)::int = 1 THEN (array_agg(id))[1]::varchar
ELSE CONCAT('!',(array_agg(id))[1]::varchar)
END AS id
${fields.length ? ',' + aggFields.join() : ''}
FROM (
SELECT
${_.qID} as id,
${fields.length ? fields.join() + ',' : ''}
round(ST_X(${_.geom}) / ${r}) * ${r} x_round,
round(ST_Y(${_.geom}) / ${r}) * ${r} y_round
FROM ${_.table}
WHERE TRUE ${where} \${filter}) grid
GROUP BY x_round, y_round;`;
};