PostGIS  3.0.6dev-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 */
43 char*
44 lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
45 {
46  stringbuffer_t *sb;
47  int rv;
48  char *kml;
49 
50  /* Can't do anything with empty */
51  if( lwgeom_is_empty(geom) )
52  return NULL;
53 
54  sb = stringbuffer_create();
55  rv = lwgeom_to_kml2_sb(geom, precision, prefix, sb);
56 
57  if ( rv == LW_FAILURE )
58  {
60  return NULL;
61  }
62 
65 
66  return kml;
67 }
68 
69 static int
70 lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
71 {
72  switch (geom->type)
73  {
74  case POINTTYPE:
75  return lwpoint_to_kml2_sb((LWPOINT*)geom, precision, prefix, sb);
76 
77  case LINETYPE:
78  return lwline_to_kml2_sb((LWLINE*)geom, precision, prefix, sb);
79 
80  case TRIANGLETYPE:
81  return lwtriangle_to_kml2_sb((LWTRIANGLE *)geom, precision, prefix, sb);
82 
83  case POLYGONTYPE:
84  return lwpoly_to_kml2_sb((LWPOLY*)geom, precision, prefix, sb);
85 
86  case MULTIPOINTTYPE:
87  case MULTILINETYPE:
88  case MULTIPOLYGONTYPE:
89  case TINTYPE:
90  return lwcollection_to_kml2_sb((LWCOLLECTION*)geom, precision, prefix, sb);
91 
92  default:
93  lwerror("lwgeom_to_kml2: '%s' geometry type not supported", lwtype_name(geom->type));
94  return LW_FAILURE;
95  }
96 }
97 
98 static int
100 {
101  uint32_t i, j;
102  uint32_t dims = FLAGS_GET_Z(pa->flags) ? 3 : 2;
103  POINT4D pt;
104  double *d;
105 
106  for ( i = 0; i < pa->npoints; i++ )
107  {
108  getPoint4d_p(pa, i, &pt);
109  d = (double*)(&pt);
110  if ( i ) stringbuffer_append(sb," ");
111  for (j = 0; j < dims; j++)
112  {
113  if ( j ) stringbuffer_append(sb,",");
114  if( fabs(d[j]) < OUT_MAX_DOUBLE )
115  {
116  if ( stringbuffer_aprintf(sb, "%.*f", precision, d[j]) < 0 ) return LW_FAILURE;
117  }
118  else
119  {
120  if ( stringbuffer_aprintf(sb, "%g", d[j]) < 0 ) return LW_FAILURE;
121  }
123  }
124  }
125  return LW_SUCCESS;
126 }
127 
128 
129 static int
130 lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
131 {
132  /* Open point */
133  if ( stringbuffer_aprintf(sb, "<%sPoint><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
134  /* Coordinate array */
135  if ( ptarray_to_kml2_sb(point->point, precision, sb) == LW_FAILURE ) return LW_FAILURE;
136  /* Close point */
137  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sPoint>", prefix, prefix) < 0 ) return LW_FAILURE;
138  return LW_SUCCESS;
139 }
140 
141 static int
142 lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
143 {
144  /* Open linestring */
145  if ( stringbuffer_aprintf(sb, "<%sLineString><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
146  /* Coordinate array */
147  if ( ptarray_to_kml2_sb(line->points, precision, sb) == LW_FAILURE ) return LW_FAILURE;
148  /* Close linestring */
149  if ( stringbuffer_aprintf(sb, "</%scoordinates></%sLineString>", prefix, prefix) < 0 ) return LW_FAILURE;
150 
151  return LW_SUCCESS;
152 }
153 
154 static int
155 lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb)
156 {
157  /* Open polygon */
159  sb, "<%sPolygon><%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix, prefix) < 0)
160  return LW_FAILURE;
161  /* Coordinate array */
162  if (ptarray_to_kml2_sb(tri->points, precision, sb) == LW_FAILURE)
163  return LW_FAILURE;
164  /* Close polygon */
166  sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs></%sPolygon>", prefix, prefix, prefix, prefix) <
167  0)
168  return LW_FAILURE;
169 
170  return LW_SUCCESS;
171 }
172 
173 static int
174 lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
175 {
176  uint32_t i;
177  int rv;
178 
179  /* Open polygon */
180  if ( stringbuffer_aprintf(sb, "<%sPolygon>", prefix) < 0 ) return LW_FAILURE;
181  for ( i = 0; i < poly->nrings; i++ )
182  {
183  /* Inner or outer ring opening tags */
184  if( i )
185  rv = stringbuffer_aprintf(sb, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
186  else
187  rv = stringbuffer_aprintf(sb, "<%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
188  if ( rv < 0 ) return LW_FAILURE;
189 
190  /* Coordinate array */
191  if ( ptarray_to_kml2_sb(poly->rings[i], precision, sb) == LW_FAILURE ) return LW_FAILURE;
192 
193  /* Inner or outer ring closing tags */
194  if( i )
195  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
196  else
197  rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
198  if ( rv < 0 ) return LW_FAILURE;
199  }
200  /* Close polygon */
201  if ( stringbuffer_aprintf(sb, "</%sPolygon>", prefix) < 0 ) return LW_FAILURE;
202 
203  return LW_SUCCESS;
204 }
205 
206 static int
207 lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
208 {
209  uint32_t i;
210  int rv;
211 
212  /* Open geometry */
213  if ( stringbuffer_aprintf(sb, "<%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
214  for ( i = 0; i < col->ngeoms; i++ )
215  {
216  rv = lwgeom_to_kml2_sb(col->geoms[i], precision, prefix, sb);
217  if ( rv == LW_FAILURE ) return LW_FAILURE;
218  }
219  /* Close geometry */
220  if ( stringbuffer_aprintf(sb, "</%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
221 
222  return LW_SUCCESS;
223 }
static uint8_t precision
Definition: cu_in_twkb.c:25
#define LW_FAILURE
Definition: liblwgeom.h:110
#define MULTILINETYPE
Definition: liblwgeom.h:120
#define LINETYPE
Definition: liblwgeom.h:117
#define LW_SUCCESS
Definition: liblwgeom.h:111
#define MULTIPOINTTYPE
Definition: liblwgeom.h:119
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
#define FLAGS_GET_Z(flags)
Definition: liblwgeom.h:179
#define TINTYPE
Definition: liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:121
#define POLYGONTYPE
Definition: liblwgeom.h:118
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:129
#define OUT_MAX_DOUBLE
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:193
static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:70
static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:207
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
Definition: lwout_kml.c:44
static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:174
static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:130
static int lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:155
static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb)
Definition: lwout_kml.c:99
static int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
Definition: lwout_kml.c:142
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:217
int stringbuffer_trim_trailing_zeroes(stringbuffer_t *s)
Trims zeroes off the end of the last number in the stringbuffer.
Definition: stringbuffer.c:268
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:76
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string.
Definition: stringbuffer.c:124
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
Definition: stringbuffer.h:88
uint32_t ngeoms
Definition: liblwgeom.h:566
LWGEOM ** geoms
Definition: liblwgeom.h:561
uint8_t type
Definition: liblwgeom.h:448
POINTARRAY * points
Definition: liblwgeom.h:469
POINTARRAY * point
Definition: liblwgeom.h:457
uint8_t type
Definition: liblwgeom.h:460
POINTARRAY ** rings
Definition: liblwgeom.h:505
uint32_t nrings
Definition: liblwgeom.h:510
POINTARRAY * points
Definition: liblwgeom.h:481
lwflags_t flags
Definition: liblwgeom.h:417
uint32_t npoints
Definition: liblwgeom.h:413