PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM_asGML()

Datum LWGEOM_asGML ( PG_FUNCTION_ARGS  )

Definition at line 203 of file lwgeom_export.c.

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

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: