Merge remote-tracking branch 'origin/release-v-1.3.3' into faster-autotest
Conflicts: src/pg/sql/40_observatory_utility.sql
This commit is contained in:
@@ -246,3 +246,25 @@ RETURNS BOOLEAN LANGUAGE SQL IMMUTABLE STRICT AS $$
|
||||
'double precision'
|
||||
)
|
||||
$$;
|
||||
|
||||
-- Attempt to perform intersection, if there's an exception then buffer
|
||||
-- https://gis.stackexchange.com/questions/50399/how-best-to-fix-a-non-noded-intersection-problem-in-postgis
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory.safe_intersection(
|
||||
geom_a Geometry(Geometry, 4326),
|
||||
geom_b Geometry(Geometry, 4326)
|
||||
)
|
||||
RETURNS Geometry(Geometry, 4326) AS
|
||||
$$
|
||||
BEGIN
|
||||
RETURN ST_MakeValid(ST_Intersection(geom_a, geom_b));
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
BEGIN
|
||||
RETURN ST_MakeValid(ST_Intersection(ST_Buffer(geom_a, 0.0000001), ST_Buffer(geom_b, 0.0000001)));
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
RETURN NULL;
|
||||
END;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' STABLE STRICT;
|
||||
|
||||
@@ -591,8 +591,8 @@ BEGIN
|
||||
(normalization IS NULL AND LOWER(denom_reltype) LIKE 'denominator')
|
||||
THEN ' CASE ' ||
|
||||
-- denominated point-in-poly or user polygon is same as OBS polygon
|
||||
' WHEN ST_GeometryType(cdb_observatory.FIRST(_geoms.geom)) = ''ST_Point'' ' ||
|
||||
' OR cdb_observatory.FIRST(_geoms.geom = ' || geom_tablename || '.' || geom_colname || ')' ||
|
||||
' WHEN EVERY(ST_GeometryType(_geoms.geom) = ''ST_Point'') ' ||
|
||||
' OR EVERY(_geoms.geom::TEXT = ' || geom_tablename || '.' || geom_colname || '::TEXT)' ||
|
||||
' THEN cdb_observatory.FIRST(' || numer_tablename || '.' || numer_colname ||
|
||||
' / NullIf(' || denom_tablename || '.' || denom_colname || ', 0))' ||
|
||||
-- denominated polygon interpolation
|
||||
@@ -600,19 +600,19 @@ BEGIN
|
||||
' ELSE ' ||
|
||||
' SUM(' || numer_tablename || '.' || numer_colname || ' ' ||
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0) ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) ' ||
|
||||
' THEN 1 ' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(' || geom_tablename || '.' || geom_colname || '))' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0))' ||
|
||||
' END) / '
|
||||
' NULLIF(SUM(' || denom_tablename || '.' || denom_colname || ' ' ||
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0) ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) ' ||
|
||||
' THEN 1 ' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(' || geom_tablename || '.' || geom_colname || '))' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0))' ||
|
||||
' END), 0) ' ||
|
||||
' / (COUNT(*) / COUNT(distinct ' || geom_tablename || '.' || geom_geomref_colname || ')) ' ||
|
||||
' END '
|
||||
@@ -621,10 +621,10 @@ BEGIN
|
||||
(normalization IS NULL AND numer_aggregate ILIKE 'sum')
|
||||
THEN ' CASE ' ||
|
||||
-- areaNormalized point-in-poly or user polygon is the same as OBS polygon
|
||||
' WHEN ST_GeometryType(cdb_observatory.FIRST(_geoms.geom)) = ''ST_Point'' ' ||
|
||||
' OR cdb_observatory.FIRST(_geoms.geom = ' || geom_tablename || '.' || geom_colname || ')' ||
|
||||
' WHEN EVERY(ST_GeometryType(_geoms.geom) = ''ST_Point'') ' ||
|
||||
' OR EVERY(_geoms.geom::TEXT = ' || geom_tablename || '.' || geom_colname || '::TEXT)' ||
|
||||
' THEN cdb_observatory.FIRST(' || numer_tablename || '.' || numer_colname ||
|
||||
' / (ST_Area(' || geom_tablename || '.' || geom_colname || '::Geography)/1000000)) ' ||
|
||||
' / (Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '::Geography), 0)/1000000)) ' ||
|
||||
-- areaNormalized polygon interpolation
|
||||
-- SUM (numer * (% OBS geom in user geom)) / area of big geom
|
||||
' ELSE ' ||
|
||||
@@ -633,20 +633,20 @@ BEGIN
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') THEN 1 ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) THEN ' ||
|
||||
' ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' / ST_Area(_geoms.geom)' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(_geoms.geom))' ||
|
||||
' END / (ST_Area(' || geom_tablename || '.' || geom_colname || '::Geography) / 1000000)) ' ||
|
||||
' / Nullif(ST_Area(_geoms.geom), 0) ' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(_geoms.geom), 0))' ||
|
||||
' END / (Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '::Geography), 0) / 1000000)) ' ||
|
||||
' / (COUNT(*) / COUNT(distinct ' || geom_tablename || '.' || geom_geomref_colname || ')) ' ||
|
||||
' END '
|
||||
' END '
|
||||
-- median/average measures with universe
|
||||
WHEN LOWER(numer_aggregate) IN ('median', 'average') AND
|
||||
denom_reltype ILIKE 'universe' AND
|
||||
(normalization IS NULL OR LOWER(normalization) LIKE 'pre%')
|
||||
THEN ' CASE ' ||
|
||||
-- predenominated point-in-poly or user polygon is the same as OBS- polygon
|
||||
' WHEN ST_GeometryType(cdb_observatory.FIRST(_geoms.geom)) = ''ST_Point'' ' ||
|
||||
' OR cdb_observatory.FIRST(_geoms.geom = ' || geom_tablename || '.' || geom_colname || ')' ||
|
||||
' WHEN EVERY(ST_GeometryType(_geoms.geom) = ''ST_Point'') ' ||
|
||||
' OR EVERY(_geoms.geom::TEXT = ' || geom_tablename || '.' || geom_colname || '::TEXT)' ||
|
||||
' THEN cdb_observatory.FIRST(' || numer_tablename || '.' || numer_colname || ') ' ||
|
||||
' ELSE ' ||
|
||||
-- predenominated polygon interpolation weighted by universe
|
||||
@@ -656,20 +656,20 @@ BEGIN
|
||||
' SUM(' || numer_tablename || '.' || numer_colname ||
|
||||
' * ' || denom_tablename || '.' || denom_colname ||
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0) ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) ' ||
|
||||
' THEN 1 ' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(' || geom_tablename || '.' || geom_colname || '))' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0)) ' ||
|
||||
' END) ' ||
|
||||
' / SUM(' || denom_tablename || '.' || denom_colname ||
|
||||
' / Nullif(SUM(' || denom_tablename || '.' || denom_colname ||
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0) ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) ' ||
|
||||
' THEN 1 ' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(' || geom_tablename || '.' || geom_colname || '))' ||
|
||||
' END) ' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0))' ||
|
||||
' END), 0) ' ||
|
||||
' / (COUNT(*) / COUNT(distinct ' || geom_tablename || '.' || geom_geomref_colname || ')) ' ||
|
||||
'END '
|
||||
-- prenormalized for summable measures. point or summable only!
|
||||
@@ -677,26 +677,27 @@ BEGIN
|
||||
(normalization IS NULL OR LOWER(normalization) LIKE 'pre%')
|
||||
THEN ' CASE ' ||
|
||||
-- predenominated point-in-poly or user polygon is the same as OBS- polygon
|
||||
' WHEN ST_GeometryType(cdb_observatory.FIRST(_geoms.geom)) = ''ST_Point'' ' ||
|
||||
' OR cdb_observatory.FIRST(_geoms.geom = ' || geom_tablename || '.' || geom_colname || ')' ||
|
||||
' WHEN EVERY(ST_GeometryType(_geoms.geom) = ''ST_Point'') ' ||
|
||||
' OR EVERY(_geoms.geom::TEXT = ' || geom_tablename || '.' || geom_colname || '::TEXT)' ||
|
||||
' THEN cdb_observatory.FIRST(' || numer_tablename || '.' || numer_colname || ') ' ||
|
||||
' ELSE ' ||
|
||||
-- predenominated polygon interpolation
|
||||
-- SUM (numer * (% user geom in OBS geom))
|
||||
' SUM(' || numer_tablename || '.' || numer_colname || ' ' ||
|
||||
' * CASE WHEN ST_Within(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / ST_Area(' || geom_tablename || '.' || geom_colname || ') ' ||
|
||||
' THEN ST_Area(_geoms.geom) / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0) ' ||
|
||||
' WHEN ST_Within(' || geom_tablename || '.' || geom_colname || ', _geoms.geom) ' ||
|
||||
' THEN 1 ' ||
|
||||
' ELSE (ST_Area(ST_Intersection(_geoms.geom, ' || geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / ST_Area(' || geom_tablename || '.' || geom_colname || '))' ||
|
||||
' ELSE (ST_Area(cdb_observatory.safe_intersection(_geoms.geom, ' ||
|
||||
geom_tablename || '.' || geom_colname || ')) ' ||
|
||||
' / Nullif(ST_Area(' || geom_tablename || '.' || geom_colname || '), 0))' ||
|
||||
' END) ' ||
|
||||
' / (COUNT(*) / COUNT(distinct ' || geom_tablename || '.' || geom_geomref_colname || ')) ' ||
|
||||
'END '
|
||||
-- Everything else. Point only!
|
||||
ELSE ' CASE ' ||
|
||||
' WHEN ST_GeometryType(cdb_observatory.FIRST(_geoms.geom)) = ''ST_Point'' ' ||
|
||||
' OR cdb_observatory.FIRST(_geoms.geom = ' || geom_tablename || '.' || geom_colname || ')' ||
|
||||
' WHEN EVERY(ST_GeometryType(_geoms.geom) = ''ST_Point'') ' ||
|
||||
' OR EVERY(_geoms.geom::TEXT = ' || geom_tablename || '.' || geom_colname || '::TEXT)' ||
|
||||
' THEN cdb_observatory.FIRST(' || numer_tablename || '.' || numer_colname || ') ' ||
|
||||
' ELSE cdb_observatory._OBS_RaiseNotice(''Cannot perform calculation over polygon for ' ||
|
||||
numer_id || '/' || coalesce(denom_id, '') || '/' || geom_id || '/' || numer_timespan || ''')::Numeric ' ||
|
||||
@@ -714,8 +715,8 @@ BEGIN
|
||||
'.' || geom_colname || ')::TEXT'
|
||||
-- code below will return the intersection of the user's geom and the
|
||||
-- OBS geom
|
||||
--'"value": "'' || ' || 'cdb_observatory.FIRST(ST_Intersection(_geoms.geom, ' || geom_tablename ||
|
||||
-- '.' || geom_colname || '))::TEXT || ''"'''
|
||||
--'''value'', ' || 'ST_Union(cdb_observatory.safe_intersection(_geoms.geom, ' || geom_tablename ||
|
||||
-- '.' || geom_colname || '))::TEXT'
|
||||
ELSE ''
|
||||
END || ')', ', ')
|
||||
AS colspecs,
|
||||
|
||||
Reference in New Issue
Block a user