PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ geography_as_gml()

Datum geography_as_gml ( PG_FUNCTION_ARGS  )

Definition at line 209 of file geography_inout.c.

210 {
211  LWGEOM *lwgeom = NULL;
212  GSERIALIZED *g = NULL;
213  char *gml;
214  text *result;
215  int version;
216  char *srs;
217  int32_t srid = SRID_DEFAULT;
218  int precision = DBL_DIG;
219  int option = 0;
220  int lwopts = LW_GML_IS_DIMS;
221  static const char *default_prefix = "gml:";
222  const char *prefix = default_prefix;
223  char *prefix_buf = "";
224  text *prefix_text, *id_text = NULL;
225  const char *id = NULL;
226  char *id_buf;
227 
228  /*
229  * Two potential callers, one starts with GML version,
230  * one starts with geography, and we check for initial
231  * argument type and then dynamically change what args
232  * we read based on presence/absence
233  */
234  Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
235  int argnum = 0;
236  int argeom = 0;
237  if (first_type != INT4OID)
238  {
239  version = 2;
240  }
241  else
242  {
243  /* Get the version */
244  version = PG_GETARG_INT32(argnum++);
245  argeom = 1;
246  if (version != 2 && version != 3)
247  {
248  elog(ERROR, "Only GML 2 and GML 3 are supported");
249  PG_RETURN_NULL();
250  }
251  }
252 
253  /* Get the parameters, both callers have same order */
254  g = PG_GETARG_GSERIALIZED_P(argnum++);
255  precision = PG_GETARG_INT32(argnum++);
256  option = PG_GETARG_INT32(argnum++);
257  prefix_text = PG_GETARG_TEXT_P(argnum++);
258  id_text = PG_GETARG_TEXT_P(argnum++);
259 
260  /* Convert to lwgeom so we can run the old functions */
261  lwgeom = lwgeom_from_gserialized(g);
262 
263  /* Condition the precision argument */
264  if (precision > DBL_DIG)
265  precision = DBL_DIG;
266  if (precision < 0)
267  precision = 0;
268 
269  /* Condition the prefix argument */
270  if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
271  {
272  /* +2 is one for the ':' and one for term null */
273  prefix_buf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
274  memcpy(prefix_buf, VARDATA_ANY(prefix_text),
275  VARSIZE_ANY_EXHDR(prefix_text));
276  /* add colon and null terminate */
277  prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)] = ':';
278  prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)+1] = '\0';
279  prefix = prefix_buf;
280  }
281  else
282  {
283  prefix = "";
284  }
285 
286  if (VARSIZE_ANY_EXHDR(id_text) > 0)
287  {
288  id_buf = palloc(VARSIZE_ANY_EXHDR(id_text)+2);
289  memcpy(id_buf, VARDATA(id_text), VARSIZE_ANY_EXHDR(id_text));
290  id_buf[VARSIZE_ANY_EXHDR(id_text)+1] = '\0';
291  id = id_buf;
292  }
293 
294  if (option & 1)
295  srs = getSRSbySRID(fcinfo, srid, false);
296  else
297  srs = getSRSbySRID(fcinfo, srid, true);
298  if (!srs)
299  {
300  elog(ERROR, "SRID %d unknown in spatial_ref_sys table", SRID_DEFAULT);
301  PG_RETURN_NULL();
302  }
303 
304  /* Revert lat/lon only with long SRS */
305  if (option & 1) lwopts |= LW_GML_IS_DEGREE;
306  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
307  if (option & 8)
308  {
309  elog(ERROR,
310  "Options %d passed to ST_AsGML(geography) sets "
311  "unsupported value 8",
312  option);
313  PG_RETURN_NULL();
314  }
315  if ((option & 4) || (option & 16) || (option & 32))
316  {
317  elog(ERROR,
318  "Options %d passed to ST_AsGML(geography) but are only "
319  "applicable to ST_AsGML(geometry)",
320  option);
321  PG_RETURN_NULL();
322  }
323 
324  if (version == 2)
325  gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
326  else
327  gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id);
328 
329  lwgeom_free(lwgeom);
330  PG_FREE_IF_COPY(g, argeom);
331 
332  /* Return null on null */
333  if (!gml)
334  PG_RETURN_NULL();
335 
336  /* Turn string result into text for return */
337  result = cstring_to_text(gml);
338  lwfree(gml);
339 
340  PG_RETURN_TEXT_P(result);
341 }
static uint8_t precision
Definition: cu_in_twkb.c:25
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
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
void lwfree(void *mem)
Definition: lwutil.c:242
#define SRID_DEFAULT
Definition: liblwgeom.h:239
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1648
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
char * getSRSbySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
Definition: lwgeom_export.c:66

References getSRSbySRID(), LW_GML_IS_DEGREE, LW_GML_IS_DIMS, lwfree(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_to_gml2(), lwgeom_to_gml3(), precision, and SRID_DEFAULT.

Here is the call graph for this function: