This repository has been archived by the owner on Mar 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
visuals.sql
146 lines (135 loc) · 3.72 KB
/
visuals.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
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
\set ON_ERROR_STOP on
SET plpgsql.extra_errors TO 'all';
-- wm_bbox clips a geometry by a bounding box around a given object,
-- matching dimensions of A-class paper (1 by sqrt(2)).
drop function if exists wm_bbox;
create function wm_bbox(
center geometry,
scaledwidth float
) returns geometry as $$
declare
halfX float;
halfY float;
begin
halfX = scaledwidth / 2;
halfY = halfX * sqrt(2);
return st_envelope(
st_union(
st_translate(center, halfX, halfY),
st_translate(center, -halfX, -halfY)
)
);
end $$ language plpgsql;
-- wm_quadrant divides the given geometry to 4 rectangles
-- and returns the requested quadrant following cartesian
-- convention:
-- +----------+
-- | II | I |
--- +----------+
-- | III | IV |
-- +-----+----+
-- matching dimensions of A-class paper (1 by sqrt(2).
drop function if exists wm_quadrant;
create function wm_quadrant(
geom geometry,
quadrant integer
) returns geometry as $$
declare
xmin float;
xmax float;
ymin float;
ymax float;
begin
xmin = st_xmin(geom);
xmax = st_xmax(geom);
ymin = st_ymin(geom);
ymax = st_ymax(geom);
if quadrant = 1 or quadrant = 2 then
ymin = (ymin + ymax)/2;
else
ymax = (ymin + ymax)/2;
end if;
if quadrant = 2 or quadrant = 3 then
xmax = (xmin + xmax)/2;
else
xmin = (xmin + xmax)/2;
end if;
return st_intersection(
geom,
st_makeenvelope(xmin, ymin, xmax, ymax, st_srid(geom))
);
end $$ language plpgsql;
drop function if exists wm_salvisbbox;
create function wm_salvisbbox(
geom geometry,
scaledwidth float
) returns geometry as $$
declare
ret geometry;
begin
with multismall as (
select st_intersection(
st_union(geom),
wm_bbox(
st_closestpoint(
(select way from wm_rivers where name='Šalčia'),
(select way from wm_rivers where name='Visinčia')
),
scaledwidth
)
) ways
)
-- protecting against very small bends that were cut
-- in the corner of the picture
select st_union(a.geom)
from st_dump((select ways from multismall)) a
where st_length(a.geom) >= 100
into ret;
return ret;
end $$ language plpgsql;
delete from wm_debug where name like 'salvis%';
delete from wm_visuals where name like 'salvis%';
insert into wm_visuals(name, way) values
('salvis-grpk10', (
wm_salvisbbox(
(select st_union(way) from wm_rivers where name in ('Šalčia', 'Visinčia')),
:scaledwidth
)
)),
('salvis-grpk50', (
wm_salvisbbox(
(select st_union(way) from wm_rivers_50 where name in ('Šalčia', 'Visinčia')),
:scaledwidth
)
)),
('salvis-grpk250', (
wm_salvisbbox(
(select st_union(way) from wm_rivers_250 where name in ('Šalčia', 'Visinčia')),
:scaledwidth
)
));
do $$
declare
i integer;
geom1 geometry;
geom2 geometry;
geom3 geometry;
begin
foreach i in array array[16, 32, 64, 256] loop
geom1 = st_simplify((select way from wm_visuals where name='salvis-grpk10'), i);
geom2 = st_simplifyvw((select way from wm_visuals where name='salvis-grpk10'), i*i);
insert into wm_visuals(name, way) values
('salvis-dp' || i, geom1),
('salvis-dpchaikin' || i, st_chaikinsmoothing(geom1, 5)),
('salvis-vw' || i, geom2),
('salvis-vwchaikin' || i, st_chaikinsmoothing(geom2, 5));
end loop;
-- more than 220 doesn't work, because there is an exaggerated bend near
-- Šalčia-Visinčia crossing, and it "exaggerates" to the
-- other river.
foreach i in array array[75, 220] loop
geom3 = st_simplifywm((select way from wm_visuals where name='salvis-grpk10'), i, null, 'salvis-wm' || i);
insert into wm_visuals(name, way) values
('salvis-wm' || i, geom3);
end loop;
end $$ language plpgsql;