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