Skip to content

Commit

Permalink
feat(tile): Include the cluster expansion zoom level into the MVT til…
Browse files Browse the repository at this point in the history
…e properties (#27)
  • Loading branch information
cosmin-petrescu committed Nov 1, 2019
1 parent 25c5b56 commit cd9c0da
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 7 deletions.
43 changes: 41 additions & 2 deletions lib/__test__/__snapshots__/queries.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,114 +17,152 @@ exports[`createClusterQuery should create a clustered Query 1`] = `
FROM filtered),
grouped_clusters_10 AS
(SELECT SUM(theCount) AS theCount,
clusters AS clusterNo,
11 AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) AS center
FROM clustered_10
GROUP BY clusters),
clustered_9 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.01953125, 1) over () as clusters , a
FROM grouped_clusters_10),
grouped_clusters_9 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 10 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_9
GROUP BY clusters),
clustered_8 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.0390625, 1) over () as clusters , a
FROM grouped_clusters_9),
grouped_clusters_8 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 9 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_8
GROUP BY clusters),
clustered_7 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.078125, 1) over () as clusters , a
FROM grouped_clusters_8),
grouped_clusters_7 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 8 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_7
GROUP BY clusters),
clustered_6 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.15625, 1) over () as clusters , a
FROM grouped_clusters_7),
grouped_clusters_6 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 7 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_6
GROUP BY clusters),
clustered_5 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.3125, 1) over () as clusters , a
FROM grouped_clusters_6),
grouped_clusters_5 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 6 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_5
GROUP BY clusters),
clustered_4 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 0.625, 1) over () as clusters , a
FROM grouped_clusters_5),
grouped_clusters_4 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 5 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_4
GROUP BY clusters),
clustered_3 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 1.25, 1) over () as clusters , a
FROM grouped_clusters_4),
grouped_clusters_3 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 4 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_3
GROUP BY clusters),
clustered_2 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 2.5, 1) over () as clusters , a
FROM grouped_clusters_3),
grouped_clusters_2 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 3 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_2
GROUP BY clusters),
clustered_1 AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, 5, 1) over () as clusters , a
FROM grouped_clusters_2),
grouped_clusters_1 AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE 2 END) AS expansionZoom,
FIRST(a) as a,
ST_Centroid(ST_Collect(center)) as center
FROM clustered_1
Expand All @@ -133,13 +171,14 @@ exports[`createClusterQuery should create a clustered Query 1`] = `
tiled as
(SELECT center,
expansionZoom,
theCount , a
FROM grouped_clusters_1
WHERE ST_Intersects(TileBBox($4, $5, $6, 3857), ST_Transform(center, 3857))),
q as
(SELECT 1 as c1,
ST_AsMVTGeom(ST_Transform(center, 3857), TileBBox($7, $8, $9, 3857), $10, 10, false) AS geom,
jsonb_build_object('count', theCount, 'a', a) as attributes
jsonb_build_object('count', theCount, 'expansionZoom', expansionZoom, 'a', a) as attributes
FROM tiled)
SELECT ST_AsMVT(q, $11, $12, 'geom') as mvt
from q
Expand Down Expand Up @@ -175,7 +214,7 @@ WITH filtered AS
q as
(SELECT 1 as c1,
ST_AsMVTGeom(ST_Transform(wkb_geometry, 3857), TileBBox($4, $5, $6, 3857), $7, 10, false) AS geom,
jsonb_build_object('count', 1, 'a', a) as attributes
jsonb_build_object('count', 1, 'expansionZoom', 10, 'a', a) AS attributes
FROM filtered)
SELECT ST_AsMVT(q, $8, $9, 'geom') as mvt
from q
Expand Down
55 changes: 50 additions & 5 deletions lib/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ const unclusteredQuery = ({
z,
table,
geometry,
maxZoomLevel,
sourceLayer,
resolution,
attributes,
query,
}: {
x: number;
y: number;
z: number;
table: string;
geometry: string;
sourceLayer: string;
maxZoomLevel: number;
resolution: number;
attributes: string[];
query: string[];
}) =>
sql`
WITH filtered AS
Expand All @@ -31,9 +43,9 @@ WITH filtered AS
ST_AsMVTGeom(ST_Transform(${sql.raw(
geometry
)}, 3857), TileBBox(${z}, ${x}, ${y}, 3857), ${resolution}, 10, false) AS geom,
jsonb_build_object('count', 1${sql.raw(
attributesToArray(attributes)
)}) as attributes
jsonb_build_object('count', 1, 'expansionZoom', ${sql.raw(
`${maxZoomLevel}`
)}${sql.raw(attributesToArray(attributes))}) AS attributes
FROM filtered)
SELECT ST_AsMVT(q, ${sourceLayer}, ${resolution}, 'geom') as mvt
from q
Expand All @@ -50,17 +62,26 @@ const baseClusteredQuery = ({
sourceLayer,
resolution,
attributes = [],
}: {
filterBlock: string;
z: number;
x: number;
y: number;
sourceLayer: string;
resolution: number;
attributes: string[];
}) => sql`
${filterBlock}
tiled as
(SELECT center,
expansionZoom,
theCount ${sql.raw(attributesToSelect(attributes))}
${sql.raw(`FROM grouped_clusters_${z}`)}
WHERE ST_Intersects(TileBBox(${z}, ${x}, ${y}, 3857), ST_Transform(center, 3857))),
q as
(SELECT 1 as c1,
ST_AsMVTGeom(ST_Transform(center, 3857), TileBBox(${z}, ${x}, ${y}, 3857), ${resolution}, 10, false) AS geom,
jsonb_build_object('count', theCount${sql.raw(
jsonb_build_object('count', theCount, 'expansionZoom', expansionZoom${sql.raw(
attributesToArray(attributes)
)}) as attributes
FROM tiled)
Expand All @@ -81,6 +102,16 @@ const filterBlock = ({
query,
attributes,
additionalLevels,
}: {
x: number;
y: number;
z: number;
maxZoomLevel: number;
table: string;
geometry: string;
query: string[];
attributes: string[];
additionalLevels: string;
}) =>
sql`
with filtered as
Expand All @@ -105,6 +136,8 @@ const filterBlock = ({
FROM filtered),
${sql.raw(`grouped_clusters_${maxZoomLevel}`)} AS
(SELECT SUM(theCount) AS theCount,
clusters AS clusterNo,
${sql.raw(`${maxZoomLevel + 1}`)} AS expansionZoom,
${sql.raw(attributesFirstToSelect(attributes))}
ST_Centroid(ST_Collect(center)) AS center
${sql.raw(`FROM clustered_${maxZoomLevel}`)}
Expand All @@ -115,16 +148,27 @@ const filterBlock = ({
/**
* Creates an SQL fragment for the particular zoomLevel depending on zoomLevel - 1 for its data
*/
const additionalLevel = ({ zoomLevel, attributes }) => `
const additionalLevel = ({
zoomLevel,
attributes,
}: {
zoomLevel: number;
attributes: string[];
}) => `
clustered_${zoomLevel} AS
(SELECT center,
expansionZoom,
clusterNo AS previousClusterNo,
theCount,
ST_ClusterDBSCAN(center, ${zoomToDistance(
zoomLevel
)}, 1) over () as clusters ${attributesToSelect(attributes)}
FROM grouped_clusters_${zoomLevel + 1}),
grouped_clusters_${zoomLevel} AS
(SELECT SUM(theCount) as theCount,
clusters AS clusterNo,
(CASE COUNT(previousClusterNo) WHEN 1 THEN FIRST(expansionZoom) ELSE ${zoomLevel +
1} END) AS expansionZoom,
${attributesFirstToSelect(attributes)}
ST_Centroid(ST_Collect(center)) as center
FROM clustered_${zoomLevel}
Expand Down Expand Up @@ -217,6 +261,7 @@ export function createQueryForTile({
table,
geometry,
sourceLayer,
maxZoomLevel,
resolution,
attributes,
query,
Expand Down

0 comments on commit cd9c0da

Please sign in to comment.