PostGIS  2.4.9dev-r@@SVN_REVISION@@
lwout_svg.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 2001-2003 Refractions Research Inc.
22  *
23  **********************************************************************/
24 
25 
35 #include "liblwgeom_internal.h"
36 
37 static char * assvg_point(const LWPOINT *point, int relative, int precision);
38 static char * assvg_line(const LWLINE *line, int relative, int precision);
39 static char * assvg_polygon(const LWPOLY *poly, int relative, int precision);
40 static char * assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision);
41 static char * assvg_multiline(const LWMLINE *mline, int relative, int precision);
42 static char * assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision);
43 static char * assvg_collection(const LWCOLLECTION *col, int relative, int precision);
44 
45 static size_t assvg_geom_size(const LWGEOM *geom, int relative, int precision);
46 static size_t assvg_geom_buf(const LWGEOM *geom, char *output, int relative, int precision);
47 static size_t pointArray_svg_size(POINTARRAY *pa, int precision);
48 static size_t pointArray_svg_rel(POINTARRAY *pa, char * output, int close_ring, int precision);
49 static size_t pointArray_svg_abs(POINTARRAY *pa, char * output, int close_ring, int precision);
50 
51 
55 char *
56 lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
57 {
58  char *ret = NULL;
59  int type = geom->type;
60 
61  /* Empty string for empties */
62  if( lwgeom_is_empty(geom) )
63  {
64  ret = lwalloc(1);
65  ret[0] = '\0';
66  return ret;
67  }
68 
69  switch (type)
70  {
71  case POINTTYPE:
72  ret = assvg_point((LWPOINT*)geom, relative, precision);
73  break;
74  case LINETYPE:
75  ret = assvg_line((LWLINE*)geom, relative, precision);
76  break;
77  case POLYGONTYPE:
78  ret = assvg_polygon((LWPOLY*)geom, relative, precision);
79  break;
80  case MULTIPOINTTYPE:
81  ret = assvg_multipoint((LWMPOINT*)geom, relative, precision);
82  break;
83  case MULTILINETYPE:
84  ret = assvg_multiline((LWMLINE*)geom, relative, precision);
85  break;
86  case MULTIPOLYGONTYPE:
87  ret = assvg_multipolygon((LWMPOLY*)geom, relative, precision);
88  break;
89  case COLLECTIONTYPE:
90  ret = assvg_collection((LWCOLLECTION*)geom, relative, precision);
91  break;
92 
93  default:
94  lwerror("lwgeom_to_svg: '%s' geometry type not supported",
95  lwtype_name(type));
96  }
97 
98  return ret;
99 }
100 
101 
106 static size_t
107 assvg_point_size(const LWPOINT *point, int circle, int precision)
108 {
109  size_t size;
110 
111  size = (OUT_MAX_DIGS_DOUBLE + precision) * 2;
112  if (circle) size += sizeof("cx='' cy=''");
113  else size += sizeof("x='' y=''");
114 
115  return size;
116 }
117 
118 static size_t
119 assvg_point_buf(const LWPOINT *point, char * output, int circle, int precision)
120 {
121  char *ptr=output;
124  POINT2D pt;
125 
126  getPoint2d_p(point->point, 0, &pt);
127 
128  if (fabs(pt.x) < OUT_MAX_DOUBLE)
129  sprintf(x, "%.*f", precision, pt.x);
130  else
131  sprintf(x, "%g", pt.x);
133 
134  /* SVG Y axis is reversed, an no need to transform 0 into -0 */
135  if (fabs(pt.y) < OUT_MAX_DOUBLE)
136  sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
137  else
138  sprintf(y, "%g", fabs(pt.y) ? pt.y * -1 : pt.y);
140 
141  if (circle) ptr += sprintf(ptr, "x=\"%s\" y=\"%s\"", x, y);
142  else ptr += sprintf(ptr, "cx=\"%s\" cy=\"%s\"", x, y);
143 
144  return (ptr-output);
145 }
146 
147 static char *
148 assvg_point(const LWPOINT *point, int circle, int precision)
149 {
150  char *output;
151  int size;
152 
153  size = assvg_point_size(point, circle, precision);
154  output = lwalloc(size);
155  assvg_point_buf(point, output, circle, precision);
156 
157  return output;
158 }
159 
160 
165 static size_t
166 assvg_line_size(const LWLINE *line, int relative, int precision)
167 {
168  size_t size;
169 
170  size = sizeof("M ");
171  size += pointArray_svg_size(line->points, precision);
172 
173  return size;
174 }
175 
176 static size_t
177 assvg_line_buf(const LWLINE *line, char * output, int relative, int precision)
178 {
179  char *ptr=output;
180 
181  /* Start path with SVG MoveTo */
182  ptr += sprintf(ptr, "M ");
183  if (relative)
184  ptr += pointArray_svg_rel(line->points, ptr, 1, precision);
185  else
186  ptr += pointArray_svg_abs(line->points, ptr, 1, precision);
187 
188  return (ptr-output);
189 }
190 
191 static char *
192 assvg_line(const LWLINE *line, int relative, int precision)
193 {
194  char *output;
195  int size;
196 
197  size = assvg_line_size(line, relative, precision);
198  output = lwalloc(size);
199  assvg_line_buf(line, output, relative, precision);
200 
201  return output;
202 }
203 
204 
209 static size_t
210 assvg_polygon_size(const LWPOLY *poly, int relative, int precision)
211 {
212  int i;
213  size_t size=0;
214 
215  for (i=0; i<poly->nrings; i++)
216  size += pointArray_svg_size(poly->rings[i], precision) + sizeof(" ");
217  size += sizeof("M Z") * poly->nrings;
218 
219  return size;
220 }
221 
222 static size_t
223 assvg_polygon_buf(const LWPOLY *poly, char * output, int relative, int precision)
224 {
225  int i;
226  char *ptr=output;
227 
228  for (i=0; i<poly->nrings; i++)
229  {
230  if (i) ptr += sprintf(ptr, " "); /* Space beetween each ring */
231  ptr += sprintf(ptr, "M "); /* Start path with SVG MoveTo */
232 
233  if (relative)
234  {
235  ptr += pointArray_svg_rel(poly->rings[i], ptr, 0, precision);
236  ptr += sprintf(ptr, " z"); /* SVG closepath */
237  }
238  else
239  {
240  ptr += pointArray_svg_abs(poly->rings[i], ptr, 0, precision);
241  ptr += sprintf(ptr, " Z"); /* SVG closepath */
242  }
243  }
244 
245  return (ptr-output);
246 }
247 
248 static char *
249 assvg_polygon(const LWPOLY *poly, int relative, int precision)
250 {
251  char *output;
252  int size;
253 
254  size = assvg_polygon_size(poly, relative, precision);
255  output = lwalloc(size);
256  assvg_polygon_buf(poly, output, relative, precision);
257 
258  return output;
259 }
260 
261 
266 static size_t
267 assvg_multipoint_size(const LWMPOINT *mpoint, int relative, int precision)
268 {
269  const LWPOINT *point;
270  size_t size=0;
271  int i;
272 
273  for (i=0 ; i<mpoint->ngeoms ; i++)
274  {
275  point = mpoint->geoms[i];
276  size += assvg_point_size(point, relative, precision);
277  }
278  size += sizeof(",") * --i; /* Arbitrary comma separator */
279 
280  return size;
281 }
282 
283 static size_t
284 assvg_multipoint_buf(const LWMPOINT *mpoint, char *output, int relative, int precision)
285 {
286  const LWPOINT *point;
287  int i;
288  char *ptr=output;
289 
290  for (i=0 ; i<mpoint->ngeoms ; i++)
291  {
292  if (i) ptr += sprintf(ptr, ","); /* Arbitrary comma separator */
293  point = mpoint->geoms[i];
294  ptr += assvg_point_buf(point, ptr, relative, precision);
295  }
296 
297  return (ptr-output);
298 }
299 
300 static char *
301 assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision)
302 {
303  char *output;
304  int size;
305 
306  size = assvg_multipoint_size(mpoint, relative, precision);
307  output = lwalloc(size);
308  assvg_multipoint_buf(mpoint, output, relative, precision);
309 
310  return output;
311 }
312 
313 
318 static size_t
319 assvg_multiline_size(const LWMLINE *mline, int relative, int precision)
320 {
321  const LWLINE *line;
322  size_t size=0;
323  int i;
324 
325  for (i=0 ; i<mline->ngeoms ; i++)
326  {
327  line = mline->geoms[i];
328  size += assvg_line_size(line, relative, precision);
329  }
330  size += sizeof(" ") * --i; /* SVG whitespace Separator */
331 
332  return size;
333 }
334 
335 static size_t
336 assvg_multiline_buf(const LWMLINE *mline, char *output, int relative, int precision)
337 {
338  const LWLINE *line;
339  int i;
340  char *ptr=output;
341 
342  for (i=0 ; i<mline->ngeoms ; i++)
343  {
344  if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
345  line = mline->geoms[i];
346  ptr += assvg_line_buf(line, ptr, relative, precision);
347  }
348 
349  return (ptr-output);
350 }
351 
352 static char *
353 assvg_multiline(const LWMLINE *mline, int relative, int precision)
354 {
355  char *output;
356  int size;
357 
358  size = assvg_multiline_size(mline, relative, precision);
359  output = lwalloc(size);
360  assvg_multiline_buf(mline, output, relative, precision);
361 
362  return output;
363 }
364 
365 
366 /*
367  * Multipolygon Geometry
368  */
369 
370 static size_t
371 assvg_multipolygon_size(const LWMPOLY *mpoly, int relative, int precision)
372 {
373  const LWPOLY *poly;
374  size_t size=0;
375  int i;
376 
377  for (i=0 ; i<mpoly->ngeoms ; i++)
378  {
379  poly = mpoly->geoms[i];
380  size += assvg_polygon_size(poly, relative, precision);
381  }
382  size += sizeof(" ") * --i; /* SVG whitespace Separator */
383 
384  return size;
385 }
386 
387 static size_t
388 assvg_multipolygon_buf(const LWMPOLY *mpoly, char *output, int relative, int precision)
389 {
390  const LWPOLY *poly;
391  int i;
392  char *ptr=output;
393 
394  for (i=0 ; i<mpoly->ngeoms ; i++)
395  {
396  if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
397  poly = mpoly->geoms[i];
398  ptr += assvg_polygon_buf(poly, ptr, relative, precision);
399  }
400 
401  return (ptr-output);
402 }
403 
404 static char *
405 assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision)
406 {
407  char *output;
408  int size;
409 
410  size = assvg_multipolygon_size(mpoly, relative, precision);
411  output = lwalloc(size);
412  assvg_multipolygon_buf(mpoly, output, relative, precision);
413 
414  return output;
415 }
416 
417 
422 static size_t
423 assvg_collection_size(const LWCOLLECTION *col, int relative, int precision)
424 {
425  int i = 0;
426  size_t size=0;
427  const LWGEOM *subgeom;
428 
429  for (i=0; i<col->ngeoms; i++)
430  {
431  subgeom = col->geoms[i];
432  size += assvg_geom_size(subgeom, relative, precision);
433  }
434 
435  if ( i ) /* We have some geometries, so add space for delimiters. */
436  size += sizeof(";") * --i;
437 
438  if (size == 0) size++; /* GEOMETRYCOLLECTION EMPTY, space for null terminator */
439 
440  return size;
441 }
442 
443 static size_t
444 assvg_collection_buf(const LWCOLLECTION *col, char *output, int relative, int precision)
445 {
446  int i;
447  char *ptr=output;
448  const LWGEOM *subgeom;
449 
450  /* EMPTY GEOMETRYCOLLECTION */
451  if (col->ngeoms == 0) *ptr = '\0';
452 
453  for (i=0; i<col->ngeoms; i++)
454  {
455  if (i) ptr += sprintf(ptr, ";");
456  subgeom = col->geoms[i];
457  ptr += assvg_geom_buf(subgeom, ptr, relative, precision);
458  }
459 
460  return (ptr - output);
461 }
462 
463 static char *
464 assvg_collection(const LWCOLLECTION *col, int relative, int precision)
465 {
466  char *output;
467  int size;
468 
469  size = assvg_collection_size(col, relative, precision);
470  output = lwalloc(size);
471  assvg_collection_buf(col, output, relative, precision);
472 
473  return output;
474 }
475 
476 
477 static size_t
478 assvg_geom_buf(const LWGEOM *geom, char *output, int relative, int precision)
479 {
480  int type = geom->type;
481  char *ptr=output;
482 
483  switch (type)
484  {
485  case POINTTYPE:
486  ptr += assvg_point_buf((LWPOINT*)geom, ptr, relative, precision);
487  break;
488 
489  case LINETYPE:
490  ptr += assvg_line_buf((LWLINE*)geom, ptr, relative, precision);
491  break;
492 
493  case POLYGONTYPE:
494  ptr += assvg_polygon_buf((LWPOLY*)geom, ptr, relative, precision);
495  break;
496 
497  case MULTIPOINTTYPE:
498  ptr += assvg_multipoint_buf((LWMPOINT*)geom, ptr, relative, precision);
499  break;
500 
501  case MULTILINETYPE:
502  ptr += assvg_multiline_buf((LWMLINE*)geom, ptr, relative, precision);
503  break;
504 
505  case MULTIPOLYGONTYPE:
506  ptr += assvg_multipolygon_buf((LWMPOLY*)geom, ptr, relative, precision);
507  break;
508 
509  default:
510  lwerror("assvg_geom_buf: '%s' geometry type not supported.",
511  lwtype_name(type));
512  }
513 
514  return (ptr-output);
515 }
516 
517 
518 static size_t
519 assvg_geom_size(const LWGEOM *geom, int relative, int precision)
520 {
521  int type = geom->type;
522  size_t size = 0;
523 
524  switch (type)
525  {
526  case POINTTYPE:
527  size = assvg_point_size((LWPOINT*)geom, relative, precision);
528  break;
529 
530  case LINETYPE:
531  size = assvg_line_size((LWLINE*)geom, relative, precision);
532  break;
533 
534  case POLYGONTYPE:
535  size = assvg_polygon_size((LWPOLY*)geom, relative, precision);
536  break;
537 
538  case MULTIPOINTTYPE:
539  size = assvg_multipoint_size((LWMPOINT*)geom, relative, precision);
540  break;
541 
542  case MULTILINETYPE:
543  size = assvg_multiline_size((LWMLINE*)geom, relative, precision);
544  break;
545 
546  case MULTIPOLYGONTYPE:
547  size = assvg_multipolygon_size((LWMPOLY*)geom, relative, precision);
548  break;
549 
550  default:
551  lwerror("assvg_geom_size: '%s' geometry type not supported.",
552  lwtype_name(type));
553  }
554 
555  return size;
556 }
557 
558 
559 static size_t
560 pointArray_svg_rel(POINTARRAY *pa, char *output, int close_ring, int precision)
561 {
562  int i, end;
563  char *ptr;
566  const POINT2D *pt;
567 
568  double f = 1.0;
569  double dx, dy, x, y, accum_x, accum_y;
570 
571  ptr = output;
572 
573  if (precision >= 0)
574  {
575  f = pow(10, precision);
576  }
577 
578  if (close_ring) end = pa->npoints;
579  else end = pa->npoints - 1;
580 
581  /* Starting point */
582  pt = getPoint2d_cp(pa, 0);
583 
584  x = round(pt->x*f)/f;
585  y = round(pt->y*f)/f;
586 
587  if (fabs(x) < OUT_MAX_DOUBLE)
588  sprintf(sx, "%.*f", precision, x);
589  else
590  sprintf(sx, "%g", x);
592 
593  if (fabs(y) < OUT_MAX_DOUBLE)
594  sprintf(sy, "%.*f", precision, fabs(y) ? y * -1 : y);
595  else
596  sprintf(sy, "%g", fabs(y) ? y * -1 : y);
598 
599  ptr += sprintf(ptr,"%s %s l", sx, sy);
600 
601  /* accum */
602  accum_x = x;
603  accum_y = y;
604 
605  /* All the following ones */
606  for (i=1 ; i < end ; i++)
607  {
608  // lpt = pt;
609 
610  pt = getPoint2d_cp(pa, i);
611 
612  x = round(pt->x*f)/f;
613  y = round(pt->y*f)/f;
614  dx = x - accum_x;
615  dy = y - accum_y;
616 
617  if (fabs(dx) < OUT_MAX_DOUBLE)
618  sprintf(sx, "%.*f", precision, dx);
619  else
620  sprintf(sx, "%g", dx);
622 
623  /* SVG Y axis is reversed, an no need to transform 0 into -0 */
624  if (fabs(dy) < OUT_MAX_DOUBLE)
625  sprintf(sy, "%.*f", precision,
626  fabs(dy) ? dy * -1: dy);
627  else
628  sprintf(sy, "%g",
629  fabs(dy) ? dy * -1: dy);
631 
632  accum_x += dx;
633  accum_y += dy;
634 
635  ptr += sprintf(ptr," %s %s", sx, sy);
636  }
637 
638  return (ptr-output);
639 }
640 
641 
645 static size_t
646 pointArray_svg_abs(POINTARRAY *pa, char *output, int close_ring, int precision)
647 {
648  int i, end;
649  char *ptr;
652  POINT2D pt;
653 
654  ptr = output;
655 
656  if (close_ring) end = pa->npoints;
657  else end = pa->npoints - 1;
658 
659  for (i=0 ; i < end ; i++)
660  {
661  getPoint2d_p(pa, i, &pt);
662 
663  if (fabs(pt.x) < OUT_MAX_DOUBLE)
664  sprintf(x, "%.*f", precision, pt.x);
665  else
666  sprintf(x, "%g", pt.x);
668 
669  /* SVG Y axis is reversed, an no need to transform 0 into -0 */
670  if (fabs(pt.y) < OUT_MAX_DOUBLE)
671  sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1:pt.y);
672  else
673  sprintf(y, "%g", fabs(pt.y) ? pt.y * -1:pt.y);
675 
676  if (i == 1) ptr += sprintf(ptr, " L ");
677  else if (i) ptr += sprintf(ptr, " ");
678  ptr += sprintf(ptr,"%s %s", x, y);
679  }
680 
681  return (ptr-output);
682 }
683 
684 
688 static size_t
690 {
691  return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(" "))
692  * 2 * pa->npoints + sizeof(" L ");
693 }
#define LINETYPE
Definition: liblwgeom.h:86
static size_t assvg_line_buf(const LWLINE *line, char *output, int relative, int precision)
Definition: lwout_svg.c:177
static size_t pointArray_svg_rel(POINTARRAY *pa, char *output, int close_ring, int precision)
Definition: lwout_svg.c:560
int npoints
Definition: liblwgeom.h:371
#define OUT_MAX_DOUBLE_PRECISION
void trim_trailing_zeros(char *num)
Definition: lwutil.c:254
#define POLYGONTYPE
Definition: liblwgeom.h:87
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
static char * assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision)
Definition: lwout_svg.c:301
static size_t assvg_polygon_buf(const LWPOLY *poly, char *output, int relative, int precision)
Definition: lwout_svg.c:223
static size_t assvg_multipoint_buf(const LWMPOINT *mpoint, char *output, int relative, int precision)
Definition: lwout_svg.c:284
char * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
Definition: lwout_svg.c:56
POINTARRAY * point
Definition: liblwgeom.h:411
int ngeoms
Definition: liblwgeom.h:481
static size_t assvg_line_size(const LWLINE *line, int relative, int precision)
Line Geometry.
Definition: lwout_svg.c:166
double x
Definition: liblwgeom.h:328
static char * assvg_multiline(const LWMLINE *mline, int relative, int precision)
Definition: lwout_svg.c:353
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
static size_t assvg_multiline_size(const LWMLINE *mline, int relative, int precision)
Multiline Geometry.
Definition: lwout_svg.c:319
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, int n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:373
static char * assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision)
Definition: lwout_svg.c:405
static size_t assvg_polygon_size(const LWPOLY *poly, int relative, int precision)
Polygon Geometry.
Definition: lwout_svg.c:210
LWPOLY ** geoms
Definition: liblwgeom.h:496
LWGEOM ** geoms
Definition: liblwgeom.h:509
static size_t assvg_multiline_buf(const LWMLINE *mline, char *output, int relative, int precision)
Definition: lwout_svg.c:336
static size_t assvg_multipoint_size(const LWMPOINT *mpoint, int relative, int precision)
Multipoint Geometry.
Definition: lwout_svg.c:267
POINTARRAY ** rings
Definition: liblwgeom.h:457
uint8_t precision
Definition: cu_in_twkb.c:25
static size_t assvg_multipolygon_size(const LWMPOLY *mpoly, int relative, int precision)
Definition: lwout_svg.c:371
LWPOINT ** geoms
Definition: liblwgeom.h:470
int nrings
Definition: liblwgeom.h:455
static size_t pointArray_svg_size(POINTARRAY *pa, int precision)
Returns maximum size of rendered pointarray in bytes.
Definition: lwout_svg.c:689
double y
Definition: liblwgeom.h:328
static char * assvg_collection(const LWCOLLECTION *col, int relative, int precision)
Definition: lwout_svg.c:464
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:347
static char * assvg_line(const LWLINE *line, int relative, int precision)
Definition: lwout_svg.c:192
int ngeoms
Definition: liblwgeom.h:494
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
#define OUT_MAX_DOUBLE
LWLINE ** geoms
Definition: liblwgeom.h:483
static size_t assvg_collection_buf(const LWCOLLECTION *col, char *output, int relative, int precision)
Definition: lwout_svg.c:444
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
static size_t assvg_point_buf(const LWPOINT *point, char *output, int circle, int precision)
Definition: lwout_svg.c:119
static char * assvg_point(const LWPOINT *point, int relative, int precision)
Definition: lwout_svg.c:148
uint8_t type
Definition: liblwgeom.h:396
type
Definition: ovdump.py:41
static size_t pointArray_svg_abs(POINTARRAY *pa, char *output, int close_ring, int precision)
Returns maximum size of rendered pointarray in bytes.
Definition: lwout_svg.c:646
static size_t assvg_collection_size(const LWCOLLECTION *col, int relative, int precision)
Collection Geometry.
Definition: lwout_svg.c:423
static size_t assvg_multipolygon_buf(const LWMPOLY *mpoly, char *output, int relative, int precision)
Definition: lwout_svg.c:388
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define OUT_MAX_DIGS_DOUBLE
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:1346
static char * assvg_polygon(const LWPOLY *poly, int relative, int precision)
Definition: lwout_svg.c:249
#define MULTILINETYPE
Definition: liblwgeom.h:89
static size_t assvg_point_size(const LWPOINT *point, int circle, int precision)
Point Geometry.
Definition: lwout_svg.c:107
int ngeoms
Definition: liblwgeom.h:468
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static size_t assvg_geom_size(const LWGEOM *geom, int relative, int precision)
Definition: lwout_svg.c:519
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
POINTARRAY * points
Definition: liblwgeom.h:422
static size_t assvg_geom_buf(const LWGEOM *geom, char *output, int relative, int precision)
Definition: lwout_svg.c:478