From 0b3ad5e5691f9ccba4d629c50e13101d04a447e9 Mon Sep 17 00:00:00 2001 From: Javier Goizueta Date: Fri, 27 May 2016 12:19:47 +0200 Subject: [PATCH] Limit the maximum zoom level Avoid returning zoom levels greater than the maximum 'safe' level. For a zero denominator (which would imply and infinite zoom level) return the maximum level too. --- scripts-available/CDB_ZoomFromScale.sql | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts-available/CDB_ZoomFromScale.sql b/scripts-available/CDB_ZoomFromScale.sql index 1c59041..faa54b7 100644 --- a/scripts-available/CDB_ZoomFromScale.sql +++ b/scripts-available/CDB_ZoomFromScale.sql @@ -1,3 +1,17 @@ +-- Maximum supported zoom level +CREATE OR REPLACE FUNCTION _CDB_MaxSupportedZoom() +RETURNS int +LANGUAGE SQL +IMMUTABLE +AS $$ + -- The maximum zoom level has to be limited for various reasons, + -- e.g. zoom levels greater than 31 would require tile coordinates + -- that would not fit in an INTEGER (which is signed, 32 bits long). + -- We'll choose 20 as a limit which is safe also when the JavaScript shift + -- operator (<<) is used for computing powers of two. + SELECT 29; +$$; + CREATE OR REPLACE FUNCTION cartodb.CDB_ZoomFromScale(scaleDenominator numeric) RETURNS int LANGUAGE SQL @@ -5,8 +19,9 @@ IMMUTABLE AS $$ SELECT CASE - -- Don't bother if the scale is larger than ~zoom level 0 + -- Don't bother if the scale is larger than ~zoom level 0 WHEN scaleDenominator > 600000000 OR scaleDenominator = 0 THEN NULL - ELSE CAST (ROUND(LOG(2, 559082264.028/scaleDenominator)) AS INTEGER) + WHEN scaleDenominator = 0 THEN _CDB_MaxSupportedZoom() + ELSE CAST (LEAST(ROUND(LOG(2, 559082264.028/scaleDenominator)), _CDB_MaxSupportedZoom()) AS INTEGER) END; $$;