From a2a0a6f3b7f0c92eb2d0721549a5727c7dc18b9a Mon Sep 17 00:00:00 2001 From: Andy Eschbacher Date: Thu, 21 Apr 2016 16:19:51 -0400 Subject: [PATCH] harmonizing functions with timespan --- src/pg/sql/44_observatory_geometries.sql | 91 ++++++++++++++++-------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/src/pg/sql/44_observatory_geometries.sql b/src/pg/sql/44_observatory_geometries.sql index f2d1c20..75c4beb 100644 --- a/src/pg/sql/44_observatory_geometries.sql +++ b/src/pg/sql/44_observatory_geometries.sql @@ -6,16 +6,15 @@ -- From an input point geometry, find the boundary which intersects with the centroid of the input geometry -CREATE OR REPLACE FUNCTION Andy_OBS_GetGeometry( - geom geometry(Geometry, 4326), - boundary_id text DEFAULT '"us.census.tiger".census_tract', -- TODO: from a specified column id list (e.g., list of available catalog, see OBS_List) - time_span text DEFAULT '2009 - 2013') - RETURNS geometry(Geometry, 4326) +CREATE OR REPLACE FUNCTION OBS_GetGeometry( + geom geometry(geometry, 4326), + boundary_id text, + time_span text DEFAULT NULL) +RETURNS geometry(geometry, 4326) AS $$ DECLARE - boundary geometry(Geometry, 4326); + boundary geometry(geometry, 4326); target_table text; - target_table_list text[]; BEGIN -- TODO: Check if SRID = 4326, if not transform? @@ -26,16 +25,29 @@ BEGIN RAISE EXCEPTION 'Invalid geometry type (%), expecting ''ST_Point''', ST_GeometryType(geom); END IF; - target_table_list := OBS_SearchTables(boundary_id, time_span); + -- choose appropriate table based on time_span + IF time_span IS NULL + THEN + SELECT x.target_tables INTO target_table + FROM _OBS_SearchTables(boundary_id, + time_span) As x(target_tables, + time_spans) + ORDER BY x.time_spans DESC + LIMIT 1; + ELSE + SELECT x.target_tables INTO target_table + FROM _OBS_SearchTables(boundary_id, + time_span) As x(target_tables, + time_spans) + WHERE x.time_spans = time_span + LIMIT 1; + END IF; -- if no tables are found, raise notice and return null - IF array_length(target_table_list, 1) IS NULL + IF target_table IS NULL THEN RAISE NOTICE 'No boundaries found for ''%'' in ''%''', ST_AsText(geom), boundary_id; RETURN NULL::geometry; - ELSE - -- else, choose first result - target_table = target_table_list[1]; END IF; RAISE NOTICE 'target_table: %', target_table; @@ -54,17 +66,16 @@ BEGIN END; $$ LANGUAGE plpgsql; -CREATE OR REPLACE FUNCTION ANDY_OBS_GetGeometryId( +CREATE OR REPLACE FUNCTION OBS_GetGeometryId( geom geometry(Geometry, 4326), - boundary_id text DEFAULT '"us.census.tiger".census_tract', - time_span text DEFAULT '2009 - 2013' + boundary_id text, + time_span text DEFAULT NULL ) RETURNS text AS $$ DECLARE output_id text; target_table text; - target_table_list text[]; BEGIN -- If not point, raise error @@ -73,15 +84,29 @@ BEGIN RAISE EXCEPTION 'Error: Invalid geometry type (%), expecting ''ST_Point''', ST_GeometryType(geom); END IF; - target_table_list := OBS_SearchTables(boundary_id, time_span); + -- choose appropriate table based on time_span + IF time_span IS NULL + THEN + SELECT x.target_tables INTO target_table + FROM cdb_observatory._OBS_SearchTables(boundary_id, + time_span) As x(target_tables, + time_spans) + ORDER BY x.time_spans DESC + LIMIT 1; + ELSE + SELECT x.target_tables INTO target_table + FROM cdb_observatory._OBS_SearchTables(boundary_id, + time_span) As x(target_tables, + time_spans) + WHERE x.time_spans = time_span + LIMIT 1; + END IF; -- if no tables are found, raise error - IF array_length(target_table_list, 1) IS NULL + IF target_table IS NULL THEN RAISE NOTICE 'Error: No boundaries found for ''%''', boundary_id; RETURN NULL::text; - ELSE - target_table = target_table_list[1]; END IF; RAISE NOTICE 'target_table: %', target_table; @@ -102,17 +127,18 @@ $$ LANGUAGE plpgsql; -- Given a geometry reference (e.g., geoid for US Census), and it's geometry level (see OBS_ListGeomColumns() for all available boundary ids), give back the boundary that corresponds to that reference and level. --- @param geom_ref text: identifier for boundary geometry corresponding to a boundary id `boundary_id`. E.g., '36047' is a geoid for US Census Tiger boundaries corresponding to a county (047) in New York State (36) +-- @param geometry_id text: identifier for boundary geometry corresponding to a boundary id `boundary_id`. E.g., '36047' is a geoid for US Census Tiger boundaries corresponding to a county (047) in New York State (36) -- @param boundary_id: -CREATE OR REPLACE FUNCTION OBS_GetGeometryById( - geom_ref text, -- ex: '36047' - boundary_id text -- ex: '"us.census.tiger".county' +CREATE OR REPLACE FUNCTION ANDY_OBS_GetGeometryById( + geometry_id text, -- ex: '36047' + boundary_id text, -- ex: '"us.census.tiger".county' + time_span text DEFAULT NULL --ex: '2009' ) RETURNS geometry(geometry, 4326) AS $$ DECLARE - boundary geometry; + boundary geometry(geometry, 4326); target_table text; geoid_colname text; geom_colname text; @@ -138,10 +164,12 @@ BEGIN AND geoid_ct.table_id = geom_t.id and geom_t.id = geom_ct.table_id and geom_ct.column_id = geom_c.id and - geom_c.type ilike 'geometry' + geom_c.type ILIKE 'geometry' $string$, boundary_id ) INTO geoid_colname, target_table, geom_colname; + RAISE NOTICE '%', target_table; + IF target_table IS NULL THEN RAISE NOTICE 'No geometries found'; @@ -150,12 +178,13 @@ BEGIN -- retrieve boundary EXECUTE - 'SELECT t.$1 - FROM observatory.$2 As t - WHERE t.$1 = ''$3'' - LIMIT 1' + format( + 'SELECT t.%s + FROM observatory.%I As t + WHERE t.%s = $1 + LIMIT 1', geom_colname, target_table, geoid_colname) INTO boundary - USING geom_colname, target_table, geom_ref; + USING geometry_id; RETURN boundary;