-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_frame_labels.sql
217 lines (207 loc) · 5.92 KB
/
create_frame_labels.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
DROP TABLE IF EXISTS sadc.frame_labels;
--create the grid line table
CREATE TABLE sadc.frame_labels(
gid serial primary key,
the_geom geometry(POINT,4326),
dot_position varchar(10),
dot_unit varchar(6),
dot_name varchar(16),
dot_orient varchar(4));
--create or replace the function that loops to create line dashes that run
CREATE OR REPLACE FUNCTION sadc.draw_frame_labels(
x_min integer, --southern-most box line in whole degrees
x_max integer, --northern-most box line in whole degrees
x_int integer, --length of vertical dashes in whole minutes (60 = 1 degree)
y_min integer, --western-most box line in whole degrees
y_max integer, --eastern-most box line in whole degrees
y_int integer) --length of horizontal dashes in whole minutes (60 = 1 degree)
RETURNS void AS
$BODY$
DECLARE
x_coord numeric(21,18); --the coordinates of the vertices on the lines
y_coord numeric(21,18); -- " ditto "
i integer;
dot_int numeric(24,21); --space between lines in decimal fractions of a degree
-- dash_start numeric(21,18); --the position of the start of the dash
orient varchar(4);
mant numeric(21,18); --fractional part of the line's definition
deg integer; --whole part (unsigned) of the line's defintion
min integer; --fractional part, (unsigned minutes) of the line's defintion
hemis varchar(2); --hemisphere (N, S, E, W) of the line's definition
coord varchar(10); --description in degrees, minutes and hemisphere, of the line
unit varchar(6); --whether line represents a whole degree or a fraction (minute)
line varchar(6); --whether the line of points is on the top, bottom, left or right
wkt_str varchar; --the WKT vesrion of each string
BEGIN
--Check the limits of the input parameters
IF x_min < -179.99 THEN
x_min := -179.99;
END IF;--
IF x_max > 180 THEN
x_max := 180;
END IF;
IF y_min < -85 THEN
y_min := -85;
END IF;
IF y_max > 85 THEN
y_max := 85;
END IF;
-- check the horizontal (longitude interval) doesn't exceed 90 deg
IF x_int > 5400 THEN
x_int := 5400;
END IF;
--get the dot interval in dec deg
dot_int := abs(x_int) / 60.0;
--loop to do the bottom and the top
FOR i IN 1..2 LOOP
--choose whether the bottom or top line
CASE i
--bottom
WHEN 1 THEN
y_coord := y_min;
line := 'Bottom';
--top
WHEN 2 THEN
y_coord := y_max;
line := 'Top';
END CASE;
--set the start of the lines to the left
x_coord := x_min;
--set up the beginning of the WKT string
wkt_str := 'SRID=4326;POINT(' || x_coord || ' ' || y_coord || ')';
--loop to add line
<<hor>>
LOOP
--make a label for the line in degrees and minutes
deg := trunc(x_coord);
mant := abs(x_coord - deg);
hemis := to_char(sign(round(x_coord,6)),'SG9');
deg := abs(deg);
min := round(round(mant,5) * 60);
IF min >= 60 THEN
deg := deg + 1;
min := min - 60;
END IF;
CASE hemis
WHEN '-1' THEN
hemis := 'W';
WHEN '+1' THEN
hemis := 'E';
ELSE
hemis := ' ';
END CASE;
coord := to_char(deg, '99') || chr(186) || to_char(min, '00') || chr(180) || ' ' || hemis;
--catagorise the line as a degree line or a minute line
CASE min
WHEN 0 THEN
unit := 'degree';
ELSE
unit := 'minute';
END CASE;
--add in the point as a WKT string
wkt_str := 'SRID=4326;POINT(' || x_coord || ' ' || y_coord || ')';
--load the data,including the WKT as a geometry, into the table as a row
INSERT INTO sadc.frame_labels(
the_geom,
dot_position,
dot_unit,
dot_name,
dot_orient)
VALUES (
ST_GeomFromEWKT(wkt_str),
coord,
unit,
line,
'long');
--add points along the line, increment by the dot interval
x_coord := x_coord + dot_int;
--leave the loop once the line has reached its right-most limit
EXIT hor WHEN x_coord >= x_max;
END LOOP hor;
END LOOP;
-- check the vertical (latitude interval) doesn't exceed 45 deg
IF y_int > 2700 THEN
y_int := 2700;
END IF;
--get the dot interval in dec deg
dot_int := abs(y_int) / 60.0;
--loop to do the left and the right
FOR i IN 1..2 LOOP
--choose whether the left or right line
CASE i
--left
WHEN 1 THEN
x_coord := x_min;
line := 'Left';
--right
WHEN 2 THEN
x_coord := x_max;
line := 'Right';
END CASE;
--set the start of the lines to the bottom
y_coord := y_min;
--loop to add line
<<vert>>
LOOP
--make a label for the line in degrees and minutes
deg := trunc(y_coord);
mant := abs(y_coord - deg);
hemis := to_char(sign(round(y_coord,6)),'SG9');
deg := abs(deg);
min := round(round(mant,5) * 60);
IF min >= 60 THEN
deg := deg + 1;
min := min - 60;
END IF;
CASE hemis
WHEN '-1' THEN
hemis := 'S';
WHEN '+1' THEN
hemis := 'N';
ELSE
hemis := ' ';
END CASE;
coord := to_char(deg, '99') || chr(186) || to_char(min, '00') || chr(180) || ' ' || hemis;
--catagorise the line as a degree line or a minute line
CASE min
WHEN 0 THEN
unit := 'degree';
ELSE
unit := 'minute';
END CASE;
--add in the point as a WKT string
wkt_str := 'SRID=4326;POINT(' || x_coord || ' ' || y_coord || ')';
--load the data,including the WKT as a geometry, into the table as a row
INSERT INTO sadc.frame_labels(
the_geom,
dot_position,
dot_unit,
dot_name,
dot_orient)
VALUES (
ST_GeomFromEWKT(wkt_str),
coord,
unit,
line,
'lat');
--increment by the dot interval
y_coord := y_coord + dot_int;
--leave the loop once the line has reached its top-most limit
EXIT vert WHEN y_coord >= y_max;
END LOOP vert;
END LOOP;
-- RETURN wkt_str;
RETURN;
END;
$BODY$
LANGUAGE plpgsql;
--run the function, with the given parameters
SELECT * FROM sadc.draw_frame_labels(8, 68, 5, -40, 8, 5);
--view thw result
SELECT
ST_AsEWKT(the_geom),
dot_position,
dot_unit,
dot_name,
dot_orient
FROM sadc.frame_labels;