From aa302c237dd1c9c5060a0f3a3fed7d08b69ea698 Mon Sep 17 00:00:00 2001 From: Paul Norman Date: Mon, 8 Feb 2016 22:45:27 -0800 Subject: [PATCH 1/3] Use standard formula for CDB_ZoomFromScale postgis-vt-util comes with a standard formula for zoom from scaleDenominator, and this is well tested. This also fixes the function throwing an error on NULL input. --- scripts-available/CDB_ZoomFromScale.sql | 40 +++++++------------------ 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/scripts-available/CDB_ZoomFromScale.sql b/scripts-available/CDB_ZoomFromScale.sql index 6ded82e..1c59041 100644 --- a/scripts-available/CDB_ZoomFromScale.sql +++ b/scripts-available/CDB_ZoomFromScale.sql @@ -1,30 +1,12 @@ -CREATE OR REPLACE FUNCTION cartodb.CDB_ZoomFromScale(scaleDenominator numeric) RETURNS int AS $$ -BEGIN +CREATE OR REPLACE FUNCTION cartodb.CDB_ZoomFromScale(scaleDenominator numeric) +RETURNS int +LANGUAGE SQL +IMMUTABLE +AS $$ +SELECT CASE - WHEN scaleDenominator > 500000000 THEN RETURN 0; - WHEN scaleDenominator <= 500000000 AND scaleDenominator > 200000000 THEN RETURN 1; - WHEN scaleDenominator <= 200000000 AND scaleDenominator > 100000000 THEN RETURN 2; - WHEN scaleDenominator <= 100000000 AND scaleDenominator > 50000000 THEN RETURN 3; - WHEN scaleDenominator <= 50000000 AND scaleDenominator > 25000000 THEN RETURN 4; - WHEN scaleDenominator <= 25000000 AND scaleDenominator > 12500000 THEN RETURN 5; - WHEN scaleDenominator <= 12500000 AND scaleDenominator > 6500000 THEN RETURN 6; - WHEN scaleDenominator <= 6500000 AND scaleDenominator > 3000000 THEN RETURN 7; - WHEN scaleDenominator <= 3000000 AND scaleDenominator > 1500000 THEN RETURN 8; - WHEN scaleDenominator <= 1500000 AND scaleDenominator > 750000 THEN RETURN 9; - WHEN scaleDenominator <= 750000 AND scaleDenominator > 400000 THEN RETURN 10; - WHEN scaleDenominator <= 400000 AND scaleDenominator > 200000 THEN RETURN 11; - WHEN scaleDenominator <= 200000 AND scaleDenominator > 100000 THEN RETURN 12; - WHEN scaleDenominator <= 100000 AND scaleDenominator > 50000 THEN RETURN 13; - WHEN scaleDenominator <= 50000 AND scaleDenominator > 25000 THEN RETURN 14; - WHEN scaleDenominator <= 25000 AND scaleDenominator > 12500 THEN RETURN 15; - WHEN scaleDenominator <= 12500 AND scaleDenominator > 5000 THEN RETURN 16; - WHEN scaleDenominator <= 5000 AND scaleDenominator > 2500 THEN RETURN 17; - WHEN scaleDenominator <= 2500 AND scaleDenominator > 1500 THEN RETURN 18; - WHEN scaleDenominator <= 1500 AND scaleDenominator > 750 THEN RETURN 19; - WHEN scaleDenominator <= 750 AND scaleDenominator > 500 THEN RETURN 20; - WHEN scaleDenominator <= 500 AND scaleDenominator > 250 THEN RETURN 21; - WHEN scaleDenominator <= 250 AND scaleDenominator > 100 THEN RETURN 22; - WHEN scaleDenominator <= 100 THEN RETURN 23; - END CASE; -END -$$ LANGUAGE plpgsql IMMUTABLE; + -- 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) + END; +$$; From 0b3ad5e5691f9ccba4d629c50e13101d04a447e9 Mon Sep 17 00:00:00 2001 From: Javier Goizueta Date: Fri, 27 May 2016 12:19:47 +0200 Subject: [PATCH 2/3] 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; $$; From 2a30eb2fd3be4b0ae72ed4ea43ab4716fdca1ad8 Mon Sep 17 00:00:00 2001 From: Javier Goizueta Date: Fri, 27 May 2016 15:10:20 +0200 Subject: [PATCH 3/3] Fix zoom from scale condition for NULL result And rewrite in cleaner form. --- scripts-available/CDB_ZoomFromScale.sql | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/scripts-available/CDB_ZoomFromScale.sql b/scripts-available/CDB_ZoomFromScale.sql index faa54b7..6ef00d1 100644 --- a/scripts-available/CDB_ZoomFromScale.sql +++ b/scripts-available/CDB_ZoomFromScale.sql @@ -17,11 +17,20 @@ RETURNS int LANGUAGE SQL IMMUTABLE AS $$ -SELECT - CASE - -- Don't bother if the scale is larger than ~zoom level 0 - WHEN scaleDenominator > 600000000 OR scaleDenominator = 0 THEN NULL - WHEN scaleDenominator = 0 THEN _CDB_MaxSupportedZoom() - ELSE CAST (LEAST(ROUND(LOG(2, 559082264.028/scaleDenominator)), _CDB_MaxSupportedZoom()) AS INTEGER) - END; + SELECT + CASE + WHEN scaleDenominator > 600000000 THEN + -- Scale is smaller than zoom level 0 + NULL + WHEN scaleDenominator = 0 THEN + -- Actual zoom level would be infinite + _CDB_MaxSupportedZoom() + ELSE + CAST ( + LEAST( + ROUND(LOG(2, 559082264.028/scaleDenominator)), + _CDB_MaxSupportedZoom() + ) + AS INTEGER) + END; $$;