getmeasure bypassing several older functions, areas not yet implemented
This commit is contained in:
@@ -37,81 +37,6 @@ END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
|
||||
-- A function that gets the column data for multiple columns
|
||||
-- Old: OBS_GetColumnData
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory._OBS_GetColumnData(
|
||||
geometry_id text,
|
||||
column_ids text[],
|
||||
timespan text
|
||||
)
|
||||
RETURNS SETOF JSON
|
||||
AS $$
|
||||
BEGIN
|
||||
|
||||
-- figure out highest-weight geometry_id/timespan pair for the first data column
|
||||
-- TODO this should be done for each data column separately
|
||||
IF geometry_id IS NULL OR timespan IS NULL THEN
|
||||
EXECUTE '
|
||||
SELECT data_t.timespan timespan, geom_c.id boundary_id
|
||||
FROM observatory.obs_table data_t,
|
||||
observatory.obs_column_table data_ct,
|
||||
observatory.obs_column data_c,
|
||||
observatory.obs_column_table geoid_ct,
|
||||
observatory.obs_column_to_column c2c,
|
||||
observatory.obs_column geom_c
|
||||
WHERE data_c.id = $2
|
||||
AND data_ct.column_id = data_c.id
|
||||
AND data_ct.table_id = data_t.id
|
||||
AND geoid_ct.table_id = data_t.id
|
||||
AND geoid_ct.column_id = c2c.source_id
|
||||
AND c2c.reltype = ''geom_ref''
|
||||
AND geom_c.id = c2c.target_id
|
||||
AND CASE WHEN $3 IS NULL THEN True ELSE $3 = timespan END
|
||||
AND CASE WHEN $1 IS NULL THEN True ELSE $1 = geom_c.id END
|
||||
ORDER BY geom_c.weight DESC,
|
||||
data_t.timespan DESC
|
||||
LIMIT 1
|
||||
' INTO timespan, geometry_id
|
||||
USING geometry_id, (column_ids)[1], timespan;
|
||||
END IF;
|
||||
|
||||
RETURN QUERY
|
||||
EXECUTE '
|
||||
WITH geomref AS (
|
||||
SELECT ct.table_id id
|
||||
FROM observatory.OBS_column_to_column c2c,
|
||||
observatory.OBS_column_table ct
|
||||
WHERE c2c.reltype = ''geom_ref''
|
||||
AND c2c.target_id = $1
|
||||
AND c2c.source_id = ct.column_id
|
||||
),
|
||||
column_ids as (
|
||||
select row_number() over () as no, a.column_id as column_id from (select unnest($2) as column_id) a
|
||||
)
|
||||
SELECT row_to_json(a) from (
|
||||
select colname,
|
||||
tablename,
|
||||
aggregate,
|
||||
name,
|
||||
type,
|
||||
c.description,
|
||||
$1 AS boundary_id
|
||||
FROM column_ids, observatory.OBS_column c, observatory.OBS_column_table ct, observatory.OBS_table t
|
||||
WHERE column_ids.column_id = c.id
|
||||
AND c.id = ct.column_id
|
||||
AND t.id = ct.table_id
|
||||
AND t.timespan = $3
|
||||
AND t.id in (SELECT id FROM geomref)
|
||||
order by column_ids.no
|
||||
) a
|
||||
'
|
||||
USING geometry_id, column_ids, timespan
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
--Test point cause Stuart always seems to make random points in the water
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory._TestPoint()
|
||||
RETURNS geometry(Point, 4326)
|
||||
@@ -158,28 +83,6 @@ BEGIN
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory._OBS_GetRelatedColumn(columns_ids text[], reltype text )
|
||||
RETURNS TEXT[]
|
||||
AS $$
|
||||
DECLARE
|
||||
result TEXT[];
|
||||
BEGIN
|
||||
EXECUTE '
|
||||
With ids as (
|
||||
select row_number() over() as no, id from (select unnest($1) as id) t
|
||||
)
|
||||
select array_agg(target_id order by no)
|
||||
FROM ids
|
||||
LEFT JOIN observatory.obs_column_to_column
|
||||
on source_id = id
|
||||
where reltype = $2 or reltype is null
|
||||
'
|
||||
INTO result
|
||||
using columns_ids, reltype;
|
||||
return result;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Function that replaces all non digits or letters with _ trims and lowercases the
|
||||
-- passed measure name
|
||||
|
||||
|
||||
@@ -345,37 +345,91 @@ CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetMeasure(
|
||||
RETURNS NUMERIC
|
||||
AS $$
|
||||
DECLARE
|
||||
map_type TEXT;
|
||||
numer_aggregate TEXT;
|
||||
numer_colname TEXT;
|
||||
numer_geomref_colname TEXT;
|
||||
numer_tablename TEXT;
|
||||
denom_colname TEXT;
|
||||
denom_geomref_colname TEXT;
|
||||
denom_tablename TEXT;
|
||||
geom_colname TEXT;
|
||||
geom_geomref_colname TEXT;
|
||||
geom_tablename TEXT;
|
||||
result NUMERIC;
|
||||
measure_ids TEXT[];
|
||||
denominator_id TEXT;
|
||||
vals NUMERIC[];
|
||||
sql TEXT;
|
||||
BEGIN
|
||||
|
||||
IF normalize ILIKE 'area' THEN
|
||||
measure_ids := ARRAY[measure_id];
|
||||
ELSIF normalize ILIKE 'denominator' THEN
|
||||
EXECUTE 'SELECT (cdb_observatory._OBS_GetRelatedColumn(ARRAY[$1], ''denominator''))[1]
|
||||
' INTO denominator_id
|
||||
USING measure_id;
|
||||
measure_ids := ARRAY[measure_id, denominator_id];
|
||||
ELSIF normalize ILIKE 'none' THEN
|
||||
-- TODO we need a switch on obs_get to disable area normalization
|
||||
RAISE EXCEPTION 'No normalization not yet supported.';
|
||||
EXECUTE
|
||||
$query$
|
||||
SELECT numer_aggregate, numer_colname, numer_geomref_colname, numer_tablename,
|
||||
denom_colname, denom_geomref_colname, denom_tablename,
|
||||
geom_colname, geom_geomref_colname, geom_tablename
|
||||
FROM observatory.obs_meta
|
||||
WHERE (geom_id = $1 OR ($1 = ''))
|
||||
AND numer_id = $2
|
||||
AND (numer_timespan = $3 OR ($3 = ''))
|
||||
ORDER BY geom_weight DESC, numer_timespan DESC
|
||||
LIMIT 1
|
||||
$query$
|
||||
INTO numer_colname, numer_geomref_colname, numer_table,
|
||||
denom_colname, denom_geomref_colname, denom_table,
|
||||
geom_colname, geom_geomref_colname, geom_table
|
||||
USING COALESCE(boundary_id, ''), measure_id, COALESCE(time_span, '');
|
||||
|
||||
IF normalize ILIKE 'area' AND numer_aggregate ILIKE 'sum' THEN
|
||||
-- area normalized
|
||||
map_type := 'areaNormalized';
|
||||
ELSIF normalize ILIKE 'denominator' AND numer_aggregate ILIKE 'sum' THEN
|
||||
-- denominated
|
||||
map_type := 'denominated';
|
||||
ELSE
|
||||
RAISE EXCEPTION 'Only valid inputs for "normalize" are "area" (default) and "denominator".';
|
||||
-- predenominated
|
||||
map_type := 'predenominated';
|
||||
END IF;
|
||||
|
||||
EXECUTE '
|
||||
SELECT ARRAY_AGG(val) FROM (SELECT (cdb_observatory._OBS_Get($1, $2, $3, $4)->>''value'')::NUMERIC val) b
|
||||
'
|
||||
INTO vals
|
||||
USING geom, measure_ids, time_span, boundary_id;
|
||||
|
||||
IF normalize ILIKE 'denominator' THEN
|
||||
RETURN (vals)[1]/(vals)[2];
|
||||
IF ST_GeometryType(geom) = 'ST_Point' THEN
|
||||
IF map_type = 'areaNormalied' THEN
|
||||
sql = format('SELECT numer.%I / (ST_Area(geom.%I::Geography) * 1000000)
|
||||
FROM observatory.%I numer, observatory.%I geom
|
||||
WHERE numer.%I = geom.%I
|
||||
AND ST_WITHIN(%L, geom.%I)',
|
||||
numer_colname, geom_colname, numer_tablename,
|
||||
geom_tablename, numer_geomref_colname,
|
||||
geom_geomref_colname, geom, geom_colname);
|
||||
ELSIF map_type = 'denominated' THEN
|
||||
sql = format('SELECT numer.%I / denom.%I
|
||||
FROM observatory.%I numer, observatory.%I geom, observatory.%I denom
|
||||
WHERE numer.%I = geom.%I
|
||||
AND geom.%I = denom.%I
|
||||
AND ST_WITHIN(%L, geom.%I)',
|
||||
numer_colname, denom_colname, numer_tablename,
|
||||
geom_tablename, denom_tablename,
|
||||
numer_geomref_colname, geom_geomref_colname,
|
||||
geom_geomref_colname, denom_geomref_colname,
|
||||
geom, geom_colname);
|
||||
ELSIF map_type = 'predenominated' THEN
|
||||
sql = format('SELECT numer.%I
|
||||
FROM observatory.%I numer, observatory.%I geom
|
||||
WHERE numer.%I = geom.%I
|
||||
AND ST_WITHIN(%L, geom.%I)',
|
||||
numer_colname, numer_tablename,
|
||||
geom_tablename, numer_geomref_colname,
|
||||
geom_geomref_colname, geom, geom_colname);
|
||||
END IF;
|
||||
ELSIF ST_GeometryType(geom) IN ('ST_Polygon', 'ST_MultiPolygon') THEN
|
||||
IF map_type = 'areaNormalied' THEN
|
||||
ELSIF map_type = 'denominated' THEN
|
||||
ELSIF map_type = 'predenominated' THEN
|
||||
END IF;
|
||||
ELSE
|
||||
RETURN (vals)[1];
|
||||
RAISE EXCEPTION 'Invalid geometry type (%), can only handle ''ST_Point'', ''ST_Polygon'', and ''ST_MultiPolygon''',
|
||||
ST_GeometryType(geom);
|
||||
END IF;
|
||||
|
||||
EXECUTE sql INTO result;
|
||||
RETURN result;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user