PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ LWGEOM_asGML()

Datum LWGEOM_asGML ( PG_FUNCTION_ARGS  )

Definition at line 209 of file lwgeom_export.c.

210 {
211  GSERIALIZED *geom;
212  LWGEOM *lwgeom;
213  char *gml = NULL;
214  text *result;
215  int version;
216  char *srs;
217  int32_t srid;
218  int option = 0;
219  int lwopts = LW_GML_IS_DIMS;
220  int precision = DBL_DIG;
221  static const char* default_prefix = "gml:"; /* default prefix */
222  const char* prefix = default_prefix;
223  const char* gml_id = NULL;
224  size_t len;
225  char *gml_id_buf, *prefix_buf;
226  text *prefix_text, *gml_id_text;
227 
228 
229  /* Get the version */
230  version = PG_GETARG_INT32(0);
231  if ( version != 2 && version != 3 )
232  {
233  elog(ERROR, "Only GML 2 and GML 3 are supported");
234  PG_RETURN_NULL();
235  }
236 
237  /* Get the geometry */
238  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
239  geom = PG_GETARG_GSERIALIZED_P(1);
240 
241  /* Retrieve precision if any (default is max) */
242  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
243  {
244  precision = PG_GETARG_INT32(2);
245  /* TODO: leave this to liblwgeom ? */
246  if (precision > DBL_DIG)
247  precision = DBL_DIG;
248  else if (precision < 0)
249  precision = 0;
250  }
251 
252  /* retrieve option */
253  if (PG_NARGS() > 3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3);
254 
255  /* retrieve prefix */
256  if (PG_NARGS() >4 && !PG_ARGISNULL(4))
257  {
258  prefix_text = PG_GETARG_TEXT_P(4);
259  if ( VARSIZE(prefix_text) == VARHDRSZ )
260  {
261  prefix = "";
262  }
263  else
264  {
265  len = VARSIZE_ANY_EXHDR(prefix_text);
266  prefix_buf = palloc(len + 2); /* +2 is one for the ':' and one for term null */
267  memcpy(prefix_buf, VARDATA(prefix_text), len);
268  /* add colon and null terminate */
269  prefix_buf[len] = ':';
270  prefix_buf[len+1] = '\0';
271  prefix = prefix_buf;
272  }
273  }
274 
275  if (PG_NARGS() >5 && !PG_ARGISNULL(5))
276  {
277  gml_id_text = PG_GETARG_TEXT_P(5);
278  if ( VARSIZE(gml_id_text) == VARHDRSZ )
279  {
280  gml_id = "";
281  }
282  else
283  {
284  len = VARSIZE_ANY_EXHDR(gml_id_text);
285  gml_id_buf = palloc(len+1);
286  memcpy(gml_id_buf, VARDATA(gml_id_text), len);
287  gml_id_buf[len] = '\0';
288  gml_id = gml_id_buf;
289  }
290  }
291 
292  srid = gserialized_get_srid(geom);
293  if (srid == SRID_UNKNOWN) srs = NULL;
294  else if (option & 1)
295  srs = getSRSbySRID(fcinfo, srid, false);
296  else
297  srs = getSRSbySRID(fcinfo, srid, true);
298 
299  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
300  if (option & 4) lwopts |= LW_GML_SHORTLINE;
301  if (option & 8)
302  {
303  elog(ERROR,
304  "Options %d passed to ST_AsGML(geography) sets "
305  "unsupported value 8",
306  option);
307  PG_RETURN_NULL();
308  }
309  if (option & 16) lwopts |= LW_GML_IS_DEGREE;
310  if (option & 32) lwopts |= LW_GML_EXTENT;
311 
312  lwgeom = lwgeom_from_gserialized(geom);
313 
314  if (version == 2)
315  {
316  if (lwopts & LW_GML_EXTENT)
317  gml = lwgeom_extent_to_gml2(
318  lwgeom, srs, precision, prefix);
319  else
320  gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
321  }
322  if (version == 3)
323  {
324  if (lwopts & LW_GML_EXTENT)
325  gml = lwgeom_extent_to_gml3(
326  lwgeom, srs, precision, lwopts, prefix);
327  else
328  gml = lwgeom_to_gml3(
329  lwgeom, srs, precision, lwopts, prefix, gml_id);
330  }
331 
332  lwgeom_free(lwgeom);
333  PG_FREE_IF_COPY(geom, 1);
334 
335  /* Return null on null */
336  if ( ! gml )
337  PG_RETURN_NULL();
338 
339  result = cstring_to_text(gml);
340  lwfree(gml);
341  PG_RETURN_TEXT_P(result);
342 }
static uint8_t precision
Definition: cu_in_twkb.c:25
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: gserialized.c:126
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
Definition: liblwgeom.h:1650
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition: liblwgeom.h:1652
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Definition: liblwgeom.h:1654
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition: lwout_gml.c:716
char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition: lwout_gml.c:213
void lwfree(void *mem)
Definition: lwutil.c:242
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1648
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition: lwout_gml.c:198
char * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
VERSION GML 2 takes a GEOMETRY and returns a GML2 representation.
Definition: lwout_gml.c:231
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:229
char * getSRSbySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
Definition: lwgeom_export.c:66

References getSRSbySRID(), gserialized_get_srid(), LW_GML_EXTENT, LW_GML_IS_DEGREE, LW_GML_IS_DIMS, LW_GML_SHORTLINE, lwfree(), lwgeom_extent_to_gml2(), lwgeom_extent_to_gml3(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_to_gml2(), lwgeom_to_gml3(), precision, and SRID_UNKNOWN.

Here is the call graph for this function: