PostGIS  3.4.0dev-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  * 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 2006 Corporacion Autonoma Regional de Santander
22  * Copyright 2010 Paul Ramsey <pramsey@cleverelephant.ca>
23  *
24  **********************************************************************/
25 
26 
27 #include "liblwgeom_internal.h"
28 #include "stringbuffer.h"
29 
30 static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb);
31 static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb);
32 static int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb);
33 static int lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb);
34 static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb);
35 static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb);
36 static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb);
37 
38 /*
39 * KML 2.2.0
40 */
41 
42 /* takes a GEOMETRY and returns a KML representation */
44 lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
45 {
46  stringbuffer_t *sb;
47  int rv;
48 
49  /* Can't do anything with empty */
50  if( lwgeom_is_empty(geom) )
51  return NULL;
52 
53  sb = stringbuffer_create();
54  rv = lwgeom_to_kml2_sb(geom, precision, prefix, sb);
55 
56  if ( rv == LW_FAILURE )
57  {
59  return NULL;
60  }
61 
64 
65  return v;
66 }
67 
68 static int
69 lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
70 {
71  switch (geom->type)
72  {
73  case POINTTYPE:
74  return lwpoint_to_kml2_sb((LWPOINT*)geom, precision, prefix, sb);
75 
76  case LINETYPE:
77  return lwline_to_kml2_sb((LWLINE*)geom, precision, prefix, sb);
78 
79  case TRIANGLETYPE:
80  return lwtriangle_to_kml2_sb((LWTRIANGLE *)geom, precision, prefix, sb);
81 
82  case POLYGONTYPE:
83  return lwpoly_to_kml2_sb((LWPOLY*)geom, precision, prefix, sb);
84 
85  case MULTIPOINTTYPE:
86  case MULTILINETYPE:
87  case MULTIPOLYGONTYPE:
88  case TINTYPE:
89  return lwcollection_to_kml2_sb((LWCOLLECTION*)geom, precision, prefix, sb);
90 
91  default:
92  lwerror("lwgeom_to_kml2: '%s' geometry type not supported", lwtype_name(geom->type));
93  return LW_FAILURE;
94  }
95 }
96 
97 static int
99 {
100  uint32_t i, j;
101  uint32_t dims = FLAGS_GET_Z(pa->flags) ? 3 : 2;
102  POINT4D pt;
103  double *d;
104 
105  for ( i = 0; i < pa->npoints; i++ )
106  {
107  getPoint4d_p(pa, i, &pt);
108  d = (double*)(&pt);
109  if ( i ) stringbuffer_append_len(sb," ",1);
110  for (j = 0; j < dims; j++)
111  {
112  if ( j ) stringbuffer_append_len(sb,",",1);
114  }
115  }
116  return LW_SUCCESS;
117 }
118 
119 
120 static int
121 lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
122 {
123  /* Open point */
124  if ( stringbuffer_aprintf(sb, "<%sPoint><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
125  /* Coordinate array */
126  if ( ptarray_to_kml2_sb(point->point, precision, sb) == LW_FAILURE ) return LW_FAILURE;
127  /* Close point */
128  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sPoint>", prefix, prefix) < 0 ) return LW_FAILURE;
129  return LW_SUCCESS;
130 }
131 
132 static int
133 lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
134 {
135  /* Open linestring */
136  if ( stringbuffer_aprintf(sb, "<%sLineString><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
137  /* Coordinate array */
138  if ( ptarray_to_kml2_sb(line->points, precision, sb) == LW_FAILURE ) return LW_FAILURE;
139  /* Close linestring */
140  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sLineString>", prefix, prefix) < 0 ) return LW_FAILURE;
141 
142  return LW_SUCCESS;
143 }
144 
145 static int
146 lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb)
147 {
148  /* Open polygon */
150  sb, "<%sPolygon><%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix, prefix) < 0)
151  return LW_FAILURE;
152  /* Coordinate array */
153  if (ptarray_to_kml2_sb(tri->points, precision, sb) == LW_FAILURE)
154  return LW_FAILURE;
155  /* Close polygon */
157  sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs></%sPolygon>", prefix, prefix, prefix, prefix) <
158  0)
159  return LW_FAILURE;
160 
161  return LW_SUCCESS;
162 }
163 
164 static int
165 lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
166 {
167  uint32_t i;
168  int rv;
169 
170  /* Open polygon */
171  if ( stringbuffer_aprintf(sb, "<%sPolygon>", prefix) < 0 ) return LW_FAILURE;
172  for ( i = 0; i < poly->nrings; i++ )
173  {
174  /* Inner or outer ring opening tags */
175  if( i )
176  rv = stringbuffer_aprintf(sb, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
177  else
178  rv = stringbuffer_aprintf(sb, "<%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
179  if ( rv < 0 ) return LW_FAILURE;
180 
181  /* Coordinate array */
182  if ( ptarray_to_kml2_sb(poly->rings[i], precision, sb) == LW_FAILURE ) return LW_FAILURE;
183 
184  /* Inner or outer ring closing tags */
185  if( i )
186  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
187  else
188  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
189  if ( rv < 0 ) return LW_FAILURE;
190  }
191  /* Close polygon */
192  if ( stringbuffer_aprintf(sb, "</%sPolygon>", prefix) < 0 ) return LW_FAILURE;
193 
194  return LW_SUCCESS;
195 }
196 
197 static int
198 lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
199 {
200  uint32_t i;
201  int rv;
202 
203  /* Open geometry */
204  if ( stringbuffer_aprintf(sb, "<%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
205  for ( i = 0; i < col->ngeoms; i++ )
206  {
207  rv = lwgeom_to_kml2_sb(col->geoms[i], precision, prefix, sb);
208  if ( rv == LW_FAILURE ) return LW_FAILURE;
209  }
210  /* Close geometry */
211  if ( stringbuffer_aprintf(sb, "</%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
212 
213  return LW_SUCCESS;
214 }
static uint8_t precision
Definition: cu_in_twkb.c:25
#define LW_FAILURE
Definition: liblwgeom.h:96
#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
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition: liblwgeom.h:165
#define TINTYPE
Definition: liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
#define POLYGONTYPE
Definition: liblwgeom.h:104
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition: lwgeom_api.c:125
#define TRIANGLETYPE
Definition: liblwgeom.h:115
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
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
lwvarlena_t * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
Definition: lwout_kml.c:44
static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:69
static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:198
static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:165
static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:121
static int lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:146
static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb)
Definition: lwout_kml.c:98
static int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:133
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_getvarlenacopy(stringbuffer_t *s)
Definition: stringbuffer.c:151
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:33
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:85
static void stringbuffer_append_double(stringbuffer_t *s, double d, int precision)
Definition: stringbuffer.h:112
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.
Definition: stringbuffer.h:93
uint32_t ngeoms
Definition: liblwgeom.h:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
uint8_t type
Definition: liblwgeom.h:462
POINTARRAY * points
Definition: liblwgeom.h:483
POINTARRAY * point
Definition: liblwgeom.h:471
uint8_t type
Definition: liblwgeom.h:474
POINTARRAY ** rings
Definition: liblwgeom.h:519
uint32_t nrings
Definition: liblwgeom.h:524
POINTARRAY * points
Definition: liblwgeom.h:495
lwflags_t flags
Definition: liblwgeom.h:431
uint32_t npoints
Definition: liblwgeom.h:427