在尝试处理PostGIS中的GEOMETRYCOLLECTION时,我发现here似乎解决了将GEOMETRYCOLLECTION转换为简单的GEOMETRY的问题,但它只适用于ST_Intersect内部函数。
由于我很懒,我认为通过将函数作为参数执行来使其更强大会更好,但它不会以这种方式工作。
CREATE OR REPLACE FUNCTION ST_GeoCollConv_(geofunction, geometry, geometry) RETURNS boolean AS $$
DECLARE
is1collection boolean;
is2collection boolean;
BEGIN
is1collection := GeometryType($1) = 'GEOMETRYCOLLECTION';
is2collection := GeometryType($2) = 'GEOMETRYCOLLECTION';
IF NOT is1collection AND NOT is2collection THEN
return PERFORM geofunction($1, $2);
END IF;
IF NOT is1collection THEN
FOR i IN 1..ST_NumGeometries($2) LOOP
IF PERFORM geofunction($1, ST_GeometryN($2, i)) THEN
RETURN true;
END IF;
END LOOP;
ELSIF NOT is2collection THEN
FOR i IN 1..ST_NumGeometries($1) LOOP
IF PERFORM geofunction(ST_GeometryN($1, i), $2) THEN
RETURN true;
END IF;
END LOOP;
ELSE
FOR i IN 1..ST_NumGeometries($1) LOOP
IF ST_GeoCollConv_(geofunction, $1, $2) THEN
RETURN true;
END IF;
END LOOP;
END IF;
RETURN false;
END;
$$ LANGUAGE 'plpgsql';
我怎样才能做到这一点?
答案 0 :(得分:1)
函数不是postgres中的一等公民(我不能想到它们所在的RDBMS)并且不能作为参数传递。接下来最接近的是枚举所有可能的函数(st_overlaps,st_intersects,st_within等),传递一个标志,指出你正在谈论的函数,并将其合并到你的if语句中,例如: “如果func ='重叠'和st_overlaps(geom1,geom2),否则如果func ='在'和'st_within(geom1,geom2)......”。
几何集合处理起来有点令人沮丧。你被迫使用它们吗?你可以改用多边形吗?
另请注意,功能本身有点过分。您可以使用st_dump枚举所有几何图形(即使您只有一个简单的几何图形也可以工作)然后加入结果。例如:
create or replace function st_intersects_gc(geometry, geometry)
returns boolean
as
$$
select exists (
select 1
from st_dump($1) a
join st_dump($2) b
on st_intersects(a.geom, b.geom)
limit 1
)
;
$$
language sql
immutable
;
示例用法(还应该有一个示例说明这适用于集合,但我手头没有):
-- returns false
select st_intersects_gc('POINT(0 0)'::geometry, 'LINESTRING ( 2 0, 0 2 )'::geometry)
-- returns true
select st_intersects_gc('POINT(0 0)'::geometry, 'LINESTRING ( 0 0, 0 2 )'::geometry)
在你的鞋子里,我会为你计划使用的每个功能写下其中一个。