PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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)...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
lwvarlena_t * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition lwout_gml.c:1081
#define LW_GML_IS_DEGREE
For GML3 only, declare that data are lat/lon.
Definition liblwgeom.h:1714
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition liblwgeom.h:1716
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Definition liblwgeom.h:1718
lwvarlena_t * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:920
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition liblwgeom.h:1712
lwvarlena_t * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:1063
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 SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
#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: