PostGIS  2.2.8dev-r@@SVN_REVISION@@
lwout_kml.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright 2006 Corporacion Autonoma Regional de Santander
7  * Eduin Carrillo <yecarrillo@cas.gov.co>
8  * Copyright 2010 Paul Ramsey <pramsey@cleverelephant.ca>
9  *
10  * This is free software; you can redistribute and/or modify it under
11  * the terms of hte GNU General Public Licence. See the COPYING file.
12  *
13  **********************************************************************/
14 
15 #include "liblwgeom_internal.h"
16 #include "stringbuffer.h"
17 
18 static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb);
19 static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb);
20 static int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb);
21 static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb);
22 static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb);
23 static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb);
24 
25 /*
26 * KML 2.2.0
27 */
28 
29 /* takes a GEOMETRY and returns a KML representation */
30 char*
31 lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
32 {
33  stringbuffer_t *sb;
34  int rv;
35  char *kml;
36 
37  /* Can't do anything with empty */
38  if( lwgeom_is_empty(geom) )
39  return NULL;
40 
41  sb = stringbuffer_create();
42  rv = lwgeom_to_kml2_sb(geom, precision, prefix, sb);
43 
44  if ( rv == LW_FAILURE )
45  {
47  return NULL;
48  }
49 
52 
53  return kml;
54 }
55 
56 static int
57 lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
58 {
59  switch (geom->type)
60  {
61  case POINTTYPE:
62  return lwpoint_to_kml2_sb((LWPOINT*)geom, precision, prefix, sb);
63 
64  case LINETYPE:
65  return lwline_to_kml2_sb((LWLINE*)geom, precision, prefix, sb);
66 
67  case POLYGONTYPE:
68  return lwpoly_to_kml2_sb((LWPOLY*)geom, precision, prefix, sb);
69 
70  case MULTIPOINTTYPE:
71  case MULTILINETYPE:
72  case MULTIPOLYGONTYPE:
73  return lwcollection_to_kml2_sb((LWCOLLECTION*)geom, precision, prefix, sb);
74 
75  default:
76  lwerror("lwgeom_to_kml2: '%s' geometry type not supported", lwtype_name(geom->type));
77  return LW_FAILURE;
78  }
79 }
80 
81 static int
83 {
84  int i, j;
85  int dims = FLAGS_GET_Z(pa->flags) ? 3 : 2;
86  POINT4D pt;
87  double *d;
88 
89  for ( i = 0; i < pa->npoints; i++ )
90  {
91  getPoint4d_p(pa, i, &pt);
92  d = (double*)(&pt);
93  if ( i ) stringbuffer_append(sb," ");
94  for (j = 0; j < dims; j++)
95  {
96  if ( j ) stringbuffer_append(sb,",");
97  if( fabs(d[j]) < OUT_MAX_DOUBLE )
98  {
99  if ( stringbuffer_aprintf(sb, "%.*f", precision, d[j]) < 0 ) return LW_FAILURE;
100  }
101  else
102  {
103  if ( stringbuffer_aprintf(sb, "%g", d[j]) < 0 ) return LW_FAILURE;
104  }
106  }
107  }
108  return LW_SUCCESS;
109 }
110 
111 
112 static int
113 lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
114 {
115  /* Open point */
116  if ( stringbuffer_aprintf(sb, "<%sPoint><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
117  /* Coordinate array */
118  if ( ptarray_to_kml2_sb(point->point, precision, sb) == LW_FAILURE ) return LW_FAILURE;
119  /* Close point */
120  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sPoint>", prefix, prefix) < 0 ) return LW_FAILURE;
121  return LW_SUCCESS;
122 }
123 
124 static int
125 lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
126 {
127  /* Open linestring */
128  if ( stringbuffer_aprintf(sb, "<%sLineString><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
129  /* Coordinate array */
130  if ( ptarray_to_kml2_sb(line->points, precision, sb) == LW_FAILURE ) return LW_FAILURE;
131  /* Close linestring */
132  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sLineString>", prefix, prefix) < 0 ) return LW_FAILURE;
133 
134  return LW_SUCCESS;
135 }
136 
137 static int
138 lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
139 {
140  int i, rv;
141 
142  /* Open polygon */
143  if ( stringbuffer_aprintf(sb, "<%sPolygon>", prefix) < 0 ) return LW_FAILURE;
144  for ( i = 0; i < poly->nrings; i++ )
145  {
146  /* Inner or outer ring opening tags */
147  if( i )
148  rv = stringbuffer_aprintf(sb, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
149  else
150  rv = stringbuffer_aprintf(sb, "<%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
151  if ( rv < 0 ) return LW_FAILURE;
152 
153  /* Coordinate array */
154  if ( ptarray_to_kml2_sb(poly->rings[i], precision, sb) == LW_FAILURE ) return LW_FAILURE;
155 
156  /* Inner or outer ring closing tags */
157  if( i )
158  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
159  else
160  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
161  if ( rv < 0 ) return LW_FAILURE;
162  }
163  /* Close polygon */
164  if ( stringbuffer_aprintf(sb, "</%sPolygon>", prefix) < 0 ) return LW_FAILURE;
165 
166  return LW_SUCCESS;
167 }
168 
169 static int
170 lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
171 {
172  int i, rv;
173 
174  /* Open geometry */
175  if ( stringbuffer_aprintf(sb, "<%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
176  for ( i = 0; i < col->ngeoms; i++ )
177  {
178  rv = lwgeom_to_kml2_sb(col->geoms[i], precision, prefix, sb);
179  if ( rv == LW_FAILURE ) return LW_FAILURE;
180  }
181  /* Close geometry */
182  if ( stringbuffer_aprintf(sb, "</%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
183 
184  return LW_SUCCESS;
185 }
#define LINETYPE
Definition: liblwgeom.h:71
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
Definition: lwout_kml.c:31
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:46
int npoints
Definition: liblwgeom.h:355
uint8_t type
Definition: liblwgeom.h:487
#define POLYGONTYPE
Definition: liblwgeom.h:72
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string...
Definition: stringbuffer.c:153
#define MULTIPOINTTYPE
Definition: liblwgeom.h:73
#define LW_SUCCESS
Definition: liblwgeom.h:65
POINTARRAY * point
Definition: liblwgeom.h:395
#define LW_FAILURE
Definition: liblwgeom.h:64
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:246
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:188
uint8_t flags
Definition: liblwgeom.h:353
LWGEOM ** geoms
Definition: liblwgeom.h:493
POINTARRAY ** rings
Definition: liblwgeom.h:441
uint8_t precision
Definition: cu_in_twkb.c:25
static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:57
int nrings
Definition: liblwgeom.h:439
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:124
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:75
#define OUT_MAX_DOUBLE
void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
Definition: stringbuffer.c:127
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:71
static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:170
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:70
uint8_t type
Definition: liblwgeom.h:380
static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb)
Definition: lwout_kml.c:82
static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:138
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 int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:125
#define MULTILINETYPE
Definition: liblwgeom.h:74
int stringbuffer_trim_trailing_zeroes(stringbuffer_t *s)
Trims zeroes off the end of the last number in the stringbuffer.
Definition: stringbuffer.c:297
static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:113
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:231
POINTARRAY * points
Definition: liblwgeom.h:406