PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ LWGEOM_asGML()

Datum LWGEOM_asGML ( PG_FUNCTION_ARGS  )

Definition at line 56 of file lwgeom_export.c.

57 {
58  GSERIALIZED *geom;
59  LWGEOM *lwgeom;
60  lwvarlena_t *v = NULL;
61  int version;
62  const char *srs;
63  int32_t srid;
64  int option = 0;
65  int lwopts = LW_GML_IS_DIMS;
67  static const char* default_prefix = "gml:"; /* default prefix */
68  const char* prefix = default_prefix;
69  const char* gml_id = NULL;
70  size_t len;
71  char *gml_id_buf, *prefix_buf;
72  text *prefix_text, *gml_id_text;
73 
74  /*
75  * Two potential callers, one starts with GML version,
76  * one starts with geometry, and we check for initial
77  * argument type and then dynamically change what args
78  * we read based on presence/absence
79  */
80  Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
81  int argnum = 0;
82  if (first_type != INT4OID)
83  {
84  version = 2;
85  }
86  else
87  {
88  /* Get the version */
89  version = PG_GETARG_INT32(argnum++);
90  if (version != 2 && version != 3)
91  {
92  elog(ERROR, "Only GML 2 and GML 3 are supported");
93  PG_RETURN_NULL();
94  }
95  }
96 
97  /* Get the geometry */
98  if (PG_ARGISNULL(argnum))
99  PG_RETURN_NULL();
100  geom = PG_GETARG_GSERIALIZED_P(argnum++);
101 
102  /* Retrieve precision if any (default is max) */
103  if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
104  {
105  precision = PG_GETARG_INT32(argnum);
106  }
107  argnum++;
108 
109  /* retrieve option */
110  if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
111  option = PG_GETARG_INT32(argnum);
112  argnum++;
113 
114  /* retrieve prefix */
115  if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
116  {
117  prefix_text = PG_GETARG_TEXT_P(argnum);
118  if ( VARSIZE(prefix_text) == VARHDRSZ )
119  {
120  prefix = "";
121  }
122  else
123  {
124  len = VARSIZE_ANY_EXHDR(prefix_text);
125  prefix_buf = palloc(len + 2); /* +2 is one for the ':' and one for term null */
126  memcpy(prefix_buf, VARDATA(prefix_text), len);
127  /* add colon and null terminate */
128  prefix_buf[len] = ':';
129  prefix_buf[len+1] = '\0';
130  prefix = prefix_buf;
131  }
132  }
133  argnum++;
134 
135  if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
136  {
137  gml_id_text = PG_GETARG_TEXT_P(argnum);
138  if ( VARSIZE(gml_id_text) == VARHDRSZ )
139  {
140  gml_id = "";
141  }
142  else
143  {
144  len = VARSIZE_ANY_EXHDR(gml_id_text);
145  gml_id_buf = palloc(len+1);
146  memcpy(gml_id_buf, VARDATA(gml_id_text), len);
147  gml_id_buf[len] = '\0';
148  gml_id = gml_id_buf;
149  }
150  }
151  argnum++;
152 
153  srid = gserialized_get_srid(geom);
154  if (srid == SRID_UNKNOWN) srs = NULL;
155  else if (option & 1)
156  srs = GetSRSCacheBySRID(fcinfo, srid, false);
157  else
158  srs = GetSRSCacheBySRID(fcinfo, srid, true);
159 
160  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
161  if (option & 4) lwopts |= LW_GML_SHORTLINE;
162  if (option & 8)
163  {
164  elog(ERROR,
165  "Options %d passed to ST_AsGML(geometry) sets "
166  "unsupported value 8",
167  option);
168  PG_RETURN_NULL();
169  }
170  if (option & 16) lwopts |= LW_GML_IS_DEGREE;
171  if (option & 32) lwopts |= LW_GML_EXTENT;
172 
173  lwgeom = lwgeom_from_gserialized(geom);
174 
175  if (version == 2)
176  {
177  if (lwopts & LW_GML_EXTENT)
178  v = lwgeom_extent_to_gml2(lwgeom, srs, precision, prefix);
179  else
180  v = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
181  }
182  if (version == 3)
183  {
184  if (lwopts & LW_GML_EXTENT)
185  v = lwgeom_extent_to_gml3(lwgeom, srs, precision, lwopts, prefix);
186  else
187  v = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, gml_id);
188  }
189 
190  if (!v)
191  PG_RETURN_NULL();
192  PG_RETURN_TEXT_P(v);
193 }
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:1684
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition: liblwgeom.h:1686
lwvarlena_t * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition: lwout_gml.c:920
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Definition: liblwgeom.h:1688
lwvarlena_t * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition: lwout_gml.c:1081
lwvarlena_t * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition: lwout_gml.c:1063
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1682
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
lwvarlena_t * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition: lwout_gml.c:978
#define OUT_DEFAULT_DECIMAL_DIGITS

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

Here is the call graph for this function: