PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
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
30#include "lwout_x3d.h"
31
32/*
33 * VERSION X3D 3.0.2 http://www.web3d.org/specifications/x3d-3.0.dtd
34 */
35/* takes a GEOMETRY and returns a X3D representation */
37lwgeom_to_x3d3(const LWGEOM *geom, int precision, int opts, const char *defid)
38{
40 int rv;
41
42 /* Empty varlena for empties */
43 if( lwgeom_is_empty(geom) )
44 {
47 return v;
48 }
49
51 rv = lwgeom_to_x3d3_sb(geom, precision, opts, defid, sb);
52
53 if ( rv == LW_FAILURE )
54 {
56 return NULL;
57 }
58
61
62 return v;
63}
64/* takes a GEOMETRY and appends to string buffer the x3d output */
65static int
66lwgeom_to_x3d3_sb(const LWGEOM *geom, int precision, int opts, const char *defid, stringbuffer_t *sb)
67{
68 int type = geom->type;
69
70 switch (type)
71 {
72 case POINTTYPE:
73 return asx3d3_point_sb((LWPOINT *)geom, precision, opts, defid, sb);
74
75 case LINETYPE:
76 return asx3d3_line_sb((LWLINE *)geom, precision, opts, defid, sb);
77
78 case POLYGONTYPE:
79 {
84 asx3d3_multi_sb(tmp, precision, opts, defid, sb);
86 return LW_SUCCESS;
87 }
88
89 case TRIANGLETYPE:
90 return asx3d3_triangle_sb((LWTRIANGLE *)geom, precision, opts, defid, sb);
91
92 case MULTIPOINTTYPE:
93 case MULTILINETYPE:
95 return asx3d3_multi_sb((LWCOLLECTION *)geom, precision, opts, defid, sb);
96
98 return asx3d3_psurface_sb((LWPSURFACE *)geom, precision, opts, defid, sb);
99
100 case TINTYPE:
101 return asx3d3_tin_sb((LWTIN *)geom, precision, opts, defid, sb);
102
103 case COLLECTIONTYPE:
104 return asx3d3_collection_sb((LWCOLLECTION *)geom, precision, opts, defid, sb);
105
106 default:
107 lwerror("lwgeom_to_x3d3: '%s' geometry type not supported", lwtype_name(type));
108 return LW_FAILURE;
109 }
110}
111
112static int
114 int precision,
115 int opts,
116 __attribute__((__unused__)) const char *defid,
117 stringbuffer_t *sb)
118{
120 return ptarray_to_x3d3_sb(point->point, precision, opts, 0, sb);
121}
122
123static int
124asx3d3_line_coords_sb(const LWLINE *line, int precision, int opts, stringbuffer_t *sb)
125{
126 return ptarray_to_x3d3_sb(line->points, precision, opts, lwline_is_closed(line), sb);
127}
128
129/* Calculate the coordIndex property of the IndexedLineSet for the multilinestring
130and add to string buffer */
131static int
133{
134 LWLINE *geom;
135 uint32_t i, j, k, si;
136 POINTARRAY *pa;
137 uint32_t np;
138
139 j = 0;
140 for (i=0; i < mgeom->ngeoms; i++)
141 {
142 geom = (LWLINE *) mgeom->geoms[i];
143 pa = geom->points;
144 np = pa->npoints;
145 si = j; /* start index of first point of linestring */
146 for (k=0; k < np ; k++)
147 {
148 if (k)
149 {
150 stringbuffer_aprintf(sb, " ");
151 }
155 if (!lwline_is_closed(geom) || k < (np -1) )
156 {
157 stringbuffer_aprintf(sb, "%u", j);
158 j += 1;
159 }
160 else
161 {
162 stringbuffer_aprintf(sb,"%u", si);
163 }
164 }
165 if (i < (mgeom->ngeoms - 1) )
166 {
167 stringbuffer_aprintf(sb, " -1 "); /* separator for each linestring */
168 }
169 }
170 return LW_SUCCESS;
171}
172
173/* Calculate the coordIndex property of the IndexedLineSet for a multipolygon
174 This is not ideal -- would be really nice to just share this function with psurf,
175 but I'm not smart enough to do that yet*/
176static int
178{
179 LWPOLY *patch;
180 uint32_t i, j, k, l;
181 uint32_t np;
182 j = 0;
183 for (i=0; i<psur->ngeoms; i++)
184 {
185 patch = (LWPOLY *) psur->geoms[i];
186 for (l=0; l < patch->nrings; l++)
187 {
188 np = patch->rings[l]->npoints - 1;
189 for (k=0; k < np ; k++)
190 {
191 if (k)
192 {
193 stringbuffer_aprintf(sb, " ");
194 }
195 stringbuffer_aprintf(sb, "%d", (j + k));
196 }
197 j += k;
198 if (l < (patch->nrings - 1) )
199 {
208 stringbuffer_aprintf(sb, " -1 "); /* separator for each inner ring. Ideally we should probably triangulate and cut around as others do */
209 }
210 }
211 if (i < (psur->ngeoms - 1) )
212 {
213 stringbuffer_aprintf(sb, " -1 "); /* separator for each subgeom */
214 }
215 }
216 return LW_SUCCESS;
217}
218
220static int
222 int precision,
223 int opts,
224 __attribute__((__unused__)) const char *defid,
225 stringbuffer_t *sb)
226{
227
228 /* int dimension=2; */
229 POINTARRAY *pa;
230
231
232 /* if (FLAGS_GET_Z(line->flags)) dimension = 3; */
233
234 pa = line->points;
235 stringbuffer_aprintf(sb, "<LineSet %s vertexCount='%d'>", defid, pa->npoints);
236
237 if ( X3D_USE_GEOCOORDS(opts) ) stringbuffer_aprintf(sb, "<GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
238 else
239 stringbuffer_aprintf(sb, "<Coordinate point='");
240
241 ptarray_to_x3d3_sb(line->points, precision, opts, lwline_is_closed((LWLINE *) line), sb);
242
243
244 stringbuffer_aprintf(sb, "' />");
245
246 return stringbuffer_aprintf(sb, "</LineSet>");
247}
248
250static int
252 int precision,
253 int opts,
254 __attribute__((__unused__)) int is_patch,
255 __attribute__((__unused__)) const char *defid,
256 stringbuffer_t *sb)
257{
258 uint32_t i;
259 for (i=0; i<poly->nrings; i++)
260 {
261 if (i) stringbuffer_aprintf(sb, " "); /* inner ring points start */
262 ptarray_to_x3d3_sb(poly->rings[i], precision, opts, 1, sb);
263 }
264 return LW_SUCCESS;
265}
266
267static int
269 int precision,
270 int opts,
271 __attribute__((__unused__)) const char *defid,
272 stringbuffer_t *sb)
273{
274 return ptarray_to_x3d3_sb(triangle->points, precision, opts, 1, sb);
275}
276
277
278/*
279 * Don't call this with single-geoms inspected!
280 */
281static int
282asx3d3_multi_sb(const LWCOLLECTION *col, int precision, int opts, const char *defid, stringbuffer_t *sb)
283{
284 char *x3dtype;
285 uint32_t i;
286 int dimension=2;
287
288 if (FLAGS_GET_Z(col->flags)) dimension = 3;
289 LWGEOM *subgeom;
290 x3dtype="";
291
292
293 switch (col->type)
294 {
295 case MULTIPOINTTYPE:
296 x3dtype = "PointSet";
297 if ( dimension == 2 ){
298 x3dtype = "Polypoint2D";
299 stringbuffer_aprintf(sb, "<%s %s point='", x3dtype, defid);
300 }
301 else {
302 stringbuffer_aprintf(sb, "<%s %s>", x3dtype, defid);
303 }
304 break;
305 case MULTILINETYPE:
306 x3dtype = "IndexedLineSet";
307 stringbuffer_aprintf(sb, "<%s %s coordIndex='", x3dtype, defid);
308 asx3d3_mline_coordindex_sb((const LWMLINE *)col, sb);
309 stringbuffer_aprintf(sb, "'>");
310 break;
311 case MULTIPOLYGONTYPE:
312 x3dtype = "IndexedFaceSet";
313 stringbuffer_aprintf(sb, "<%s %s convex='false' coordIndex='", x3dtype, defid);
314 asx3d3_mpoly_coordindex_sb((const LWMPOLY *)col, sb);
315 stringbuffer_aprintf(sb, "'>");
316 break;
317 default:
318 lwerror("asx3d3_multi_buf: '%s' geometry type not supported", lwtype_name(col->type));
319 return 0;
320 }
321 if (dimension == 3){
322 if ( X3D_USE_GEOCOORDS(opts) )
323 stringbuffer_aprintf(sb, "<GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ((opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
324 else
325 stringbuffer_aprintf(sb, "<Coordinate point='");
326 }
327
328 for (i=0; i<col->ngeoms; i++)
329 {
330 subgeom = col->geoms[i];
331 if (subgeom->type == POINTTYPE)
332 {
333 asx3d3_point_sb((LWPOINT *)subgeom, precision, opts, defid, sb);
334 stringbuffer_aprintf(sb, " ");
335 }
336 else if (subgeom->type == LINETYPE)
337 {
338 asx3d3_line_coords_sb((LWLINE*)subgeom, precision, opts, sb);
339 stringbuffer_aprintf(sb, " ");
340 }
341 else if (subgeom->type == POLYGONTYPE)
342 {
343 asx3d3_poly_sb((LWPOLY *)subgeom, precision, opts, 0, defid, sb);
344 stringbuffer_aprintf(sb, " ");
345 }
346 }
347
348 /* Close outmost tag */
349 if (dimension == 3){
350 stringbuffer_aprintf(sb, "' /></%s>", x3dtype);
351 }
352 else { stringbuffer_aprintf(sb, "' />"); }
353 return LW_SUCCESS;
354
355}
356
357/*
358 * Don't call this with single-geoms inspected!
359 */
360static int
361asx3d3_psurface_sb(const LWPSURFACE *psur, int precision, int opts, const char *defid, stringbuffer_t *sb)
362{
363 uint32_t i;
364 uint32_t j;
365 uint32_t k;
366 uint32_t np;
367 LWPOLY *patch;
368
369 /* Open outmost tag */
370 stringbuffer_aprintf(sb, "<IndexedFaceSet convex='false' %s coordIndex='",defid);
371
372 j = 0;
373 for (i=0; i<psur->ngeoms; i++)
374 {
375 patch = (LWPOLY *) psur->geoms[i];
376 np = patch->rings[0]->npoints - 1;
377 for (k=0; k < np ; k++)
378 {
379 if (k)
380 {
381 stringbuffer_aprintf(sb, " ");
382 }
383 stringbuffer_aprintf(sb,"%d", (j + k));
384 }
385 if (i < (psur->ngeoms - 1) )
386 {
387 stringbuffer_aprintf(sb, " -1 "); /* separator for each subgeom */
388 }
389 j += k;
390 }
391
392 if ( X3D_USE_GEOCOORDS(opts) )
393 stringbuffer_aprintf(sb, "'><GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='",
394 ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
395 else stringbuffer_aprintf(sb, "'><Coordinate point='");
396
397 for (i=0; i<psur->ngeoms; i++)
398 {
399 asx3d3_poly_sb(psur->geoms[i], precision, opts, 1, defid, sb);
400 if (i < (psur->ngeoms - 1) )
401 {
402 stringbuffer_aprintf(sb, " "); /* only add a trailing space if its not the last polygon in the set */
403 }
404 }
405
406 /* Close outmost tag */
407 return stringbuffer_aprintf(sb, "' /></IndexedFaceSet>");
408}
409
410/*
411 * Computes X3D representation of TIN (as IndexedTriangleSet and adds to string buffer)
412 */
413static int
414asx3d3_tin_sb(const LWTIN *tin, int precision, int opts, const char *defid, stringbuffer_t *sb)
415{
416 uint32_t i;
417 uint32_t k;
418 /* int dimension=2; */
419
420 stringbuffer_aprintf(sb,"<IndexedTriangleSet %s index='",defid);
421 k = 0;
423 for (i=0; i<tin->ngeoms; i++)
424 {
425 stringbuffer_aprintf(sb, "%d %d %d", k, (k+1), (k+2));
426 if (i < (tin->ngeoms - 1) )
427 {
428 stringbuffer_aprintf(sb, " ");
429 }
430 k += 3;
431 }
432
433 if ( X3D_USE_GEOCOORDS(opts) ) stringbuffer_aprintf(sb, "'><GeoCoordinate geoSystem='\"GD\" \"WE\" \"%s\"' point='", ( (opts & LW_X3D_FLIP_XY) ? "latitude_first" : "longitude_first") );
434 else stringbuffer_aprintf(sb, "'><Coordinate point='");
435
436 for (i=0; i<tin->ngeoms; i++)
437 {
438 asx3d3_triangle_sb(tin->geoms[i], precision, opts, defid, sb);
439 if (i < (tin->ngeoms - 1) )
440 {
441 stringbuffer_aprintf(sb, " ");
442 }
443 }
444
445 /* Close outmost tag */
446
447 return stringbuffer_aprintf(sb, "'/></IndexedTriangleSet>");
448}
449
450static int
451asx3d3_collection_sb(const LWCOLLECTION *col, int precision, int opts, const char *defid, stringbuffer_t *sb)
452{
453 uint32_t i;
454 LWGEOM *subgeom;
455
456 /* Open outmost tag */
459#ifdef PGIS_X3D_OUTERMOST_TAGS
460 stringbuffer_aprintf(sb, "<%sGroup>", defid);
461#endif
462
463 for (i=0; i<col->ngeoms; i++)
464 {
465 subgeom = col->geoms[i];
466 stringbuffer_aprintf(sb, "<Shape%s>", defid);
467 if ( subgeom->type == POINTTYPE )
468 {
469 asx3d3_point_sb((LWPOINT *)subgeom, precision, opts, defid, sb);
470 }
471 else if ( subgeom->type == LINETYPE )
472 {
473 asx3d3_line_sb((LWLINE *)subgeom, precision, opts, defid, sb);
474 }
475 else if ( subgeom->type == POLYGONTYPE )
476 {
477 asx3d3_poly_sb((LWPOLY *)subgeom, precision, opts, 0, defid, sb);
478 }
479 else if ( subgeom->type == TINTYPE )
480 {
481 asx3d3_tin_sb((LWTIN *)subgeom, precision, opts, defid, sb);
482 }
483 else if ( subgeom->type == POLYHEDRALSURFACETYPE )
484 {
485 asx3d3_psurface_sb((LWPSURFACE *)subgeom, precision, opts, defid, sb);
486 }
487 else if ( lwgeom_is_collection(subgeom) )
488 {
489 if ( subgeom->type == COLLECTIONTYPE )
490 asx3d3_collection_sb((LWCOLLECTION *)subgeom, precision, opts, defid, sb);
491 else
492 asx3d3_multi_sb((LWCOLLECTION *)subgeom, precision, opts, defid, sb);
493 }
494 else
495 lwerror("asx3d3_collection_buf: unknown geometry type");
496
497 stringbuffer_aprintf(sb, "</Shape>");
498 }
499
500 /* Close outmost tag */
501#ifdef PGIS_X3D_OUTERMOST_TAGS
502 stringbuffer_aprintf(sb, "</%sGroup>", defid);
503#endif
504
505 return LW_SUCCESS;
506}
507
510static int
511ptarray_to_x3d3_sb(POINTARRAY *pa, int precision, int opts, int is_closed, stringbuffer_t *sb )
512{
513 uint32_t i;
517
518 if ( ! FLAGS_GET_Z(pa->flags) )
519 {
520 for (i=0; i<pa->npoints; i++)
521 {
523 if ( !is_closed || i < (pa->npoints - 1) )
524 {
525 POINT2D pt;
526 getPoint2d_p(pa, i, &pt);
527
528 lwprint_double(pt.x, precision, x);
529 lwprint_double(pt.y, precision, y);
530
531 if ( i ) stringbuffer_append_len(sb," ",1);
532
533 if ( ( opts & LW_X3D_FLIP_XY) )
534 stringbuffer_aprintf(sb, "%s %s", y, x);
535 else
536 stringbuffer_aprintf(sb, "%s %s", x, y);
537 }
538 }
539 }
540 else
541 {
542 for (i=0; i<pa->npoints; i++)
543 {
545 if ( !is_closed || i < (pa->npoints - 1) )
546 {
547 POINT4D pt;
548 getPoint4d_p(pa, i, &pt);
549
550 lwprint_double(pt.x, precision, x);
551 lwprint_double(pt.y, precision, y);
552 lwprint_double(pt.z, precision, z);
553
554 if ( i ) stringbuffer_append_len(sb," ",1);
555
556 if ( ( opts & LW_X3D_FLIP_XY) )
557 stringbuffer_aprintf(sb, "%s %s %s", y, x, z);
558 else
559 stringbuffer_aprintf(sb, "%s %s %s", x, y, z);
560 }
561 }
562 }
563
564 return LW_SUCCESS;
565}
static uint8_t precision
Definition cu_in_twkb.c:25
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
#define COLLECTIONTYPE
Definition liblwgeom.h:108
#define LWVARHDRSZ
Definition liblwgeom.h:311
#define LW_FAILURE
Definition liblwgeom.h:96
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
Definition lwgeom.c:408
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
#define LW_SUCCESS
Definition liblwgeom.h:97
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition lwgeom_api.c:342
#define LW_X3D_FLIP_XY
Macros for specifying X3D options.
Definition liblwgeom.h:1730
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
#define TINTYPE
Definition liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
Definition lwgeom.c:1125
#define POLYGONTYPE
Definition liblwgeom.h:104
#define __attribute__(x)
Definition liblwgeom.h:228
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
void lwcollection_free(LWCOLLECTION *col)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
#define LWSIZE_SET(varsize, len)
Definition liblwgeom.h:325
#define TRIANGLETYPE
Definition liblwgeom.h:115
#define X3D_USE_GEOCOORDS(x)
Definition liblwgeom.h:1732
int lwline_is_closed(const LWLINE *line)
Definition lwline.c:455
#define OUT_DOUBLE_BUFFER_SIZE
int lwprint_double(double d, int maxdd, char *buf)
Definition lwprint.c:463
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:199
static int lwgeom_to_x3d3_sb(const LWGEOM *geom, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:66
static int asx3d3_collection_sb(const LWCOLLECTION *col, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:451
lwvarlena_t * lwgeom_to_x3d3(const LWGEOM *geom, int precision, int opts, const char *defid)
Definition lwout_x3d.c:37
static int asx3d3_point_sb(const LWPOINT *point, int precision, int opts, __attribute__((__unused__)) const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:113
static int asx3d3_multi_sb(const LWCOLLECTION *col, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:282
static int asx3d3_tin_sb(const LWTIN *tin, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:414
static int asx3d3_triangle_sb(const LWTRIANGLE *triangle, int precision, int opts, __attribute__((__unused__)) const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:268
static int asx3d3_poly_sb(const LWPOLY *poly, int precision, int opts, __attribute__((__unused__)) int is_patch, __attribute__((__unused__)) const char *defid, stringbuffer_t *sb)
Compute the X3D coordinates of the polygon and add to string buffer.
Definition lwout_x3d.c:251
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:511
static int asx3d3_mpoly_coordindex_sb(const LWMPOLY *psur, stringbuffer_t *sb)
Definition lwout_x3d.c:177
static int asx3d3_line_sb(const LWLINE *line, int precision, int opts, __attribute__((__unused__)) const char *defid, stringbuffer_t *sb)
Return the linestring as an X3D LineSet.
Definition lwout_x3d.c:221
static int asx3d3_line_coords_sb(const LWLINE *line, int precision, int opts, stringbuffer_t *sb)
Definition lwout_x3d.c:124
static int asx3d3_mline_coordindex_sb(const LWMLINE *mgeom, stringbuffer_t *sb)
Definition lwout_x3d.c:132
static int asx3d3_psurface_sb(const LWPSURFACE *psur, int precision, int opts, const char *defid, stringbuffer_t *sb)
Definition lwout_x3d.c:361
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
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.
lwvarlena_t * stringbuffer_getvarlenacopy(stringbuffer_t *s)
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
static void stringbuffer_append_len(stringbuffer_t *s, const char *a, size_t alen)
Append the specified string to the stringbuffer_t using known length.
lwflags_t flags
Definition liblwgeom.h:577
uint32_t ngeoms
Definition liblwgeom.h:580
uint8_t type
Definition liblwgeom.h:578
LWGEOM ** geoms
Definition liblwgeom.h:575
uint8_t type
Definition liblwgeom.h:462
POINTARRAY * points
Definition liblwgeom.h:483
LWLINE ** geoms
Definition liblwgeom.h:547
uint8_t type
Definition liblwgeom.h:550
uint32_t ngeoms
Definition liblwgeom.h:552
uint32_t ngeoms
Definition liblwgeom.h:566
LWPOLY ** geoms
Definition liblwgeom.h:561
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
LWPOLY ** geoms
Definition liblwgeom.h:645
uint32_t ngeoms
Definition liblwgeom.h:650
uint32_t ngeoms
Definition liblwgeom.h:664
LWTRIANGLE ** geoms
Definition liblwgeom.h:659
POINTARRAY * points
Definition liblwgeom.h:495
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427
uint32_t size
Definition liblwgeom.h:307