1 #include "pg_sphere.h"
2 #include "sbuffer.h"
3
4 /* Functions to buffer the parser input. */
5
6 /* Maximum count of buffered angles. */
7 #define MAX_BUF_ANGLE 20
8
9 /* The type of parsed spherical object. */
10 unsigned char spheretype;
11
12 /* The angle buffer. */
13 float8 bufangle[MAX_BUF_ANGLE];
14
15 /* A simple spherical point. */
16 typedef struct
17 {
18 double lng; /* longitude */
19 double lat; /* latitude */
20 } bpoint;
21
22 /* Spherical point buffer. */
23 struct
24 {
25 int m; /* count of buffered points */
26 bpoint *p; /* pointer to array of points */
27 } bufpoints;
28
29 /* ID of line's length angle. */
30 int bufline;
31
32 /*
33 * First element is the ID of spherical point ( center ).
34 * Second element is the ID of radius angle.
35 */
36 int bufcircle[2];
37
38 /* Buffer of ellipse. */
39 int bufellipse[5];
40
41 /* Buffer of IDs of Euler transformation values. */
42 int bufeuler[3];
43
44 /* Structure to buffer the axes of Euler transformation. */
45 struct
46 {
47 unsigned char phi, /* first axis */
48 theta, /* second axis */
49 psi; /* third axis */
50 } bufeulertype;
51
52 /* Current angle ID. */
53 int bufapos;
54
55 /* Current point ID. */
56 int bufspos;
57
58 /* Pointer to input buffer. */
59 char *parse_buffer;
60
61
62 void
set_spheretype(unsigned char st)63 set_spheretype(unsigned char st)
64 {
65 spheretype = st;
66 }
67
68
69 void
init_buffer(char * buffer)70 init_buffer(char *buffer)
71 {
72 spheretype = STYPE_UNKNOWN;
73 parse_buffer = buffer;
74
75 bufapos = 0;
76 bufspos = 0;
77 bufeulertype.phi = bufeulertype.psi = EULER_AXIS_Z;
78 bufeulertype.theta = EULER_AXIS_X;
79
80 bufpoints.m = 2;
81 bufpoints.p = (bpoint *) palloc(bufpoints.m * sizeof(bpoint));
82
83 }
84
85
86 void
reset_buffer(void)87 reset_buffer(void)
88 {
89 sphere_flush_scanner_buffer();
90 pfree(bufpoints.p);
91 bufpoints.p = NULL;
92 bufpoints.m = 0;
93 init_buffer(NULL);
94 }
95
96
97 int
set_angle_sign(int apos,int s)98 set_angle_sign(int apos, int s)
99 {
100 if (bufangle[apos] > 0 && s < 0)
101 {
102 bufangle[apos] *= -1;
103 }
104 if (bufangle[apos] < 0 && s > 0)
105 {
106 bufangle[apos] *= -1;
107 }
108 return apos;
109 }
110
111 int
set_angle(unsigned char is_deg,float8 a)112 set_angle(unsigned char is_deg, float8 a)
113 {
114 if (is_deg)
115 {
116 a /= RADIANS;
117 }
118 bufangle[bufapos] = a;
119 bufapos++;
120 return (bufapos - 1);
121 }
122
123 int
set_point(int lngpos,int latpos)124 set_point(int lngpos, int latpos)
125 {
126 if (bufspos >= bufpoints.m)
127 {
128 bpoint *p = bufpoints.p;
129 int i = (bufpoints.m * 2);
130
131 bufpoints.p = (bpoint *) palloc(i * sizeof(bpoint));
132 memcpy((void *) bufpoints.p, (void *) p, bufpoints.m * sizeof(bpoint));
133 bufpoints.m = i;
134 pfree(p);
135 }
136 bufpoints.p[bufspos].lng = bufangle[lngpos];
137 bufpoints.p[bufspos].lat = bufangle[latpos];
138 bufspos++;
139 lngpos = 0;
140 latpos = 0;
141 if ((bufapos + 3) > MAX_BUF_ANGLE)
142 {
143 bufapos = 0;
144 }
145 return (bufspos - 1);
146 }
147
148 void
set_circle(int spos,int rpos)149 set_circle(int spos, int rpos)
150 {
151 bufcircle[0] = spos;
152 bufcircle[1] = rpos;
153 }
154
155
156 void
set_ellipse(int r1,int r2,int sp,int inc)157 set_ellipse(int r1, int r2, int sp, int inc)
158 {
159 bufellipse[0] = r1;
160 bufellipse[1] = r2;
161 bufellipse[2] = sp;
162 bufellipse[3] = inc;
163 }
164
165
166 void
set_line(int length)167 set_line(int length)
168 {
169 bufline = length;
170 }
171
172 void
set_euler(int phi,int theta,int psi,char * etype)173 set_euler(int phi, int theta, int psi, char *etype)
174 {
175 int i;
176 unsigned char t = 0;
177
178 bufeuler[0] = phi;
179 bufeuler[1] = theta;
180 bufeuler[2] = psi;
181 for (i = 0; i < 3; i++)
182 {
183 switch (etype[i])
184 {
185 case 'x':
186 case 'X':
187 t = EULER_AXIS_X;
188 break;
189 case 'y':
190 case 'Y':
191 t = EULER_AXIS_Y;
192 break;
193 case 'z':
194 case 'Z':
195 t = EULER_AXIS_Z;
196 break;
197 }
198 switch (i)
199 {
200 case 0:
201 bufeulertype.phi = t;
202 break;
203 case 1:
204 bufeulertype.theta = t;
205 break;
206 case 2:
207 bufeulertype.psi = t;
208 break;
209 }
210 }
211 }
212
213 int
get_point(double * lng,double * lat)214 get_point(double *lng, double *lat)
215 {
216 if (spheretype == STYPE_POINT)
217 {
218 *lng = bufpoints.p[0].lng;
219 *lat = bufpoints.p[0].lat;
220 return 1;
221 }
222 else
223 {
224 return 0;
225 }
226 }
227
228 int
get_line(double * phi,double * theta,double * psi,unsigned char * etype,double * length)229 get_line(double *phi, double *theta,
230 double *psi, unsigned char *etype, double *length)
231 {
232 int i;
233
234 if (spheretype != STYPE_LINE)
235 {
236 return 0;
237 }
238
239 *phi = bufangle[bufeuler[0]];
240 *theta = bufangle[bufeuler[1]];
241 *psi = bufangle[bufeuler[2]];
242 for (i = 0; i < 3; i++)
243 {
244 switch (i)
245 {
246 case 0:
247 etype[i] = bufeulertype.phi;
248 break;
249 case 1:
250 etype[i] = bufeulertype.theta;
251 break;
252 case 2:
253 etype[i] = bufeulertype.psi;
254 break;
255 }
256 }
257 *length = bufangle[bufline];
258 return 1;
259 }
260
261
262 int
get_euler(double * phi,double * theta,double * psi,unsigned char * etype)263 get_euler(double *phi, double *theta,
264 double *psi, unsigned char *etype)
265 {
266 int i;
267
268 if (spheretype != STYPE_EULER)
269 {
270 return 0;
271 }
272 *phi = bufangle[bufeuler[0]];
273 *theta = bufangle[bufeuler[1]];
274 *psi = bufangle[bufeuler[2]];
275 for (i = 0; i < 3; i++)
276 {
277 switch (i)
278 {
279 case 0:
280 etype[i] = bufeulertype.phi;
281 break;
282 case 1:
283 etype[i] = bufeulertype.theta;
284 break;
285 case 2:
286 etype[i] = bufeulertype.psi;
287 break;
288 }
289 }
290
291 return 1;
292 }
293
294 int
get_circle(double * lng,double * lat,double * radius)295 get_circle(double *lng, double *lat, double *radius)
296 {
297 if (spheretype == STYPE_CIRCLE)
298 {
299 *lng = bufpoints.p[bufcircle[0]].lng;
300 *lat = bufpoints.p[bufcircle[0]].lat;
301 *radius = bufangle[bufcircle[1]];
302 return 1;
303 }
304 else
305 {
306 return 0;
307 }
308 }
309
310 int
get_ellipse(double * lng,double * lat,double * r1,double * r2,double * inc)311 get_ellipse(double *lng, double *lat,
312 double *r1, double *r2, double *inc)
313 {
314 if (spheretype == STYPE_ELLIPSE)
315 {
316 *lng = bufpoints.p[bufellipse[2]].lng;
317 *lat = bufpoints.p[bufellipse[2]].lat;
318 *r1 = bufangle[bufellipse[0]];
319 *r2 = bufangle[bufellipse[1]];
320 *inc = bufangle[bufellipse[3]];
321 return 1;
322 }
323 else
324 {
325 return 0;
326 }
327
328 }
329
330 int
get_path_count(void)331 get_path_count(void)
332 {
333 return (bufspos);
334 }
335
336 int
get_path_elem(int spos,double * lng,double * lat)337 get_path_elem(int spos, double *lng, double *lat)
338 {
339 if (spheretype == STYPE_PATH)
340 {
341 *lng = bufpoints.p[spos].lng;
342 *lat = bufpoints.p[spos].lat;
343 return 1;
344 }
345 else
346 {
347 return 0;
348 }
349 }
350
351
352 int
get_box(double * lng1,double * lat1,double * lng2,double * lat2)353 get_box(double *lng1, double *lat1, double *lng2, double *lat2)
354 {
355 if (spheretype == STYPE_BOX)
356 {
357 *lng1 = bufpoints.p[0].lng;
358 *lat1 = bufpoints.p[0].lat;
359 *lng2 = bufpoints.p[1].lng;
360 *lat2 = bufpoints.p[1].lat;
361 return 1;
362 }
363 return 0;
364 }
365
366
367 int
get_buffer(char * buf,int offset)368 get_buffer(char *buf, int offset)
369 {
370 int slen = strlen(parse_buffer);
371
372 if (!parse_buffer || !(slen > 0))
373 {
374 return 0;
375 }
376
377 if (slen >= offset)
378 {
379 slen = offset;
380 }
381 memcpy((void *) buf, (void *) parse_buffer, slen);
382 parse_buffer += slen;
383
384 return slen;
385
386 }
387