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