PostGIS  3.0.6dev-r@@SVN_REVISION@@
lwgeom_export.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright 2009-2011 Olivier Courtin <olivier.courtin@oslandia.com>
22  *
23  **********************************************************************/
24 
25 
26 
31 #include "float.h" /* for DBL_DIG */
32 
33 #include "postgres.h"
34 #include "catalog/pg_type.h" /* for CSTRINGOID */
35 #include "executor/spi.h"
36 #include "utils/builtins.h"
37 
38 #if POSTGIS_PGSQL_VERSION > 95
39 #include "utils/fmgrprotos.h"
40 #else
41 #include "utils/jsonb.h"
42 #endif
43 
44 #include "../postgis_config.h"
45 #include "lwgeom_pg.h"
46 #include "liblwgeom.h"
47 #include "lwgeom_export.h"
48 
49 Datum LWGEOM_asGML(PG_FUNCTION_ARGS);
50 Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS);
51 Datum LWGEOM_asGeoJson_old(PG_FUNCTION_ARGS);
52 Datum LWGEOM_asSVG(PG_FUNCTION_ARGS);
53 Datum LWGEOM_asX3D(PG_FUNCTION_ARGS);
54 Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS);
55 Datum geometry_to_json(PG_FUNCTION_ARGS);
56 Datum geometry_to_jsonb(PG_FUNCTION_ARGS);
57 
58 /*
59  * Retrieve an SRS from a given SRID
60  * Require valid spatial_ref_sys table entry
61  *
62  * Could return SRS as short one (i.e EPSG:4326)
63  * or as long one: (i.e urn:ogc:def:crs:EPSG::4326)
64  */
65 char *
66 getSRSbySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
67 {
68  static const uint16_t max_query_size = 512;
69  char query[512];
70  char *srs, *srscopy;
71  int size, err;
72  postgis_initialize_cache(fcinfo);
73 
74  if (SPI_OK_CONNECT != SPI_connect ())
75  {
76  elog(NOTICE, "getSRSbySRID: could not connect to SPI manager");
77  SPI_finish();
78  return NULL;
79  }
80 
81  if (short_crs)
82  snprintf(query,
83  max_query_size,
84  "SELECT auth_name||':'||auth_srid \
85  FROM %s WHERE srid='%d'",
86  postgis_spatial_ref_sys(),
87  srid);
88  else
89  snprintf(query,
90  max_query_size,
91  "SELECT 'urn:ogc:def:crs:'||auth_name||'::'||auth_srid \
92  FROM %s WHERE srid='%d'",
93  postgis_spatial_ref_sys(),
94  srid);
95 
96  err = SPI_exec(query, 1);
97  if ( err < 0 )
98  {
99  elog(NOTICE, "getSRSbySRID: error executing query %d", err);
100  SPI_finish();
101  return NULL;
102  }
103 
104  /* no entry in spatial_ref_sys */
105  if (SPI_processed <= 0)
106  {
107  SPI_finish();
108  return NULL;
109  }
110 
111  /* get result */
112  srs = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
113 
114  /* NULL result */
115  if ( ! srs )
116  {
117  SPI_finish();
118  return NULL;
119  }
120 
121  /* copy result to upper executor context */
122  size = strlen(srs)+1;
123  srscopy = SPI_palloc(size);
124  memcpy(srscopy, srs, size);
125 
126  /* disconnect from SPI */
127  SPI_finish();
128 
129  return srscopy;
130 }
131 
132 
133 /*
134 * Retrieve an SRID from a given SRS
135 * Require valid spatial_ref_sys table entry
136 *
137 */
138 int
139 getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
140 {
141  static const int16_t max_query_size = 512;
142  char query[512];
143  Oid argtypes[] = {CSTRINGOID};
144  Datum values[] = {CStringGetDatum(srs)};
145  int32_t srid, err;
146 
147  postgis_initialize_cache(fcinfo);
148  snprintf(query,
149  max_query_size,
150  "SELECT srid "
151  "FROM %s, "
152  "regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
153  "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
154  postgis_spatial_ref_sys());
155 
156  if (!srs) return 0;
157 
158  if (SPI_OK_CONNECT != SPI_connect())
159  {
160  elog(NOTICE, "getSRIDbySRS: could not connect to SPI manager");
161  return 0;
162  }
163 
164  err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
165  if (err < 0)
166  {
167  elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
168  SPI_finish();
169  return 0;
170  }
171 
172  /* no entry in spatial_ref_sys */
173  if (SPI_processed <= 0)
174  {
175  snprintf(query,
176  max_query_size,
177  "SELECT srid "
178  "FROM %s, "
179  "regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
180  "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
181  postgis_spatial_ref_sys());
182 
183  err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
184  if (err < 0)
185  {
186  elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
187  SPI_finish();
188  return 0;
189  }
190 
191  if (SPI_processed <= 0)
192  {
193  SPI_finish();
194  return 0;
195  }
196  }
197 
198  srid = atoi(SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1));
199  SPI_finish();
200 
201  return srid;
202 }
203 
204 
209 Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
210 {
211  GSERIALIZED *geom;
212  LWGEOM *lwgeom;
213  char *gml = NULL;
214  text *result;
215  int version;
216  char *srs;
217  int32_t srid;
218  int option = 0;
219  int lwopts = LW_GML_IS_DIMS;
220  int precision = DBL_DIG;
221  static const char* default_prefix = "gml:"; /* default prefix */
222  const char* prefix = default_prefix;
223  const char* gml_id = NULL;
224  size_t len;
225  char *gml_id_buf, *prefix_buf;
226  text *prefix_text, *gml_id_text;
227 
228 
229  /* Get the version */
230  version = PG_GETARG_INT32(0);
231  if ( version != 2 && version != 3 )
232  {
233  elog(ERROR, "Only GML 2 and GML 3 are supported");
234  PG_RETURN_NULL();
235  }
236 
237  /* Get the geometry */
238  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
239  geom = PG_GETARG_GSERIALIZED_P(1);
240 
241  /* Retrieve precision if any (default is max) */
242  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
243  {
244  precision = PG_GETARG_INT32(2);
245  /* TODO: leave this to liblwgeom ? */
246  if (precision > DBL_DIG)
247  precision = DBL_DIG;
248  else if (precision < 0)
249  precision = 0;
250  }
251 
252  /* retrieve option */
253  if (PG_NARGS() > 3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3);
254 
255  /* retrieve prefix */
256  if (PG_NARGS() >4 && !PG_ARGISNULL(4))
257  {
258  prefix_text = PG_GETARG_TEXT_P(4);
259  if ( VARSIZE(prefix_text) == VARHDRSZ )
260  {
261  prefix = "";
262  }
263  else
264  {
265  len = VARSIZE_ANY_EXHDR(prefix_text);
266  prefix_buf = palloc(len + 2); /* +2 is one for the ':' and one for term null */
267  memcpy(prefix_buf, VARDATA(prefix_text), len);
268  /* add colon and null terminate */
269  prefix_buf[len] = ':';
270  prefix_buf[len+1] = '\0';
271  prefix = prefix_buf;
272  }
273  }
274 
275  if (PG_NARGS() >5 && !PG_ARGISNULL(5))
276  {
277  gml_id_text = PG_GETARG_TEXT_P(5);
278  if ( VARSIZE(gml_id_text) == VARHDRSZ )
279  {
280  gml_id = "";
281  }
282  else
283  {
284  len = VARSIZE_ANY_EXHDR(gml_id_text);
285  gml_id_buf = palloc(len+1);
286  memcpy(gml_id_buf, VARDATA(gml_id_text), len);
287  gml_id_buf[len] = '\0';
288  gml_id = gml_id_buf;
289  }
290  }
291 
292  srid = gserialized_get_srid(geom);
293  if (srid == SRID_UNKNOWN) srs = NULL;
294  else if (option & 1)
295  srs = getSRSbySRID(fcinfo, srid, false);
296  else
297  srs = getSRSbySRID(fcinfo, srid, true);
298 
299  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
300  if (option & 4) lwopts |= LW_GML_SHORTLINE;
301  if (option & 8)
302  {
303  elog(ERROR,
304  "Options %d passed to ST_AsGML(geography) sets "
305  "unsupported value 8",
306  option);
307  PG_RETURN_NULL();
308  }
309  if (option & 16) lwopts |= LW_GML_IS_DEGREE;
310  if (option & 32) lwopts |= LW_GML_EXTENT;
311 
312  lwgeom = lwgeom_from_gserialized(geom);
313 
314  if (version == 2)
315  {
316  if (lwopts & LW_GML_EXTENT)
317  gml = lwgeom_extent_to_gml2(
318  lwgeom, srs, precision, prefix);
319  else
320  gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
321  }
322  if (version == 3)
323  {
324  if (lwopts & LW_GML_EXTENT)
325  gml = lwgeom_extent_to_gml3(
326  lwgeom, srs, precision, lwopts, prefix);
327  else
328  gml = lwgeom_to_gml3(
329  lwgeom, srs, precision, lwopts, prefix, gml_id);
330  }
331 
332  lwgeom_free(lwgeom);
333  PG_FREE_IF_COPY(geom, 1);
334 
335  /* Return null on null */
336  if ( ! gml )
337  PG_RETURN_NULL();
338 
339  result = cstring_to_text(gml);
340  lwfree(gml);
341  PG_RETURN_TEXT_P(result);
342 }
343 
344 
345 
346 
354 Datum LWGEOM_asGeoJson_old(PG_FUNCTION_ARGS)
355 {
356  switch( PG_NARGS() )
357  {
358  case 2:
359  return DirectFunctionCall1(LWGEOM_asGeoJson, PG_GETARG_DATUM(1));
360  case 3:
361  return DirectFunctionCall2(LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2));
362  case 4:
363  return DirectFunctionCall3(LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2), PG_GETARG_DATUM(3));
364  default:
365  elog(ERROR, "bad call in %s", __func__);
366  }
367  PG_RETURN_NULL();
368 }
369 
374 Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
375 {
376  GSERIALIZED *geom;
377  LWGEOM *lwgeom;
378  char *geojson;
379  text *result;
380  int precision = DBL_DIG;
381  int output_bbox = LW_FALSE;
382  int output_long_crs = LW_FALSE;
383  int output_short_crs = LW_FALSE;
384  int output_guess_short_srid = LW_FALSE;
385  char *srs = NULL;
386  int32_t srid;
387 
388  /* Get the geometry */
389  if (PG_ARGISNULL(0))
390  PG_RETURN_NULL();
391 
392  geom = PG_GETARG_GSERIALIZED_P(0);
393  srid = gserialized_get_srid(geom);
394 
395  /* Retrieve precision if any (default is max) */
396  if ( PG_NARGS() > 1 && !PG_ARGISNULL(1) )
397  {
398  precision = PG_GETARG_INT32(1);
399  if ( precision > DBL_DIG )
400  precision = DBL_DIG;
401  else if ( precision < 0 )
402  precision = 0;
403  }
404 
405  /* Retrieve output option
406  * 0 = without option
407  * 1 = bbox
408  * 2 = short crs
409  * 4 = long crs
410  * 8 = guess if CRS is needed (default)
411  */
412  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
413  {
414  int option = PG_GETARG_INT32(2);
415  output_guess_short_srid = (option & 8) ? LW_TRUE : LW_FALSE;
416  output_short_crs = (option & 2) ? LW_TRUE : LW_FALSE;
417  output_long_crs = (option & 4) ? LW_TRUE : LW_FALSE;
418  output_bbox = (option & 1) ? LW_TRUE : LW_FALSE;
419  }
420  else
421  output_guess_short_srid = LW_TRUE;
422 
423  if (output_guess_short_srid && srid != WGS84_SRID && srid != SRID_UNKNOWN)
424  output_short_crs = LW_TRUE;
425 
426  if (srid != SRID_UNKNOWN && (output_short_crs || output_long_crs))
427  {
428  srs = getSRSbySRID(fcinfo, srid, !output_long_crs);
429 
430  if (!srs)
431  {
432  elog(ERROR, "SRID %i unknown in spatial_ref_sys table", srid);
433  PG_RETURN_NULL();
434  }
435  }
436 
437  lwgeom = lwgeom_from_gserialized(geom);
438  geojson = lwgeom_to_geojson(lwgeom, srs, precision, output_bbox);
439  lwgeom_free(lwgeom);
440 
441  if (srs) pfree(srs);
442 
443  result = cstring_to_text(geojson);
444  lwfree(geojson);
445 
446  PG_FREE_IF_COPY(geom, 0);
447  PG_RETURN_TEXT_P(result);
448 }
449 
450 
455 Datum geometry_to_json(PG_FUNCTION_ARGS)
456 {
457  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
458  LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
459  char *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0);
460  text *result = cstring_to_text(geojson);
461  lwgeom_free(lwgeom);
462  pfree(geojson);
463  PG_FREE_IF_COPY(geom, 0);
464  PG_RETURN_TEXT_P(result);
465 }
466 
468 Datum geometry_to_jsonb(PG_FUNCTION_ARGS)
469 {
470  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
471  LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
472  char *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0);
473  lwgeom_free(lwgeom);
474  PG_RETURN_DATUM(DirectFunctionCall1(jsonb_in, PointerGetDatum(geojson)));
475 }
476 
477 
482 Datum LWGEOM_asSVG(PG_FUNCTION_ARGS)
483 {
484  GSERIALIZED *geom;
485  LWGEOM *lwgeom;
486  char *svg;
487  text *result;
488  int relative = 0;
489  int precision=DBL_DIG;
490 
491  if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
492 
493  geom = PG_GETARG_GSERIALIZED_P(0);
494 
495  /* check for relative path notation */
496  if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
497  relative = PG_GETARG_INT32(1) ? 1:0;
498 
499  if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
500  {
501  precision = PG_GETARG_INT32(2);
502  /* TODO: leave this to liblwgeom ? */
503  if ( precision > DBL_DIG )
504  precision = DBL_DIG;
505  else if ( precision < 0 ) precision = 0;
506  }
507 
508  lwgeom = lwgeom_from_gserialized(geom);
509  svg = lwgeom_to_svg(lwgeom, precision, relative);
510  result = cstring_to_text(svg);
511  lwgeom_free(lwgeom);
512  pfree(svg);
513  PG_FREE_IF_COPY(geom, 0);
514 
515  PG_RETURN_TEXT_P(result);
516 }
517 
522 Datum LWGEOM_asX3D(PG_FUNCTION_ARGS)
523 {
524  GSERIALIZED *geom;
525  LWGEOM *lwgeom;
526  char *x3d;
527  text *result;
528  int version;
529  char *srs;
530  int32_t srid;
531  int option = 0;
532  int precision = DBL_DIG;
533  static const char* default_defid = "x3d:"; /* default defid */
534  char *defidbuf;
535  const char* defid = default_defid;
536  text *defid_text;
537 
538  /* Get the version */
539  version = PG_GETARG_INT32(0);
540  if ( version != 3 )
541  {
542  elog(ERROR, "Only X3D version 3 are supported");
543  PG_RETURN_NULL();
544  }
545 
546  /* Get the geometry */
547  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
548  geom = PG_GETARG_GSERIALIZED_P(1);
549 
550  /* Retrieve precision if any (default is max) */
551  if (PG_NARGS() >2 && !PG_ARGISNULL(2))
552  {
553  precision = PG_GETARG_INT32(2);
554  /* TODO: leave this to liblwgeom ? */
555  if ( precision > DBL_DIG )
556  precision = DBL_DIG;
557  else if ( precision < 0 ) precision = 0;
558  }
559 
560  /* retrieve option */
561  if (PG_NARGS() >3 && !PG_ARGISNULL(3))
562  option = PG_GETARG_INT32(3);
563 
564 
565 
566  /* retrieve defid */
567  if (PG_NARGS() >4 && !PG_ARGISNULL(4))
568  {
569  defid_text = PG_GETARG_TEXT_P(4);
570  if ( VARSIZE_ANY_EXHDR(defid_text) == 0 )
571  {
572  defid = "";
573  }
574  else
575  {
576  /* +2 is one for the ':' and one for term null */
577  defidbuf = palloc(VARSIZE_ANY_EXHDR(defid_text)+2);
578  memcpy(defidbuf, VARDATA(defid_text),
579  VARSIZE_ANY_EXHDR(defid_text));
580  /* add colon and null terminate */
581  defidbuf[VARSIZE_ANY_EXHDR(defid_text)] = ':';
582  defidbuf[VARSIZE_ANY_EXHDR(defid_text)+1] = '\0';
583  defid = defidbuf;
584  }
585  }
586 
587  lwgeom = lwgeom_from_gserialized(geom);
588  srid = gserialized_get_srid(geom);
589  if (srid == SRID_UNKNOWN) srs = NULL;
590  else if (option & 1)
591  srs = getSRSbySRID(fcinfo, srid, false);
592  else
593  srs = getSRSbySRID(fcinfo, srid, true);
594 
595  if (option & LW_X3D_USE_GEOCOORDS) {
596  if (srid != 4326) {
597  PG_FREE_IF_COPY(geom, 0);
600  elog(ERROR, "Only SRID 4326 is supported for geocoordinates.");
601  PG_RETURN_NULL();
602  }
603  }
604 
605 
606  x3d = lwgeom_to_x3d3(lwgeom, srs, precision,option, defid);
607 
608  lwgeom_free(lwgeom);
609  PG_FREE_IF_COPY(geom, 1);
610 
611  result = cstring_to_text(x3d);
612  lwfree(x3d);
613 
614  PG_RETURN_TEXT_P(result);
615 }
616 
621 Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS)
622 {
623  GSERIALIZED *geom;
624  LWGEOM *lwgeom;
625  char *encodedpolyline;
626  int precision = 5;
627  text *result;
628 
629  if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
630 
631  geom = PG_GETARG_GSERIALIZED_P(0);
632  if (gserialized_get_srid(geom) != 4326) {
633  PG_FREE_IF_COPY(geom, 0);
634  elog(ERROR, "Only SRID 4326 is supported.");
635  PG_RETURN_NULL();
636  }
637  lwgeom = lwgeom_from_gserialized(geom);
638 
639  if (PG_NARGS() > 1 && !PG_ARGISNULL(1))
640  {
641  precision = PG_GETARG_INT32(1);
642  if ( precision < 0 ) precision = 5;
643  }
644 
645  encodedpolyline = lwgeom_to_encoded_polyline(lwgeom, precision);
646  lwgeom_free(lwgeom);
647  PG_FREE_IF_COPY(geom, 0);
648 
649  result = cstring_to_text(encodedpolyline);
650  lwfree(encodedpolyline);
651 
652  PG_RETURN_TEXT_P(result);
653 }
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
char * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
Definition: lwout_svg.c:56
#define WGS84_SRID
Definition: liblwgeom.h:163
#define LW_FALSE
Definition: liblwgeom.h:108
#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
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition: liblwgeom.h:1652
char * lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid)
Definition: lwout_x3d.c:36
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Definition: liblwgeom.h:1654
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
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:242
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1648
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition: lwout_gml.c:198
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:107
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:229
char * lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
Definition: lwout_geojson.c:49
#define LW_X3D_USE_GEOCOORDS
Definition: liblwgeom.h:1667
char * lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
This library is the generic geometry handling section of PostGIS.
Datum geometry_to_json(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(LWGEOM_asGML)
Encode feature in GML.
int getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
Datum LWGEOM_asGeoJson_old(PG_FUNCTION_ARGS)
Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS)
Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
Datum LWGEOM_asSVG(PG_FUNCTION_ARGS)
Datum geometry_to_jsonb(PG_FUNCTION_ARGS)
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
char * getSRSbySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
Definition: lwgeom_export.c:66
Datum LWGEOM_asX3D(PG_FUNCTION_ARGS)