tmp commit

This commit is contained in:
John Krauss
2016-09-19 16:08:37 +00:00
parent c9e809c061
commit 18cfdc60d0
2 changed files with 320 additions and 1 deletions
+17
View File
@@ -203,3 +203,20 @@ BEGIN
RETURN result;
END;
$$ LANGUAGE plpgsql;
-- Create a function that always returns the first non-NULL item
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
SELECT $1;
$$;
DROP AGGREGATE IF EXISTS public.FIRST (anyelement);
-- And then wrap an aggregate around it
CREATE AGGREGATE public.FIRST (
sfunc = public.first_agg,
basetype = anyelement,
stype = anyelement
);
+303 -1
View File
@@ -1,4 +1,4 @@
-- return a table that contains a string match based on input
-- TODO: implement search for timespan
CREATE OR REPLACE FUNCTION cdb_observatory._OBS_SearchTables(
@@ -120,3 +120,305 @@ BEGIN
RETURN;
END
$$ LANGUAGE plpgsql;
DROP FUNCTION cdb_observatory.OBS_GetAvailableNumerators(
bounds GEOMETRY, filter_tags TEXT[], denom_id TEXT, geom_id TEXT, timespan TEXT
);
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetAvailableNumerators(
bounds GEOMETRY,
filter_tags TEXT[] DEFAULT NULL,
denom_id TEXT DEFAULT NULL,
geom_id TEXT DEFAULT NULL,
timespan TEXT DEFAULT NULL
) RETURNS TABLE (
numer_id TEXT,
numer_name TEXT,
numer_description TEXT,
numer_weight NUMERIC,
numer_license TEXT,
numer_source TEXT,
numer_type TEXT,
numer_extra JSONB,
numer_tags JSONB,
valid_denom BOOLEAN,
valid_geom BOOLEAN,
valid_timespan BOOLEAN
) AS $$
BEGIN
filter_tags := COALESCE(filter_tags, (ARRAY[])::TEXT[]);
denom_id := COALESCE(denom_id, '');
geom_id := COALESCE(geom_id, '');
timespan := COALESCE(timespan, '');
RETURN QUERY
EXECUTE
$string$
SELECT numer_id::TEXT,
numer_name::TEXT,
numer_description::TEXT,
numer_weight::NUMERIC,
NULL::TEXT license,
NULL::TEXT source,
numer_type numer_type,
numer_extra::JSONB numer_extra,
numer_tags numer_tags,
$1 = ANY(denoms) valid_denom,
$2 = ANY(geoms) valid_geom,
$3 = ANY(timespans) valid_timespan
FROM obs_meta_numer
WHERE st_intersects(the_geom, $5)
AND (numer_tags ?& $4 OR CARDINALITY($4) = 0)
$string$
USING denom_id, geom_id, timespan, filter_tags, bounds;
RETURN;
END
$$ LANGUAGE plpgsql;
SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(
ST_SetSRID(ST_MakePoint(-73.9, 40.7), 4326),
NULL, 'us.census.acs.B01003001', 'us.census.tiger.census_tract', ''
) where valid_denom IS true and valid_geom IS true;
SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(
ST_SetSRID(ST_MakePoint(-73.9, 40.7), 4326),
ARRAY['unit/tags.money'], '', '', ''
);
-- DENOMS
DROP FUNCTION cdb_observatory.OBS_GetAvailableDenominators(
bounds GEOMETRY, filter_tags TEXT[], numer_id TEXT, geom_id TEXT, timespan TEXT
);
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetAvailableDenominators(
bounds GEOMETRY,
filter_tags TEXT[] DEFAULT NULL,
numer_id TEXT DEFAULT NULL,
geom_id TEXT DEFAULT NULL,
timespan TEXT DEFAULT NULL
) RETURNS TABLE (
denom_id TEXT,
denom_name TEXT,
denom_description TEXT,
denom_weight NUMERIC,
denom_license TEXT,
denom_source TEXT,
denom_type TEXT,
denom_extra JSONB,
denom_tags JSONB,
valid_numer BOOLEAN,
valid_geom BOOLEAN,
valid_timespan BOOLEAN
) AS $$
BEGIN
filter_tags := COALESCE(filter_tags, (ARRAY[])::TEXT[]);
numer_id := COALESCE(numer_id, '');
geom_id := COALESCE(geom_id, '');
timespan := COALESCE(timespan, '');
RETURN QUERY
EXECUTE
$string$
SELECT denom_id::TEXT,
denom_name::TEXT,
denom_description::TEXT,
denom_weight::NUMERIC,
NULL::TEXT license,
NULL::TEXT source,
denom_type::TEXT,
denom_extra::JSONB,
denom_tags::JSONB,
$1 = ANY(numers) valid_numer,
$2 = ANY(geoms) valid_geom,
$3 = ANY(timespans) valid_timespan
FROM obs_meta_denom
WHERE st_intersects(the_geom, $5)
AND (denom_tags ?& $4 OR CARDINALITY($4) = 0)
$string$
USING numer_id, geom_id, timespan, filter_tags, bounds;
RETURN;
END
$$ LANGUAGE plpgsql;
SELECT * FROM cdb_observatory.OBS_GetAvailableDenominators(
ST_SetSRID(ST_MakePoint(-73.9, 40.7), 4326),
NULL, 'us.census.acs.B03002006', 'us.census.tiger.census_tract', ''
) where valid_numer IS true and valid_geom IS true;
--- GEOMS
DROP FUNCTION cdb_observatory.OBS_GetAvailableGeometries(
bounds GEOMETRY, filter_tags TEXT[], numer_id TEXT, denom_id TEXT, timespan TEXT
);
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetAvailableGeometries(
bounds GEOMETRY,
filter_tags TEXT[] DEFAULT NULL,
numer_id TEXT DEFAULT NULL,
denom_id TEXT DEFAULT NULL,
timespan TEXT DEFAULT NULL
) RETURNS TABLE (
geom_id TEXT,
geom_name TEXT,
geom_description TEXT,
geom_weight NUMERIC,
geom_license TEXT,
geom_source TEXT,
valid_numer BOOLEAN,
valid_denom BOOLEAN,
valid_timespan BOOLEAN
) AS $$
BEGIN
filter_tags := COALESCE(filter_tags, (ARRAY[])::TEXT[]);
numer_id := COALESCE(numer_id, '');
denom_id := COALESCE(denom_id, '');
timespan := COALESCE(timespan, '');
RETURN QUERY
EXECUTE
$string$
SELECT geom_id::TEXT,
geom_name::TEXT,
geom_description::TEXT,
geom_weight::NUMERIC,
NULL::TEXT license,
NULL::TEXT source,
$1 = ANY(numers) valid_numer,
$2 = ANY(denoms) valid_denom,
$3 = ANY(timespans) valid_timespan
FROM obs_meta_geom
WHERE st_intersects(the_geom, $5)
AND (geom_tags ?& $4 OR CARDINALITY($4) = 0)
$string$
USING numer_id, denom_id, timespan, filter_tags, bounds;
RETURN;
END
$$ LANGUAGE plpgsql;
SELECT * FROM cdb_observatory.OBS_GetAvailableGeometries(
ST_SetSRID(ST_MakePoint(-73.9, 40.7), 4326),
NULL, 'us.census.acs.B03002006', 'us.census.acs.B01003001', ''
) where valid_numer IS true and valid_denom IS true;
-- TIMESPANS
DROP FUNCTION cdb_observatory.OBS_GetAvailableTimespans(
bounds GEOMETRY, filter_tags TEXT[], numer_id TEXT, denom_id TEXT, geom_id TEXT
);
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetAvailableTimespans(
bounds GEOMETRY,
filter_tags TEXT[] DEFAULT NULL,
numer_id TEXT DEFAULT NULL,
denom_id TEXT DEFAULT NULL,
geom_id TEXT DEFAULT NULL
) RETURNS TABLE (
timespan_id TEXT,
timespan_name TEXT,
timespan_description TEXT,
timespan_weight NUMERIC,
timespan_license TEXT,
timespan_source TEXT,
valid_numer BOOLEAN,
valid_denom BOOLEAN,
valid_geom BOOLEAN,
stats JSONB -- information about # of geoms, avg geom size, etc.
) AS $$
BEGIN
filter_tags := COALESCE(filter_tags, (ARRAY[])::TEXT[]);
numer_id := COALESCE(numer_id, '');
denom_id := COALESCE(denom_id, '');
geom_id := COALESCE(geom_id, '');
RETURN QUERY
EXECUTE
$string$
SELECT timespan_id::TEXT,
timespan_name::TEXT,
timespan_description::TEXT,
timespan_weight::NUMERIC,
NULL::TEXT license,
NULL::TEXT source,
$1 = ANY(numers) valid_numer,
$2 = ANY(denoms) valid_denom,
$3 = ANY(geoms) valid_geom_id,
NULL::JSONB stats
FROM obs_meta_timespan
WHERE st_intersects(the_geom, $5)
AND (timespan_tags ?& $4 OR CARDINALITY($4) = 0)
$string$
USING numer_id, denom_id, geom_id, filter_tags, bounds;
RETURN;
END
$$ LANGUAGE plpgsql;
SELECT * FROM cdb_observatory.OBS_GetAvailableTimespans(
ST_SetSRID(ST_MakePoint(-73.9, 40.7), 4326),
NULL, 'us.census.acs.B03002006', 'us.census.acs.B01003001', 'us.census.tiger.census_tract'
) where valid_numer IS true and valid_denom IS true AND valid_geom IS true;
-- notes: add the_geom index to obs_meta
-- change the_geom type to geometry(geometery, 4326)
DROP TABLE IF EXISTS obs_meta_numer;
CREATE TABLE obs_meta_numer AS
SELECT numer_id::TEXT,
FIRST(numer_name)::TEXT numer_name,
FIRST(numer_description)::TEXT numer_description,
FIRST(numer_tags)::JSONB numer_tags,
FIRST(numer_weight)::NUMERIC numer_weight,
FIRST(numer_extra)::JSONB numer_extra, -- cannot include ct_extra because it depends on table
FIRST(numer_type)::TEXT numer_type,
ARRAY_AGG(DISTINCT denom_id)::TEXT[] denoms,
ARRAY_AGG(DISTINCT geom_id)::TEXT[] geoms,
ARRAY_AGG(DISTINCT numer_timespan)::TEXT[] timespans,
ST_Union(DISTINCT ST_SetSRID(the_geom, 4326)) the_geom
FROM observatory.obs_meta
GROUP BY numer_id;
CREATE INDEX ON obs_meta_numer USING GIST (the_geom);
DROP TABLE IF EXISTS obs_meta_denom;
CREATE TABLE obs_meta_denom AS
SELECT denom_id::TEXT,
FIRST(denom_name)::TEXT denom_name,
FIRST(denom_description)::TEXT denom_description,
NULL::JSONB denom_tags,
FIRST(denom_weight)::NUMERIC denom_weight,
'denominator'::TEXT reltype,
FIRST(denom_extra)::JSONB denom_extra,
FIRST(denom_type)::TEXT denom_type,
ARRAY_AGG(DISTINCT numer_id)::TEXT[] numers,
ARRAY_AGG(DISTINCT geom_id)::TEXT[] geoms,
ARRAY_AGG(DISTINCT numer_timespan)::TEXT[] timespans,
ST_Union(DISTINCT ST_SetSRID(the_geom, 4326)) the_geom
FROM observatory.obs_meta
GROUP BY denom_id;
CREATE INDEX ON obs_meta_denom USING GIST (the_geom);
DROP TABLE IF EXISTS obs_meta_geom;
CREATE TABLE obs_meta_geom AS
SELECT geom_id::TEXT,
FIRST(geom_name)::TEXT geom_name,
FIRST(geom_description)::TEXT geom_description,
NULL::JSONB geom_tags,
FIRST(geom_weight)::NUMERIC geom_weight,
FIRST(geom_extra)::JSONB geom_extra,
FIRST(geom_type)::TEXT geom_type,
ST_SetSRID(FIRST(the_geom), 4326)::GEOMETRY(GEOMETRY, 4326) the_geom,
NULL::raster summary_geom,
ARRAY_AGG(DISTINCT numer_id)::TEXT[] numers,
ARRAY_AGG(DISTINCT denom_id)::TEXT[] denoms,
ARRAY_AGG(DISTINCT numer_timespan)::TEXT[] timespans
FROM observatory.obs_meta
GROUP BY geom_id;
CREATE INDEX ON obs_meta_geom USING GIST (the_geom);
DROP TABLE IF EXISTS obs_meta_timespan;
CREATE TABLE obs_meta_timespan AS
SELECT numer_timespan::TEXT timespan_id,
numer_timespan::TEXT timespan_name,
NULL::TEXT timespan_description,
NULL::JSONB timespan_tags,
NULL::NUMERIC timespan_weight,
NULL::JSONB timespan_extra,
NULL::TEXT timespan_type,
ARRAY_AGG(DISTINCT numer_id)::TEXT[] numers,
ARRAY_AGG(DISTINCT denom_id)::TEXT[] denoms,
ARRAY_AGG(DISTINCT geom_id)::TEXT[] geoms,
ST_Union(DISTINCT ST_SetSRID(the_geom, 4326)) the_geom
FROM observatory.obs_meta
GROUP BY numer_timespan;
CREATE INDEX ON obs_meta_geom USING GIST (the_geom);