-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbuild_multipolygon.sql
60 lines (51 loc) · 1.54 KB
/
build_multipolygon.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
create or replace function build_multipolygon(
rel_id bigint,
outer_ids bigint[],
outer_geom geometry[],
inner_ids bigint[],
inner_geom geometry[])
returns geometry
as $$
declare
outer_ways geometry;
inner_ways geometry;
next geometry;
i int;
begin
if $1 is null then
return null;
end if;
if coalesce(array_upper(inner_geom, 1), 0)>256 then
raise notice 'MP % consists of % (more then 256) inner members ... ignore', rel_id, coalesce(array_upper(outer_geom, 1), 0)+coalesce(array_upper(inner_geom, 1), 0);
return null;
end if;
outer_ways:=make_multipolygon(rel_id, outer_ids, outer_geom);
if outer_ways is null then
return null;
end if;
if not ST_IsValid(outer_ways) then
return outer_ways;
end if;
if inner_geom is not null then
inner_ways:=make_multipolygon(rel_id, inner_ids, inner_geom);
end if;
if inner_ways is null then
return outer_ways;
end if;
-- raise notice E'outer_ways (%): %\ninner_ways (%): %', NumGeometries(outer_ways), astext(outer_ways), NumGeometries(inner_ways), astext(inner_ways);
-- substract the inner ways one by one
for i in 1..ST_NumGeometries(inner_ways) loop
next:=ST_GeometryN(inner_ways, i);
if ST_IsValid(next) then
begin
outer_ways:=ST_Difference(outer_ways, next);
exception
when others then
raise notice 'MP % got an error when substracting inner polygons (inner %)', rel_id, i;
return null;
end;
end if;
end loop;
return outer_ways; -- ST_Difference(outer_ways, inner_ways);
end;
$$ language 'plpgsql';