PostGIS  3.4.0dev-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 #include "stringbuffer.h"
37 
38 
39 static void
40 assvg_geom(stringbuffer_t* sb, const LWGEOM *geom, int relative, int precision);
41 
42 
43 static void
44 pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
45 {
46  int i, end;
47  const POINT2D *pt;
48 
49  double f = 1.0;
50  double dx, dy, x, y, accum_x, accum_y;
51 
52  char sx[OUT_DOUBLE_BUFFER_SIZE];
53  char sy[OUT_DOUBLE_BUFFER_SIZE];
54 
55  if (precision >= 0)
56  {
57  f = pow(10, precision);
58  }
59 
60  end = close_ring ? pa->npoints : pa->npoints - 1;
61 
62  /* Starting point */
63  pt = getPoint2d_cp(pa, start_at_index);
64 
65  x = round(pt->x*f)/f;
66  y = round(pt->y*f)/f;
67 
69  lwprint_double(-y, precision, sy);
70 
71  stringbuffer_aprintf(sb, "%s %s l", sx, sy);
72 
73  /* accum */
74  accum_x = x;
75  accum_y = y;
76 
77  /* All the following ones */
78  for (i = (start_at_index + 1); i < end; i++)
79  {
80  pt = getPoint2d_cp(pa, i);
81 
82  x = round(pt->x*f)/f;
83  y = round(pt->y*f)/f;
84 
85  dx = x - accum_x;
86  dy = y - accum_y;
87 
88  accum_x += dx;
89  accum_y += dy;
90 
91  lwprint_double(dx, precision, sx);
92  lwprint_double(-dy, precision, sy);
93  stringbuffer_aprintf(sb, " %s %s", sx, sy);
94  }
95 }
96 
97 
101 static void
102 pointArray_svg_abs(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
103 {
104  int i, end;
105  const POINT2D* pt;
106  char sx[OUT_DOUBLE_BUFFER_SIZE];
107  char sy[OUT_DOUBLE_BUFFER_SIZE];
108 
109  end = close_ring ? pa->npoints : pa->npoints - 1;
110 
111  for (i = start_at_index; i < end; i++)
112  {
113  pt = getPoint2d_cp(pa, i);
114 
115  if (i == 1)
116  {
117  if (start_at_index > 0 ){
118  stringbuffer_append(sb, "L ");
119  }
120  else {
121  stringbuffer_append(sb, " L ");
122  }
123  }
124  else if (i) stringbuffer_append(sb, " ");
125 
126  lwprint_double(pt->x, precision, sx);
127  lwprint_double(-(pt->y), precision, sy);
128 
129  stringbuffer_aprintf(sb, "%s %s", sx, sy);
130  }
131 }
132 
133 
134 static void
135 assvg_point(stringbuffer_t* sb, const LWPOINT *point, int circle, int precision)
136 {
137  char sx[OUT_DOUBLE_BUFFER_SIZE];
138  char sy[OUT_DOUBLE_BUFFER_SIZE];
139  if ( !lwgeom_is_empty((LWGEOM*)point) ){
140  const POINT2D* pt = getPoint2d_cp(point->point, 0);
141  lwprint_double(pt->x, precision, sx);
142  lwprint_double(-(pt->y), precision, sy);
143 
145  circle ? "x=\"%s\" y=\"%s\"" : "cx=\"%s\" cy=\"%s\"",
146  sx, sy);
147  }
148 }
149 
150 
151 static void
152 assvg_line(stringbuffer_t* sb, const LWLINE *line, int relative, int precision)
153 {
154  /* Start path with SVG MoveTo */
155  stringbuffer_append(sb, "M ");
156  if (relative)
157  pointArray_svg_rel(sb, line->points, 1, precision, 0);
158  else
159  pointArray_svg_abs(sb, line->points, 1, precision, 0);
160 }
161 
162 static void pointArray_svg_arc(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int relative, int precision)
163 {
164  uint32_t i; //, end;
165  char sx[OUT_DOUBLE_BUFFER_SIZE];
166  char sy[OUT_DOUBLE_BUFFER_SIZE];
167 
168  LWDEBUG(2, "pointArray_svg_arc called.");
169 
170  for (i = 2; i < pa->npoints; i+=2)
171  {
172  LWDEBUGF(3, "assvg_circstring: arc ending at point %d", i);
173  int largeArcFlag, sweepFlag, clockwise;
174  int is_circle = LW_FALSE;
175  double a1, a3;
176  double radius; /* Arc radius */
177  double total_angle;
178  POINT2D center;
179  const POINT2D *t1;
180  const POINT2D *t2;
181  const POINT2D *t3;
182  int p2_side = 0;
183  t1 = getPoint2d_cp(pa, i - 2);
184  t2 = getPoint2d_cp(pa, i - 1);
185  t3 = getPoint2d_cp(pa, i);
186  radius = lw_arc_center(t1, t2, t3, &center);
187  if ( t1->x == t3->x && t1->y == t3->y ){
188  is_circle = LW_TRUE;
189  }
190  p2_side = lw_segment_side(t1, t3, t2);
191  if ( p2_side == -1 )
192  clockwise = LW_TRUE;
193  else
194  clockwise = LW_FALSE;
195  /* Angles of each point that defines the arc section */
196  a1 = atan2(t1->y - center.y, t1->x - center.x)*180/M_PI;
197  //a2 = atan2(t2->y - center.y, t2->x - center.x)*180/M_PI;
198  a3 = atan2(t3->y - center.y, t3->x - center.x)*180/M_PI;
199 
200  LWDEBUGF(2, " center is POINT(%.15g %.15g) - radius:%g", center.x, center.y, radius);
201 
202  total_angle = clockwise ? a1 - a3 : a3 - a1;
203  if (total_angle < 0 ){
204  total_angle += 360;
205  }
206 
207  //stringbuffer_aprintf(sb, "angles (a1 a2 a3): %g %g %g is_circle: %d, total_angle: %g, t1.x: %f, t3.x: %f, t1.y: %f, t3.y: %f ", a1, a2, a3, is_circle, total_angle, t1->x, t3->x, t1->y, t3->y);
208 
210  largeArcFlag = (total_angle <= 180)? 0 : 1;
211  /* The side of the t1/t3 line that t2 falls on dictates the sweep
212  direction from t1 to t3. */
213  sweepFlag = (p2_side == -1) ? 1 : 0;
214  if ( (i == 2) && !is_circle ){
216  lwprint_double(t1->x, precision, sx);
217  lwprint_double(-(t1->y), precision, sy);
218  stringbuffer_aprintf(sb, "%s %s", sx, sy);
219  }
221  if ( (i == 2) && is_circle){
223  lwprint_double(center.x, precision, sx);
224  lwprint_double(-(center.y), precision, sy);
225  stringbuffer_aprintf(sb, "%s %s", sx, sy);
226  }
227  lwprint_double(radius, precision, sx);
228  lwprint_double(0, precision, sy);
230  if (is_circle){
231  //https://stackoverflow.com/questions/5737975/circle-drawing-with-svgs-arc-path
232  lwprint_double(radius*2, precision, sy);
233  stringbuffer_aprintf(sb, " m %s 0 a %s %s 0 1 0 -%s 0", sx, sx, sx, sy);
234  stringbuffer_aprintf(sb, " a %s %s 0 1 0 %s 0", sx, sx, sy);
235  }
236  else {
237  /* Arc radius radius 0 arcflag swipeflag */
238  if (relative){
239  stringbuffer_aprintf(sb, " a %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
240  }
241  else {
242  stringbuffer_aprintf(sb, " A %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
243  }
244  lwprint_double(t3->x, precision, sx);
245  lwprint_double(-(t3->y), precision, sy);
246  /* end point */
247  stringbuffer_aprintf(sb, "%s %s", sx, sy);
248  }
249  }
250 }
251 
252 static void
253 assvg_circstring(stringbuffer_t* sb, const LWCIRCSTRING *icurve, int relative, int precision)
254 {
255  /* Start path with SVG MoveTo */
256  stringbuffer_append(sb, "M ");
257  pointArray_svg_arc(sb, icurve->points, 1, relative, precision);
258 }
259 
260 static void
261 assvg_compound(stringbuffer_t* sb, const LWCOMPOUND *icompound, int relative, int precision)
262 {
263  uint32_t i;
264  LWGEOM *geom;
265  LWCIRCSTRING *tmpc = NULL;
266  LWLINE *tmpl = NULL;
267  /* Start path with SVG MoveTo */
268  stringbuffer_append(sb, "M ");
269 
270  for (i = 0; i < icompound->ngeoms; i++)
271  {
272  if (i) stringbuffer_append(sb, " "); /* SVG whitespace Separator */
273  geom = icompound->geoms[i];
274 
275  switch (geom->type)
276  {
277  case CIRCSTRINGTYPE:
278  tmpc = (LWCIRCSTRING *)geom;
279  pointArray_svg_arc(sb, tmpc->points, 1, relative, precision);
280  break;
281 
282  case LINETYPE:
283  tmpl = (LWLINE *)geom;
284 
285  if (i){
289  if (relative)
290  pointArray_svg_rel(sb, tmpl->points, 1, precision, 1);
291  else
292  pointArray_svg_abs(sb, tmpl->points, 1, precision, 1);
293  }
294  else {
295  if (relative)
296  pointArray_svg_rel(sb, tmpl->points, 1, precision, 0);
297  else
298  pointArray_svg_abs(sb, tmpl->points, 1, precision, 0);
299  }
300  break;
301 
302  default:
303  break;
304  }
305  }
306 }
307 
308 static void
309 assvg_polygon(stringbuffer_t* sb, const LWPOLY *poly, int relative, int precision)
310 {
311  uint32_t i;
312 
313  for (i = 0; i<poly->nrings; i++)
314  {
315  if (i) stringbuffer_append(sb, " "); /* Space beetween each ring */
316  stringbuffer_append(sb, "M "); /* Start path with SVG MoveTo */
317 
318  if (relative)
319  {
320  pointArray_svg_rel(sb, poly->rings[i], 0, precision, 0);
321  stringbuffer_append(sb, " z"); /* SVG closepath */
322  }
323  else
324  {
325  pointArray_svg_abs(sb, poly->rings[i], 0, precision, 0);
326  stringbuffer_append(sb, " Z"); /* SVG closepath */
327  }
328  }
329 }
330 
331 static void
332 assvg_multipoint(stringbuffer_t* sb, const LWMPOINT *mpoint, int relative, int precision)
333 {
334  const LWPOINT *point;
335  uint32_t i;
336 
337  for (i = 0; i<mpoint->ngeoms; i++)
338  {
339  if (i) stringbuffer_append(sb, ","); /* Arbitrary comma separator */
340  point = mpoint->geoms[i];
341  assvg_point(sb, point, relative, precision);
342  }
343 }
344 
345 
346 static void
347 assvg_multiline(stringbuffer_t* sb, const LWMLINE *mline, int relative, int precision)
348 {
349  const LWLINE *line;
350  uint32_t i;
351 
352  for (i = 0; i<mline->ngeoms; i++)
353  {
354  if (i) stringbuffer_append(sb, " "); /* SVG whitespace Separator */
355  line = mline->geoms[i];
356  assvg_line(sb, line, relative, precision);
357  }
358 }
359 
360 static void
361 assvg_multipolygon(stringbuffer_t* sb, const LWMPOLY *mpoly, int relative, int precision)
362 {
363  const LWPOLY *poly;
364  uint32_t i;
365 
366  for (i = 0; i<mpoly->ngeoms; i++)
367  {
368  if (i) stringbuffer_append(sb, " "); /* SVG whitespace Separator */
369  poly = mpoly->geoms[i];
370  assvg_polygon(sb, poly, relative, precision);
371  }
372 }
373 
374 static void
375 assvg_multicurve(stringbuffer_t* sb, const LWMCURVE *mcurve, int relative, int precision)
376 {
377  uint32_t i;
378  LWGEOM *geom;
379  const LWCIRCSTRING *tmpc = NULL;
380  const LWLINE *tmpl = NULL;
381 
382  for (i = 0; i < mcurve->ngeoms; i++)
383  {
384  if (i) stringbuffer_append(sb, " "); /* SVG whitespace Separator */
385  geom = mcurve->geoms[i];
386 
387  switch (geom->type)
388  {
389  case CIRCSTRINGTYPE:
390  tmpc = (LWCIRCSTRING *)geom;
391  assvg_circstring(sb, tmpc, relative, precision);
392  break;
393 
394  case LINETYPE:
395  tmpl = (LWLINE *)geom;
396  assvg_line(sb, tmpl, relative, precision);
397  break;
398 
399  default:
400  break;
401  }
402  }
403 }
404 
405 static void
406 assvg_curvepoly(stringbuffer_t* sb, const LWCURVEPOLY *curvepoly, int relative, int precision)
407 {
408  uint32_t i;
409  LWGEOM *tmp;
410 
411  for (i = 0; i < curvepoly->nrings; i++)
412  {
413  if (i) stringbuffer_append(sb, " "); /* Space between each ring */
414  tmp = curvepoly->rings[i];
415  switch (tmp->type)
416  {
417  case CIRCSTRINGTYPE:
418  assvg_circstring(sb, (LWCIRCSTRING *)tmp, relative, precision);
419  break;
420 
421  case LINETYPE:
422  assvg_line(sb, (LWLINE *)tmp, relative, precision);
423  break;
424 
425  case COMPOUNDTYPE:
426  assvg_compound(sb, (LWCOMPOUND *)tmp, relative, precision);
427  break;
428 
429  default:
430  break;
431  }
432  if (relative)
433  {
434  stringbuffer_append(sb, " z"); /* SVG closepath */
435  }
436  else
437  {
438  stringbuffer_append(sb, " Z"); /* SVG closepath */
439  }
440  }
441 }
442 
443 static void
444 assvg_multisurface(stringbuffer_t* sb, const LWMSURFACE *msurface, int relative, int precision)
445 {
446  LWGEOM *geom;
447  uint32_t i;
448  const LWPOLY *poly;
449  const LWCURVEPOLY *curvepoly;
450 
451  for (i = 0; i < msurface->ngeoms; i++)
452  {
453  if (i) stringbuffer_append(sb, " "); /* SVG whitespace Separator */
454  geom = msurface->geoms[i];
455  switch (geom->type)
456  {
457  case CURVEPOLYTYPE:
458  curvepoly = (LWCURVEPOLY *) geom;
459  assvg_curvepoly(sb, curvepoly, relative, precision);
460  break;
461  case POLYGONTYPE:
462  poly = (LWPOLY *) geom;
463  assvg_polygon(sb, poly, relative, precision);
464  break;
465  default:
466  break;
467  }
468  }
469 }
470 
471 static void
472 assvg_collection(stringbuffer_t* sb, const LWCOLLECTION *col, int relative, int precision)
473 {
474  uint32_t i; uint32_t j = 0;
475  const LWGEOM *subgeom;
476 
477  /* EMPTY GEOMETRYCOLLECTION */
478  if (col->ngeoms == 0) return;
479 
480  for (i = 0; i<col->ngeoms; i++)
481  {
482  subgeom = col->geoms[i];
483  if (!lwgeom_is_empty(subgeom) ){
487  if (j) stringbuffer_append(sb, ";");
488  j++;
489  assvg_geom(sb, subgeom, relative, precision);
490  }
491  }
492 
493 }
494 
495 
496 
497 static void
498 assvg_geom(stringbuffer_t* sb, const LWGEOM *geom, int relative, int precision)
499 {
500  int type = geom->type;
501 
502  switch (type)
503  {
504  case POINTTYPE:
505  assvg_point(sb, (LWPOINT*)geom, relative, precision);
506  break;
507 
508  case LINETYPE:
509  assvg_line(sb, (LWLINE*)geom, relative, precision);
510  break;
511 
512  case POLYGONTYPE:
513  assvg_polygon(sb, (LWPOLY*)geom, relative, precision);
514  break;
515 
516  case MULTIPOINTTYPE:
517  assvg_multipoint(sb, (LWMPOINT*)geom, relative, precision);
518  break;
519 
520  case MULTILINETYPE:
521  assvg_multiline(sb, (LWMLINE*)geom, relative, precision);
522  break;
523 
524  case MULTIPOLYGONTYPE:
525  assvg_multipolygon(sb, (LWMPOLY*)geom, relative, precision);
526  break;
527 
528  case CIRCSTRINGTYPE:
529  assvg_circstring(sb, (LWCIRCSTRING*)geom, relative, precision);
530  break;
531 
532  case COMPOUNDTYPE:
533  assvg_compound(sb, (LWCOMPOUND*)geom, relative, precision);
534  break;
535 
536  case CURVEPOLYTYPE:
537  assvg_curvepoly(sb, (LWCURVEPOLY*)geom, relative, precision);
538  break;
539 
540  case MULTICURVETYPE:
541  assvg_multicurve(sb, (LWMCURVE*)geom, relative, precision);
542  break;
543 
544  case MULTISURFACETYPE:
545  assvg_multisurface(sb, (LWMSURFACE*)geom, relative, precision);
546  break;
547 
548  default:
549  lwerror("assvg_geom_buf: '%s' geometry type not supported.",
550  lwtype_name(type));
551  }
552 
553 }
554 
558 lwvarlena_t *
559 lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
560 {
561  stringbuffer_t sb;
562  int type = geom->type;
563 
564  /* Empty varlena for empties */
565  if(lwgeom_is_empty(geom))
566  {
569  return v;
570  }
571 
573 
574  switch (type)
575  {
576  case POINTTYPE:
577  assvg_point(&sb, (LWPOINT*)geom, relative, precision);
578  break;
579  case LINETYPE:
580  assvg_line(&sb, (LWLINE*)geom, relative, precision);
581  break;
582  case POLYGONTYPE:
583  assvg_polygon(&sb, (LWPOLY*)geom, relative, precision);
584  break;
585  case CIRCSTRINGTYPE:
586  assvg_circstring(&sb, (LWCIRCSTRING*)geom, relative, precision);
587  break;
588  case COMPOUNDTYPE:
589  assvg_compound(&sb, (LWCOMPOUND*)geom, relative, precision);
590  break;
591  case CURVEPOLYTYPE:
592  assvg_curvepoly(&sb, (LWCURVEPOLY*)geom, relative, precision);
593  break;
594  case MULTIPOINTTYPE:
595  assvg_multipoint(&sb, (LWMPOINT*)geom, relative, precision);
596  break;
597  case MULTILINETYPE:
598  assvg_multiline(&sb, (LWMLINE*)geom, relative, precision);
599  break;
600  case MULTICURVETYPE:
601  assvg_multicurve(&sb, (LWMCURVE*)geom, relative, precision);
602  break;
603  case MULTIPOLYGONTYPE:
604  assvg_multipolygon(&sb, (LWMPOLY*)geom, relative, precision);
605  break;
606  case MULTISURFACETYPE:
607  assvg_multisurface(&sb, (LWMSURFACE*)geom, relative, precision);
608  break;
609  case COLLECTIONTYPE:
610  assvg_collection(&sb, (LWCOLLECTION*)geom, relative, precision);
611  break;
612 
613  default:
614  lwerror("lwgeom_to_svg: '%s' geometry type not supported", lwtype_name(type));
615  }
616 
617  return stringbuffer_getvarlena(&sb);
618 }
619 
static uint8_t precision
Definition: cu_in_twkb.c:25
#define LW_FALSE
Definition: liblwgeom.h:94
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
#define COMPOUNDTYPE
Definition: liblwgeom.h:110
#define LWVARHDRSZ
Definition: liblwgeom.h:311
#define CURVEPOLYTYPE
Definition: liblwgeom.h:111
#define MULTILINETYPE
Definition: liblwgeom.h:106
#define MULTISURFACETYPE
Definition: liblwgeom.h:113
#define LINETYPE
Definition: liblwgeom.h:103
#define MULTIPOINTTYPE
Definition: liblwgeom.h:105
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
#define POLYGONTYPE
Definition: liblwgeom.h:104
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:109
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
#define LWSIZE_SET(varsize, len)
Definition: liblwgeom.h:325
#define MULTICURVETYPE
Definition: liblwgeom.h:112
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result)
Determines the center of the circle defined by the three given points.
Definition: lwalgorithm.c:226
#define OUT_DOUBLE_BUFFER_SIZE
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:62
int lwprint_double(double d, int maxdd, char *buf)
Definition: lwprint.c:457
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
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:203
static void assvg_compound(stringbuffer_t *sb, const LWCOMPOUND *icompound, int relative, int precision)
Definition: lwout_svg.c:261
static void assvg_multipoint(stringbuffer_t *sb, const LWMPOINT *mpoint, int relative, int precision)
Definition: lwout_svg.c:332
lwvarlena_t * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
Definition: lwout_svg.c:559
static void pointArray_svg_rel(stringbuffer_t *sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
Definition: lwout_svg.c:44
static void assvg_curvepoly(stringbuffer_t *sb, const LWCURVEPOLY *curvepoly, int relative, int precision)
Definition: lwout_svg.c:406
static void assvg_multiline(stringbuffer_t *sb, const LWMLINE *mline, int relative, int precision)
Definition: lwout_svg.c:347
static void assvg_multipolygon(stringbuffer_t *sb, const LWMPOLY *mpoly, int relative, int precision)
Definition: lwout_svg.c:361
static void pointArray_svg_arc(stringbuffer_t *sb, const POINTARRAY *pa, int close_ring, int relative, int precision)
Definition: lwout_svg.c:162
static void assvg_line(stringbuffer_t *sb, const LWLINE *line, int relative, int precision)
Definition: lwout_svg.c:152
static void assvg_polygon(stringbuffer_t *sb, const LWPOLY *poly, int relative, int precision)
Definition: lwout_svg.c:309
static void assvg_circstring(stringbuffer_t *sb, const LWCIRCSTRING *icurve, int relative, int precision)
Definition: lwout_svg.c:253
static void assvg_multicurve(stringbuffer_t *sb, const LWMCURVE *mcurve, int relative, int precision)
Definition: lwout_svg.c:375
static void assvg_point(stringbuffer_t *sb, const LWPOINT *point, int circle, int precision)
Definition: lwout_svg.c:135
static void pointArray_svg_abs(stringbuffer_t *sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
Returns maximum size of rendered pointarray in bytes.
Definition: lwout_svg.c:102
static void assvg_geom(stringbuffer_t *sb, const LWGEOM *geom, int relative, int precision)
Definition: lwout_svg.c:498
static void assvg_multisurface(stringbuffer_t *sb, const LWMSURFACE *msurface, int relative, int precision)
Definition: lwout_svg.c:444
static void assvg_collection(stringbuffer_t *sb, const LWCOLLECTION *col, int relative, int precision)
Definition: lwout_svg.c:472
type
Definition: ovdump.py:42
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:247
lwvarlena_t * stringbuffer_getvarlena(stringbuffer_t *s)
Definition: stringbuffer.c:143
void stringbuffer_init_varlena(stringbuffer_t *s)
Definition: stringbuffer.c:60
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
Definition: stringbuffer.h:105
POINTARRAY * points
Definition: liblwgeom.h:507
uint32_t ngeoms
Definition: liblwgeom.h:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
uint32_t ngeoms
Definition: liblwgeom.h:594
LWGEOM ** geoms
Definition: liblwgeom.h:589
LWGEOM ** rings
Definition: liblwgeom.h:603
uint32_t nrings
Definition: liblwgeom.h:608
uint8_t type
Definition: liblwgeom.h:462
POINTARRAY * points
Definition: liblwgeom.h:483
LWGEOM ** geoms
Definition: liblwgeom.h:617
uint32_t ngeoms
Definition: liblwgeom.h:622
LWLINE ** geoms
Definition: liblwgeom.h:547
uint32_t ngeoms
Definition: liblwgeom.h:552
uint32_t ngeoms
Definition: liblwgeom.h:538
LWPOINT ** geoms
Definition: liblwgeom.h:533
uint32_t ngeoms
Definition: liblwgeom.h:566
LWPOLY ** geoms
Definition: liblwgeom.h:561
uint32_t ngeoms
Definition: liblwgeom.h:636
LWGEOM ** geoms
Definition: liblwgeom.h:631
POINTARRAY * point
Definition: liblwgeom.h:471
POINTARRAY ** rings
Definition: liblwgeom.h:519
uint32_t nrings
Definition: liblwgeom.h:524
double y
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:390
uint32_t npoints
Definition: liblwgeom.h:427
uint32_t size
Definition: liblwgeom.h:307