-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsicob_spikeremovercore.sql
More file actions
114 lines (100 loc) · 3.73 KB
/
Copy pathsicob_spikeremovercore.sql
File metadata and controls
114 lines (100 loc) · 3.73 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
SET CLIENT_ENCODING TO 'utf8';
CREATE OR REPLACE FUNCTION public.sicob_spikeremovercore(geometry, angle double precision)
RETURNS geometry
LANGUAGE plpgsql
AS $function$
declare
ingeom alias for $1;
angle alias for $2;
lineusp geometry;
linenew geometry;
newgeom geometry;
testgeom varchar;
remove_point boolean;
newb boolean;
changed boolean;
point_id integer;
numpoints integer;
begin
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: spikeRemoverCore.sql 2009-10-01 08:00 Andreas Schmidt(andreas.schmidtATiz.bwl.de) & Nils Krüger(nils.kruegerATiz.bwl.de) $
--
-- spikeRemover - remove Spike from polygon
-- input Polygon geometries, angle
-- http://www.izlbw.de/
-- Copyright 2009 Informatikzentrum Landesverwaltung Baden-Württemberg (IZLBW) Germany
-- Version 1.0
--
-- This is free software; you can redistribute and/or modify it under
-- the terms of the GNU General Public Licence. See the COPYING file.
-- This software is without any warrenty and you use it at your own risk
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- input geometry or rather set as default for the output
newgeom := ingeom;
-- check polygon
if (select st_geometrytype(ingeom)) = 'ST_Polygon' then
if (select st_numinteriorrings(ingeom)) = 0 then
-- default value of the loop indicates if the geometry has been changed
newb := true;
--save the polygon boundary as a line
lineusp := st_boundary(ingeom) as line;
-- number of tags
numpoints := st_numpoints(lineusp);
-- globale changevariable
changed := false;
-- loop ( to remove several points)
while newb = true loop
-- default values
remove_point := false;
newb := false;
point_id := 0;
-- the geometry passes pointwisely
while (point_id <= numpoints) and (remove_point = false) loop
-- the check of the angle at the current point of a spike including the special case, that it is the first point.
if (select abs(pi() - abs(st_azimuth(st_pointn(lineusp, case when point_id= 1 then st_numpoints(lineusp) - 1 else point_id - 1 end),
st_pointn(lineusp, point_id)) - st_azimuth(st_pointn(lineusp, point_id), st_pointn(lineusp, point_id + 1))))) <= angle then
-- remove point
linenew := st_removepoint(lineusp, point_id - 1);
if linenew is not null then
raise notice '---> remove point %', point_id;
lineusp := linenew;
remove_point := true;
-- if the first point is concerned, the last point must also be changed to close the line again.
if point_id = 1 then
linenew := st_setpoint(lineusp, numpoints - 2, st_pointn(lineusp, 1));
lineusp := linenew;
end if;
end if;
end if;
point_id = point_id + 1;
end loop;
-- remove point
if remove_point = true then
numpoints := st_numpoints(lineusp);
newb := true;
point_id := 0;
changed := true;
end if;
end loop;
--with the change it is tried to change back the new line geometry in a polygon. if this is not possible, the existing geometry is used
if changed = true then
newgeom := st_buildarea(lineusp) as geom;
-- errorhandling
if newgeom is not null then
raise notice 'creating new geometry!';
else
newgeom := ingeom;
raise notice '-------------- area could not be created !!! --------------';
testgeom:=st_astext(lineusp);
raise notice 'geometry %', testgeom;
end if;
end if;
end if;
end if;
-- return value
return newgeom;
end;
$function$