PostGIS  2.5.0dev-r@@SVN_REVISION@@
lwout_x3d.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright 2011-2017 Arrival 3D, Regina Obe
22  *
23  **********************************************************************/
24 
29 #include "lwout_x3d.h"
30 
31 /*
32  * VERSION X3D 3.0.2 http://www.web3d.org/specifications/x3d-3.0.dtd
33  */
34 /* takes a GEOMETRY and returns a X3D representation */
35 char*
36 lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid)
37 {
38  stringbuffer_t *sb;
39  int rv;
40  char *result;
41 
42  /* Empty string for empties */
43  if( lwgeom_is_empty(geom) )
44  {
45  char *ret = NULL;
46  ret = lwalloc(1);
47  ret[0] = '\0';
48  return ret;
49  }
50 
51  sb = stringbuffer_create();
52  rv = lwgeom_to_x3d3_sb(geom, srs, precision, opts, defid, sb);
53 
54  if ( rv == LW_FAILURE )
55  {
57  return NULL;
58  }
59 
60  result = stringbuffer_getstringcopy(sb);
62 
63  return result;
64 }
65 /* takes a GEOMETRY and appends to string buffer the x3d output */
66 static int
67 lwgeom_to_x3d3_sb(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
68 {
69  int type = geom->type;
70 
71  switch (type)
72  {
73  case POINTTYPE:
74  return asx3d3_point_sb((LWPOINT*)geom, srs, precision, opts, defid, sb);
75 
76  case LINETYPE:
77  return asx3d3_line_sb((LWLINE*)geom, srs, precision, opts, defid, sb);
78 
79  case POLYGONTYPE:
80  {
85  asx3d3_multi_sb(tmp, srs, precision, opts, defid, sb);
86  lwcollection_free(tmp);
87  return LW_SUCCESS;
88  }
89 
90  case TRIANGLETYPE:
91  return asx3d3_triangle_sb((LWTRIANGLE*)geom, srs, precision, opts, defid, sb);
92 
93  case MULTIPOINTTYPE:
94  case MULTILINETYPE:
95  case MULTIPOLYGONTYPE:
96  return asx3d3_multi_sb((LWCOLLECTION*)geom, srs, precision, opts, defid, sb);
97 
99  return asx3d3_psurface_sb((LWPSURFACE*)geom, srs, precision, opts, defid, sb);
100 
101  case TINTYPE:
102  return asx3d3_tin_sb((LWTIN*)geom, srs, precision, opts, defid, sb);
103 
104  case COLLECTIONTYPE:
105  return asx3d3_collection_sb((LWCOLLECTION*)geom, srs, precision, opts, defid, sb);
106 
107  default:
108  lwerror("lwgeom_to_x3d3: '%s' geometry type not supported", lwtype_name(type));
109  return LW_FAILURE;
110  }
111 }
112 
113 static int
114 asx3d3_point_sb(const LWPOINT *point, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
115 {
117  return ptarray_to_x3d3_sb(point->point, precision, opts, 0, sb);
118 }
119 
120 static int
121 asx3d3_line_coords_sb(const LWLINE *line, int precision, int opts, stringbuffer_t *sb)
122 {
123  return ptarray_to_x3d3_sb(line->points, precision, opts, lwline_is_closed(line), sb);
124 }
125 
126 /* Calculate the coordIndex property of the IndexedLineSet for the multilinestring
127 and add to string buffer */
128 static int
130 {
131  LWLINE *geom;
132  uint32_t i, j, k, si;
133  POINTARRAY *pa;
134  uint32_t np;
135 
136  j = 0;
137  for (i=0; i < mgeom->ngeoms; i++)
138  {
139  geom = (LWLINE *) mgeom->geoms[i];
140  pa = geom->points;
141  np = pa->npoints;
142  si = j; /* start index of first point of linestring */
143  for (k=0; k < np ; k++)
144  {
145  if (k)
146  {
147  stringbuffer_aprintf(sb, " ");
148  }
152  if (!lwline_is_closed(geom) || k < (np -1) )
153  {
154  stringbuffer_aprintf(sb, "%u", j);
155  j += 1;
156  }
157  else
158  {
159  stringbuffer_aprintf(sb,"%u", si);
160  }
161  }
162  if (i < (mgeom->ngeoms - 1) )
163  {
164  stringbuffer_aprintf(sb, " -1 "); /* separator for each linestring */
165  }
166  }
167  return LW_SUCCESS;
168 }
169 
170 /* Calculate the coordIndex property of the IndexedLineSet for a multipolygon
171  This is not ideal -- would be really nice to just share this function with psurf,
172  but I'm not smart enough to do that yet*/
173 static int
175 {
176  LWPOLY *patch;
177  uint32_t i, j, k, l;
178  uint32_t np;
179  j = 0;
180  for (i=0; i<psur->ngeoms; i++)
181  {
182  patch = (LWPOLY *) psur->geoms[i];
183  for (l=0; l < patch->nrings; l++)
184  {
185  np = patch->rings[l]->npoints - 1;
186  for (k=0; k < np ; k++)
187  {
188  if (k)
189  {
190  stringbuffer_aprintf(sb, " ");
191  }
192  stringbuffer_aprintf(sb, "%d", (j + k));
193  }
194  j += k;
195  if (l < (patch->nrings - 1) )
196  {
205  stringbuffer_aprintf(sb, " -1 "); /* separator for each inner ring. Ideally we should probably triangulate and cut around as others do */
206  }
207  }
208  if (i < (psur->ngeoms - 1) )
209  {
210  stringbuffer_aprintf(sb, " -1 "); /* separator for each subgeom */
211  }
212  }
213  return LW_SUCCESS;
214 }
215 
217 static int
218 asx3d3_line_sb(const LWLINE *line, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
219 {
220 
221  /* int dimension=2; */
222  POINTARRAY *pa;
223 
224 
225  /* if (FLAGS_GET_Z(line->flags)) dimension = 3; */
226 
227  pa = line->points;
228  stringbuffer_aprintf(sb, "<LineSet %s vertexCount='%d'>", defid, pa->npoints);
229 
230  if ( X3D_USE_GEOCOORDS(opts) ) stringbuffer_aprintf(sb, "<GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
231  else
232  stringbuffer_aprintf(sb, "<Coordinate point='");
233 
234  ptarray_to_x3d3_sb(line->points, precision, opts, lwline_is_closed((LWLINE *) line), sb);
235 
236 
237  stringbuffer_aprintf(sb, "' />");
238 
239  return stringbuffer_aprintf(sb, "</LineSet>");
240 }
241 
243 static int
244 asx3d3_poly_sb(const LWPOLY *poly, char *srs, int precision, int opts, int is_patch, const char *defid, stringbuffer_t *sb)
245 {
246  uint32_t i;
247  for (i=0; i<poly->nrings; i++)
248  {
249  if (i) stringbuffer_aprintf(sb, " "); /* inner ring points start */
250  ptarray_to_x3d3_sb(poly->rings[i], precision, opts, 1, sb);
251  }
252  return LW_SUCCESS;
253 }
254 
255 static int
256 asx3d3_triangle_sb(const LWTRIANGLE *triangle, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
257 {
258  return ptarray_to_x3d3_sb(triangle->points, precision, opts, 1, sb);
259 }
260 
261 
262 /*
263  * Don't call this with single-geoms inspected!
264  */
265 static int
266 asx3d3_multi_sb(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
267 {
268  char *x3dtype;
269  uint32_t i;
270  int dimension=2;
271 
272  if (FLAGS_GET_Z(col->flags)) dimension = 3;
273  LWGEOM *subgeom;
274  x3dtype="";
275 
276 
277  switch (col->type)
278  {
279  case MULTIPOINTTYPE:
280  x3dtype = "PointSet";
281  if ( dimension == 2 ){
282  x3dtype = "Polypoint2D";
283  stringbuffer_aprintf(sb, "<%s %s point='", x3dtype, defid);
284  }
285  else {
286  stringbuffer_aprintf(sb, "<%s %s>", x3dtype, defid);
287  }
288  break;
289  case MULTILINETYPE:
290  x3dtype = "IndexedLineSet";
291  stringbuffer_aprintf(sb, "<%s %s coordIndex='", x3dtype, defid);
292  asx3d3_mline_coordindex_sb((const LWMLINE *)col, sb);
293  stringbuffer_aprintf(sb, "'>");
294  break;
295  case MULTIPOLYGONTYPE:
296  x3dtype = "IndexedFaceSet";
297  stringbuffer_aprintf(sb, "<%s %s convex='false' coordIndex='", x3dtype, defid);
298  asx3d3_mpoly_coordindex_sb((const LWMPOLY *)col, sb);
299  stringbuffer_aprintf(sb, "'>");
300  break;
301  default:
302  lwerror("asx3d3_multi_buf: '%s' geometry type not supported", lwtype_name(col->type));
303  return 0;
304  }
305  if (dimension == 3){
306  if ( X3D_USE_GEOCOORDS(opts) )
307  stringbuffer_aprintf(sb, "<GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ((opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
308  else
309  stringbuffer_aprintf(sb, "<Coordinate point='");
310  }
311 
312  for (i=0; i<col->ngeoms; i++)
313  {
314  subgeom = col->geoms[i];
315  if (subgeom->type == POINTTYPE)
316  {
317  asx3d3_point_sb((LWPOINT*)subgeom, 0, precision, opts, defid, sb);
318  stringbuffer_aprintf(sb, " ");
319  }
320  else if (subgeom->type == LINETYPE)
321  {
322  asx3d3_line_coords_sb((LWLINE*)subgeom, precision, opts, sb);
323  stringbuffer_aprintf(sb, " ");
324  }
325  else if (subgeom->type == POLYGONTYPE)
326  {
327  asx3d3_poly_sb((LWPOLY*)subgeom, 0, precision, opts, 0, defid, sb);
328  stringbuffer_aprintf(sb, " ");
329  }
330  }
331 
332  /* Close outmost tag */
333  if (dimension == 3){
334  stringbuffer_aprintf(sb, "' /></%s>", x3dtype);
335  }
336  else { stringbuffer_aprintf(sb, "' />"); }
337  return LW_SUCCESS;
338 
339 }
340 
341 /*
342  * Don't call this with single-geoms inspected!
343  */
344 static int
345 asx3d3_psurface_sb(const LWPSURFACE *psur, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
346 {
347  uint32_t i;
348  uint32_t j;
349  uint32_t k;
350  uint32_t np;
351  LWPOLY *patch;
352 
353  /* Open outmost tag */
354  stringbuffer_aprintf(sb, "<IndexedFaceSet convex='false' %s coordIndex='",defid);
355 
356  j = 0;
357  for (i=0; i<psur->ngeoms; i++)
358  {
359  patch = (LWPOLY *) psur->geoms[i];
360  np = patch->rings[0]->npoints - 1;
361  for (k=0; k < np ; k++)
362  {
363  if (k)
364  {
365  stringbuffer_aprintf(sb, " ");
366  }
367  stringbuffer_aprintf(sb,"%d", (j + k));
368  }
369  if (i < (psur->ngeoms - 1) )
370  {
371  stringbuffer_aprintf(sb, " -1 "); /* separator for each subgeom */
372  }
373  j += k;
374  }
375 
376  if ( X3D_USE_GEOCOORDS(opts) )
377  stringbuffer_aprintf(sb, "'><GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='",
378  ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
379  else stringbuffer_aprintf(sb, "'><Coordinate point='");
380 
381  for (i=0; i<psur->ngeoms; i++)
382  {
383  asx3d3_poly_sb(psur->geoms[i], srs, precision, opts, 1, defid, sb);
384  if (i < (psur->ngeoms - 1) )
385  {
386  stringbuffer_aprintf(sb, " "); /* only add a trailing space if its not the last polygon in the set */
387  }
388  }
389 
390  /* Close outmost tag */
391  return stringbuffer_aprintf(sb, "' /></IndexedFaceSet>");
392 }
393 
394 /*
395  * Computes X3D representation of TIN (as IndexedTriangleSet and adds to string buffer)
396  */
397 static int
398 asx3d3_tin_sb(const LWTIN *tin, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
399 {
400  uint32_t i;
401  uint32_t k;
402  /* int dimension=2; */
403 
404  stringbuffer_aprintf(sb,"<IndexedTriangleSet %s index='",defid);
405  k = 0;
407  for (i=0; i<tin->ngeoms; i++)
408  {
409  stringbuffer_aprintf(sb, "%d %d %d", k, (k+1), (k+2));
410  if (i < (tin->ngeoms - 1) )
411  {
412  stringbuffer_aprintf(sb, " ");
413  }
414  k += 3;
415  }
416 
417  if ( X3D_USE_GEOCOORDS(opts) ) stringbuffer_aprintf(sb, "'><GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
418  else stringbuffer_aprintf(sb, "'><Coordinate point='");
419 
420  for (i=0; i<tin->ngeoms; i++)
421  {
422  asx3d3_triangle_sb(tin->geoms[i], 0, precision,
423  opts, defid, sb);
424  if (i < (tin->ngeoms - 1) )
425  {
426  stringbuffer_aprintf(sb, " ");
427  }
428  }
429 
430  /* Close outmost tag */
431 
432  return stringbuffer_aprintf(sb, "'/></IndexedTriangleSet>");
433 }
434 
435 static int
436 asx3d3_collection_sb(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
437 {
438  uint32_t i;
439  LWGEOM *subgeom;
440 
441  /* Open outmost tag */
444 #ifdef PGIS_X3D_OUTERMOST_TAGS
445  stringbuffer_aprintf(sb, "<%sGroup>", defid);
446 #endif
447 
448  for (i=0; i<col->ngeoms; i++)
449  {
450  subgeom = col->geoms[i];
451  stringbuffer_aprintf(sb, "<Shape%s>", defid);
452  if ( subgeom->type == POINTTYPE )
453  {
454  asx3d3_point_sb((LWPOINT*)subgeom, 0, precision, opts, defid, sb);
455  }
456  else if ( subgeom->type == LINETYPE )
457  {
458  asx3d3_line_sb((LWLINE*)subgeom, 0, precision, opts, defid, sb);
459  }
460  else if ( subgeom->type == POLYGONTYPE )
461  {
462  asx3d3_poly_sb((LWPOLY*)subgeom, 0, precision, opts, 0, defid, sb);
463  }
464  else if ( subgeom->type == TINTYPE )
465  {
466  asx3d3_tin_sb((LWTIN*)subgeom, srs, precision, opts, defid, sb);
467 
468  }
469  else if ( subgeom->type == POLYHEDRALSURFACETYPE )
470  {
471  asx3d3_psurface_sb((LWPSURFACE*)subgeom, srs, precision, opts, defid, sb);
472 
473  }
474  else if ( lwgeom_is_collection(subgeom) )
475  {
476  if ( subgeom->type == COLLECTIONTYPE )
477  asx3d3_collection_sb((LWCOLLECTION*)subgeom, 0, precision, opts, defid, sb);
478  else
479  asx3d3_multi_sb((LWCOLLECTION*)subgeom, 0, precision, opts, defid, sb);
480  }
481  else
482  lwerror("asx3d3_collection_buf: unknown geometry type");
483 
484  stringbuffer_aprintf(sb, "</Shape>");
485  }
486 
487  /* Close outmost tag */
488 #ifdef PGIS_X3D_OUTERMOST_TAGS
489  stringbuffer_aprintf(sb, "</%sGroup>", defid);
490 #endif
491 
492  return LW_SUCCESS;
493 }
494 
497 static int
498 ptarray_to_x3d3_sb(POINTARRAY *pa, int precision, int opts, int is_closed, stringbuffer_t *sb )
499 {
500  uint32_t i;
503  char z[OUT_DOUBLE_BUFFER_SIZE];
504 
505  if ( ! FLAGS_GET_Z(pa->flags) )
506  {
507  for (i=0; i<pa->npoints; i++)
508  {
510  if ( !is_closed || i < (pa->npoints - 1) )
511  {
512  POINT2D pt;
513  getPoint2d_p(pa, i, &pt);
514 
516  pt.x, precision, x, OUT_DOUBLE_BUFFER_SIZE);
518  pt.y, precision, y, OUT_DOUBLE_BUFFER_SIZE);
519 
520  if ( i ) stringbuffer_append(sb," ");
521 
522  if ( ( opts & LW_X3D_FLIP_XY) )
523  stringbuffer_aprintf(sb, "%s %s", y, x);
524  else
525  stringbuffer_aprintf(sb, "%s %s", x, y);
526  }
527  }
528  }
529  else
530  {
531  for (i=0; i<pa->npoints; i++)
532  {
534  if ( !is_closed || i < (pa->npoints - 1) )
535  {
536  POINT4D pt;
537  getPoint4d_p(pa, i, &pt);
538 
540  pt.x, precision, x, OUT_DOUBLE_BUFFER_SIZE);
542  pt.y, precision, y, OUT_DOUBLE_BUFFER_SIZE);
544  pt.z, precision, z, OUT_DOUBLE_BUFFER_SIZE);
545 
546  if ( i ) stringbuffer_append(sb," ");
547 
548  if ( ( opts & LW_X3D_FLIP_XY) )
549  stringbuffer_aprintf(sb, "%s %s %s", y, x, z);
550  else
551  stringbuffer_aprintf(sb, "%s %s %s", x, y, z);
552  }
553  }
554  }
555 
556  return LW_SUCCESS;
557 }
double x
Definition: liblwgeom.h:351
#define LINETYPE
Definition: liblwgeom.h:85
int lwprint_double(double d, int maxdd, char *buf, size_t bufsize)
Definition: lwprint.c:488
POINTARRAY * points
Definition: liblwgeom.h:432
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
Definition: lwgeom.c:1078
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:35
static int asx3d3_tin_sb(const LWTIN *tin, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:398
uint8_t type
Definition: liblwgeom.h:502
static int asx3d3_line_sb(const LWLINE *line, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Return the linestring as an X3D LineSet.
Definition: lwout_x3d.c:218
uint32_t ngeoms
Definition: liblwgeom.h:493
static int asx3d3_poly_sb(const LWPOLY *poly, char *srs, int precision, int opts, int is_patch, const char *defid, stringbuffer_t *sb)
Compute the X3D coordinates of the polygon and add to string buffer.
Definition: lwout_x3d.c:244
#define POLYGONTYPE
Definition: liblwgeom.h:86
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string...
Definition: stringbuffer.c:160
#define MULTIPOINTTYPE
Definition: liblwgeom.h:87
#define LW_SUCCESS
Definition: liblwgeom.h:79
static int asx3d3_psurface_sb(const LWPSURFACE *psur, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:345
#define TRIANGLETYPE
Definition: liblwgeom.h:97
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:96
LWPOLY ** geoms
Definition: liblwgeom.h:573
uint32_t ngeoms
Definition: liblwgeom.h:571
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
Definition: lwgeom.c:364
static int asx3d3_line_coords_sb(const LWLINE *line, int precision, int opts, stringbuffer_t *sb)
Definition: lwout_x3d.c:121
uint32_t ngeoms
Definition: liblwgeom.h:506
POINTARRAY * point
Definition: liblwgeom.h:410
#define X3D_USE_GEOCOORDS(x)
Definition: liblwgeom.h:1555
static int asx3d3_triangle_sb(const LWTRIANGLE *triangle, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:256
uint32_t nrings
Definition: liblwgeom.h:454
#define LW_FAILURE
Definition: liblwgeom.h:78
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided...
Definition: stringbuffer.c:253
unsigned int uint32_t
Definition: uthash.h:78
double x
Definition: liblwgeom.h:327
uint8_t flags
Definition: liblwgeom.h:503
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
static int asx3d3_point_sb(const LWPOINT *point, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:114
uint8_t flags
Definition: liblwgeom.h:368
LWPOLY ** geoms
Definition: liblwgeom.h:495
LWGEOM ** geoms
Definition: liblwgeom.h:508
#define TINTYPE
Definition: liblwgeom.h:98
LWTRIANGLE ** geoms
Definition: liblwgeom.h:586
static int asx3d3_mline_coordindex_sb(const LWMLINE *mgeom, stringbuffer_t *sb)
Definition: lwout_x3d.c:129
POINTARRAY ** rings
Definition: liblwgeom.h:456
#define LW_X3D_FLIP_XY
Macros for specifying X3D options.
Definition: liblwgeom.h:1553
uint8_t precision
Definition: cu_in_twkb.c:25
char * lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid)
Definition: lwout_x3d.c:36
double y
Definition: liblwgeom.h:327
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:139
double z
Definition: liblwgeom.h:351
tuple x
Definition: pixval.py:53
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition: lwgeom_api.c:113
static int asx3d3_multi_sb(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:266
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:89
uint32_t ngeoms
Definition: liblwgeom.h:480
static int asx3d3_mpoly_coordindex_sb(const LWMPOLY *psur, stringbuffer_t *sb)
Definition: lwout_x3d.c:174
LWLINE ** geoms
Definition: liblwgeom.h:482
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:338
void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
Definition: stringbuffer.c:134
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:78
static int lwgeom_to_x3d3_sb(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:67
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:454
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
uint8_t type
Definition: liblwgeom.h:395
static int asx3d3_collection_sb(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition: lwout_x3d.c:436
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:342
static int ptarray_to_x3d3_sb(POINTARRAY *pa, int precision, int opts, int is_closed, stringbuffer_t *sb)
In X3D3, coordinates are separated by a space separator.
Definition: lwout_x3d.c:498
#define OUT_DOUBLE_BUFFER_SIZE
void * lwalloc(size_t size)
Definition: lwutil.c:229
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1386
double y
Definition: liblwgeom.h:351
#define MULTILINETYPE
Definition: liblwgeom.h:88
uint32_t ngeoms
Definition: liblwgeom.h:584
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
tuple y
Definition: pixval.py:54
#define COLLECTIONTYPE
Definition: liblwgeom.h:90
POINTARRAY * points
Definition: liblwgeom.h:421
uint32_t npoints
Definition: liblwgeom.h:370