PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ LWGEOM_asGML()

Datum LWGEOM_asGML ( PG_FUNCTION_ARGS  )

Definition at line 185 of file lwgeom_export.c.

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

Referenced by getSRIDbySRS().

186 {
187  GSERIALIZED *geom;
188  LWGEOM *lwgeom;
189  char *gml = NULL;
190  text *result;
191  int version;
192  char *srs;
193  int srid;
194  int option = 0;
195  int lwopts = LW_GML_IS_DIMS;
196  int precision = DBL_DIG;
197  static const char* default_prefix = "gml:"; /* default prefix */
198  const char* prefix = default_prefix;
199  const char* gml_id = NULL;
200  size_t len;
201  char *gml_id_buf, *prefix_buf;
202  text *prefix_text, *gml_id_text;
203 
204 
205  /* Get the version */
206  version = PG_GETARG_INT32(0);
207  if ( version != 2 && version != 3 )
208  {
209  elog(ERROR, "Only GML 2 and GML 3 are supported");
210  PG_RETURN_NULL();
211  }
212 
213  /* Get the geometry */
214  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
215  geom = PG_GETARG_GSERIALIZED_P(1);
216 
217  /* Retrieve precision if any (default is max) */
218  if (PG_NARGS() >2 && !PG_ARGISNULL(2))
219  {
220  precision = PG_GETARG_INT32(2);
221  /* TODO: leave this to liblwgeom ? */
222  if ( precision > DBL_DIG )
223  precision = DBL_DIG;
224  else if ( precision < 0 ) precision = 0;
225  }
226 
227  /* retrieve option */
228  if (PG_NARGS() >3 && !PG_ARGISNULL(3))
229  option = PG_GETARG_INT32(3);
230 
231  /* retrieve prefix */
232  if (PG_NARGS() >4 && !PG_ARGISNULL(4))
233  {
234  prefix_text = PG_GETARG_TEXT_P(4);
235  if ( VARSIZE(prefix_text) == VARHDRSZ )
236  {
237  prefix = "";
238  }
239  else
240  {
241  len = VARSIZE(prefix_text)-VARHDRSZ;
242  prefix_buf = palloc(len + 2); /* +2 is one for the ':' and one for term null */
243  memcpy(prefix_buf, VARDATA(prefix_text), len);
244  /* add colon and null terminate */
245  prefix_buf[len] = ':';
246  prefix_buf[len+1] = '\0';
247  prefix = prefix_buf;
248  }
249  }
250 
251  if (PG_NARGS() >5 && !PG_ARGISNULL(5))
252  {
253  gml_id_text = PG_GETARG_TEXT_P(5);
254  if ( VARSIZE(gml_id_text) == VARHDRSZ )
255  {
256  gml_id = "";
257  }
258  else
259  {
260  len = VARSIZE(gml_id_text)-VARHDRSZ;
261  gml_id_buf = palloc(len+1);
262  memcpy(gml_id_buf, VARDATA(gml_id_text), len);
263  gml_id_buf[len] = '\0';
264  gml_id = gml_id_buf;
265  }
266  }
267 
268  srid = gserialized_get_srid(geom);
269  if (srid == SRID_UNKNOWN) srs = NULL;
270  else if (option & 1) srs = getSRSbySRID(srid, false);
271  else srs = getSRSbySRID(srid, true);
272 
273  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
274  if (option & 4) lwopts |= LW_GML_SHORTLINE;
275  if (option & 16) lwopts |= LW_GML_IS_DEGREE;
276  if (option & 32) lwopts |= LW_GML_EXTENT;
277 
278  lwgeom = lwgeom_from_gserialized(geom);
279 
280  if (version == 2 && lwopts & LW_GML_EXTENT)
281  gml = lwgeom_extent_to_gml2(lwgeom, srs, precision, prefix);
282  else if (version == 2)
283  gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
284  else if (version == 3 && lwopts & LW_GML_EXTENT)
285  gml = lwgeom_extent_to_gml3(lwgeom, srs, precision, lwopts, prefix);
286  else if (version == 3)
287  gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, gml_id);
288 
289  lwgeom_free(lwgeom);
290  PG_FREE_IF_COPY(geom, 1);
291 
292  /* Return null on null */
293  if ( ! gml )
294  PG_RETURN_NULL();
295 
296  result = cstring2text(gml);
297  lwfree(gml);
298  PG_RETURN_TEXT_P(result);
299 }
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 LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition: liblwgeom.h:1517
void lwfree(void *mem)
Definition: lwutil.c:242
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1063
LWGEOM * geom
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Definition: liblwgeom.h:1519
uint8_t precision
Definition: cu_in_twkb.c:25
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition: lwout_gml.c:198
char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition: lwout_gml.c:213
char * getSRSbySRID(int srid, bool short_crs)
Definition: lwgeom_export.c:55
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1513
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition: lwout_gml.c:736
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:83
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
Definition: liblwgeom.h:1515
Here is the call graph for this function:
Here is the caller graph for this function: