Aggregation: Style improvements
This commit is contained in:
@@ -6,7 +6,7 @@ const debug = require('debug')('backend:cluster');
|
||||
const AggregationMapConfig = require('../models/aggregation/aggregation-mapconfig');
|
||||
|
||||
const windshaftUtils = require('windshaft').utils;
|
||||
const wmh = new windshaftUtils.WebMercatorHelper();
|
||||
const webmercator = new windshaftUtils.WebMercatorHelper();
|
||||
|
||||
module.exports = class ClusterBackend {
|
||||
getClusterFeatures (mapConfigProvider, params, callback) {
|
||||
@@ -159,8 +159,8 @@ const clusterFeaturesQuery = ctx => `
|
||||
`;
|
||||
|
||||
const gridResolution = ctx => {
|
||||
const zoom_resolution = wmh.getResolution({ z : Math.min(38, ctx.zoom) });
|
||||
return `${256/ctx.res} * (${zoom_resolution})::double precision`;
|
||||
const zoomResolution = webmercator.getResolution({ z : Math.min(38, ctx.zoom) });
|
||||
return `${256/ctx.res} * (${zoomResolution})::double precision`;
|
||||
};
|
||||
|
||||
const aggregationQuery = ctx => `
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
const timeDimension = require('./time-dimension');
|
||||
|
||||
const DEFAULT_PLACEMENT = 'point-sample';
|
||||
const windshaftUtils = require('windshaft').utils;
|
||||
const webmercator = new windshaftUtils.WebMercatorHelper();
|
||||
|
||||
function optionsToParams (options) {
|
||||
return {
|
||||
@@ -265,16 +267,18 @@ const havingClause = ctx => {
|
||||
// We limit the the minimum resolution to avoid division by zero problems. The limit used is
|
||||
// the pixel size of zoom level 30 (i.e. 1/2*(30+8) of the full earth web-mercator extent), which is about 0.15 mm.
|
||||
//
|
||||
// NOTE: We'd rather use !scale_denominator!, but in Mapnik this value is extent / 256 for raster
|
||||
// NOTE: We'd rather use !pixel_width!, but in Mapnik this value is extent / 256 for raster
|
||||
// and extent / tile_extent {4096 default} for MVT, so since aggregations are always based
|
||||
// on 256 we can't have the same query in both cases
|
||||
// As this scale change doesn't happen in !scale_denominator! we use that instead
|
||||
// NOTE 2: The 0.00028 is used in Mapnik (and replicated in pg-mvt) and comes from
|
||||
// OGC's Styled Layer Descriptor Implementation Specification
|
||||
const gridResolution = ctx => {
|
||||
const minimumResolution = 2*Math.PI*6378137/Math.pow(2,38);
|
||||
const minimumResolution = webmercator.getResolution({ z : 38 });
|
||||
return `${256/ctx.res} * GREATEST(!scale_denominator! * 0.00028, ${minimumResolution})::double precision`;
|
||||
};
|
||||
|
||||
// SQL query to extra the boundaries of the area to be aggregated and the grid resolution
|
||||
// SQL query to extract the boundaries of the area to be aggregated and the grid resolution
|
||||
// cdb_{x-y}{min_max} return the limits of the tile. Aggregations do [min, max) in both axis
|
||||
// cdb_res: Aggregation resolution (as specified by gridResolution)
|
||||
// cdb_point_bbox: Tile bounding box [min, max]
|
||||
@@ -311,17 +315,17 @@ const aggregatedPointWebMercator = (ctx) => {
|
||||
switch (ctx.placement) {
|
||||
|
||||
// For centroid, we return the average of the cell
|
||||
case `centroid`:
|
||||
return `, ST_SetSRID(ST_MakePoint(AVG(cdb_x), AVG(cdb_y)), 3857) AS the_geom_webmercator`;
|
||||
case 'centroid':
|
||||
return ', ST_SetSRID(ST_MakePoint(AVG(cdb_x), AVG(cdb_y)), 3857) AS the_geom_webmercator';
|
||||
|
||||
// Middle point of the cell
|
||||
case `point-grid`:
|
||||
case 'point-grid':
|
||||
return `, ST_SetSRID(ST_MakePoint(cdb_pos_grid_x, cdb_pos_grid_y), 3857) AS the_geom_webmercator`;
|
||||
|
||||
// For point-sample we'll get a single point directly from the source
|
||||
// If it's default aggregation we'll add the extra columns to keep backwards compatibility
|
||||
case `point-sample`:
|
||||
return ``;
|
||||
case 'point-sample':
|
||||
return '';
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid aggregation placement "${ctx.placement}`);
|
||||
@@ -332,16 +336,17 @@ const aggregatedPointWebMercator = (ctx) => {
|
||||
const aggregatedPointJoin = (ctx) => {
|
||||
switch (ctx.placement) {
|
||||
|
||||
case `centroid`:
|
||||
return ``;
|
||||
case 'centroid':
|
||||
return '';
|
||||
|
||||
case `point-grid`:
|
||||
return ``;
|
||||
case 'point-grid':
|
||||
return '';
|
||||
|
||||
// For point-sample we'll get a single point directly from the source
|
||||
// If it's default aggregation we'll add the extra columns to keep backwards compatibility
|
||||
case `point-sample`:
|
||||
return `NATURAL JOIN
|
||||
case 'point-sample':
|
||||
return `
|
||||
NATURAL JOIN
|
||||
(
|
||||
SELECT ${ctx.isDefaultAggregation ? `*` : `cartodb_id, the_geom_webmercator`}
|
||||
FROM
|
||||
@@ -352,7 +357,7 @@ const aggregatedPointJoin = (ctx) => {
|
||||
`;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid aggregation placement "${ctx.placement}`);
|
||||
throw new Error('Invalid aggregation placement "${ctx.placement}"');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const TestClient = require('../support/test-client');
|
||||
const serverOptions = require('../../lib/cartodb/server_options');
|
||||
|
||||
const windshaftUtils = require('windshaft').utils;
|
||||
const wmh = new windshaftUtils.WebMercatorHelper();
|
||||
const webmercator = new windshaftUtils.WebMercatorHelper();
|
||||
|
||||
const suites = [
|
||||
{
|
||||
@@ -112,15 +112,15 @@ describe('aggregation', function () {
|
||||
WITH hgrid AS (
|
||||
SELECT
|
||||
CDB_RectangleGrid (
|
||||
ST_Expand(!bbox!, ${wmh.getResolution({ z : 1 })} * 12),
|
||||
${wmh.getResolution({ z : 1 })} * 12,
|
||||
${wmh.getResolution({ z : 1 })} * 12
|
||||
ST_Expand(!bbox!, ${webmercator.getResolution({ z : 1 })} * 12),
|
||||
${webmercator.getResolution({ z : 1 })} * 12,
|
||||
${webmercator.getResolution({ z : 1 })} * 12
|
||||
) as cell
|
||||
)
|
||||
SELECT
|
||||
hgrid.cell as the_geom_webmercator,
|
||||
count(1) as agg_value,
|
||||
count(1) /power( 12 * ${wmh.getResolution({ z : 1 })}, 2 ) as agg_value_density,
|
||||
count(1) /power( 12 * ${webmercator.getResolution({ z : 1 })}, 2 ) as agg_value_density,
|
||||
row_number() over () as cartodb_id
|
||||
FROM hgrid, (<%= sql %>) i
|
||||
WHERE ST_Intersects(i.the_geom_webmercator, hgrid.cell) GROUP BY hgrid.cell
|
||||
@@ -207,7 +207,7 @@ describe('aggregation', function () {
|
||||
//
|
||||
const POINTS_SQL_GRID = (z, resolution) => `
|
||||
WITH params AS (
|
||||
SELECT ${wmh.getResolution({ z : z })}*${resolution} AS l -- cell size for Z, resolution
|
||||
SELECT ${webmercator.getResolution({ z : z })}*${resolution} AS l -- cell size for Z, resolution
|
||||
)
|
||||
SELECT
|
||||
row_number() OVER () AS cartodb_id,
|
||||
|
||||
Reference in New Issue
Block a user