From 0f47659cf9ee25a6b6bb548707a60d1d8f2c983f Mon Sep 17 00:00:00 2001 From: abelvm Date: Thu, 18 Aug 2016 16:13:56 -0400 Subject: [PATCH] smart resolution guessing --- doc/19_contour.md | 11 +++++--- src/pg/sql/19_contour.sql | 40 ++++++++++++++++++++--------- src/pg/test/sql/19_contour_test.sql | 2 +- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/doc/19_contour.md b/doc/19_contour.md index f34f7c0..d6629e4 100644 --- a/doc/19_contour.md +++ b/doc/19_contour.md @@ -14,11 +14,11 @@ Function to generate a contour map from an scatter dataset of points, using one |------|------|-------------| | geom | geometry[] | Array of points's geometries | | values | numeric[] | Array of points' values for the param under study| -| resolution | integer | Size in meters of the cells in the grid| | buffer | numeric | Value between 0 and 1 for spatial buffer of the set of points | method | integer | 0:nearest neighbor, 1: barycentric, 2: IDW| | classmethod | integer | 0:equals, 1: heads&tails, 2:jenks, 3:quantiles | | steps | integer | Number of steps in the classification| +| max_time | integer | Max time in millisecons for processing time ### Returns Returns a table object @@ -37,11 +37,14 @@ Returns a table object WITH a AS ( SELECT ARRAY[800, 700, 600, 500, 400, 300, 200, 100]::numeric[] AS vals, - ARRAY[ST_GeomFromText('POINT(2.1744 41.403)'),ST_GeomFromText('POINT(2.1228 41.380)'),ST_GeomFromText('POINT(2.1511 41.374)'),ST_GeomFromText('POINT(2.1528 41.413)'),ST_GeomFromText('POINT(2.165 41.391)'),ST_GeomFromText('POINT(2.1498 41.371)'),ST_GeomFromText('POINT(2.1533 41.368)'),ST_GeomFromText('POINT(2.131386 41.41399)')] AS g -) + ARRAY[ST_GeomFromText('POINT(2.1744 41.403)',4326),ST_GeomFromText('POINT(2.1228 41.380)',4326),ST_GeomFromText('POINT(2.1511 41.374)',4326),ST_GeomFromText('POINT(2.1528 41.413)',4326),ST_GeomFromText('POINT(2.165 41.391)',4326),ST_GeomFromText('POINT(2.1498 41.371)',4326),ST_GeomFromText('POINT(2.1533 41.368)',4326),ST_GeomFromText('POINT(2.131386 41.41399)',4326)] AS g +), +b as( SELECT foo.* FROM a, - CDB_contour(a.g, a.vals, 500, 0.0, 1,3,5) foo; + cdb_crankshaft.CDB_contour(a.g, a.vals, 0.0, 1, 3, 5, 60) foo +) +SELECT bin, avg_value from b order by bin; ``` diff --git a/src/pg/sql/19_contour.sql b/src/pg/sql/19_contour.sql index 528ad9a..c0a64c2 100644 --- a/src/pg/sql/19_contour.sql +++ b/src/pg/sql/19_contour.sql @@ -1,11 +1,11 @@ CREATE OR REPLACE FUNCTION CDB_Contour( IN geomin geometry[], IN colin numeric[], - IN resolution integer, IN buffer numeric, IN intmethod integer, IN classmethod integer, - IN steps integer + IN steps integer, + IN max_time integer DEFAULT 60000 ) RETURNS TABLE( the_geom geometry, @@ -15,19 +15,28 @@ RETURNS TABLE( avg_value numeric ) AS $$ DECLARE - cell numeric; + cell_count integer; tin geometry[]; BEGIN -- calc the cell size in web mercator units - WITH center as ( - SELECT ST_centroid(ST_Collect(geomin)) as c - ) - SELECT - round(resolution / cos(ST_y(c) * pi()/180)) - INTO cell - FROM center; + -- WITH center as ( + -- SELECT ST_centroid(ST_Collect(geomin)) as c + -- ) + -- SELECT + -- round(resolution / cos(ST_y(c) * pi()/180)) + -- INTO cell + -- FROM center; -- raise notice 'Resol: %', cell; + -- calc the optimal number of cells for the current dataset + SELECT + CASE intmethod + WHEN 0 THEN round(3.7745903782 * max_time - 9.4399210051 * array_length(geomin,1) - 1350.8778213073) + WHEN 1 THEN round(2.2855592156 * max_time - 87.285217133 * array_length(geomin,1) + 17255.7085601797) + WHEN 2 THEN round(0.9799471999 * max_time - 127.0334085369 * array_length(geomin,1) + 22707.9579721218) + ELSE 10000 + END INTO cell_count; + -- we don't have iterative barycentric interpolation in CDB_interpolation, -- and it's a costy function, so let's make a custom one here till -- we update the code @@ -59,10 +68,17 @@ BEGIN ST_Transform(e, 3857) as geom FROM envelope ), + resolution as( + SELECT + round(|/ ( + ST_area(geom) / cell_count + )) as cell + FROM envelope3857 + ), grid as( SELECT - ST_Transform(cdb_crankshaft.CDB_RectangleGrid(geom, cell, cell), 4326) as geom - FROM envelope3857 + ST_Transform(cdb_crankshaft.CDB_RectangleGrid(e.geom, r.cell, r.cell), 4326) as geom + FROM envelope3857 e, resolution r ), interp as( SELECT diff --git a/src/pg/test/sql/19_contour_test.sql b/src/pg/test/sql/19_contour_test.sql index eb1da6c..70e5cf9 100644 --- a/src/pg/test/sql/19_contour_test.sql +++ b/src/pg/test/sql/19_contour_test.sql @@ -12,6 +12,6 @@ SELECT foo.* FROM a, - cdb_crankshaft.CDB_contour(a.g, a.vals, 500, 0.0, 1, 3, 5) foo + cdb_crankshaft.CDB_contour(a.g, a.vals, 0.0, 1, 3, 5, 60) foo ) SELECT bin, avg_value from b order by bin;