PostGIS  2.1.10dev-r@@SVN_REVISION@@
lwgeom_inout.c
Go to the documentation of this file.
1 #include "postgres.h"
2 
3 #include "../postgis_config.h"
4 
5 #include <math.h>
6 #include <float.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <errno.h>
10 #include <assert.h>
11 
12 #include "access/gist.h"
13 #include "access/itup.h"
14 
15 #include "fmgr.h"
16 #include "utils/elog.h"
17 #include "mb/pg_wchar.h"
18 # include "lib/stringinfo.h" /* for binary input */
19 
20 #include "liblwgeom.h"
21 #include "lwgeom_pg.h"
22 #include "geography.h" /* for lwgeom_valid_typmod */
23 
24 void elog_ERROR(const char* string);
25 
26 Datum LWGEOM_in(PG_FUNCTION_ARGS);
27 Datum LWGEOM_out(PG_FUNCTION_ARGS);
28 Datum LWGEOM_to_text(PG_FUNCTION_ARGS);
29 Datum LWGEOM_to_bytea(PG_FUNCTION_ARGS);
30 Datum LWGEOM_from_bytea(PG_FUNCTION_ARGS);
31 Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS);
32 Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS);
33 Datum LWGEOM_recv(PG_FUNCTION_ARGS);
34 Datum LWGEOM_send(PG_FUNCTION_ARGS);
35 Datum LWGEOM_to_latlon(PG_FUNCTION_ARGS);
36 
37 
38 /*
39  * LWGEOM_in(cstring)
40  * format is '[SRID=#;]wkt|wkb'
41  * LWGEOM_in( 'SRID=99;POINT(0 0)')
42  * LWGEOM_in( 'POINT(0 0)') --> assumes SRID=SRID_UNKNOWN
43  * LWGEOM_in( 'SRID=99;0101000000000000000000F03F000000000000004')
44  * LWGEOM_in( '0101000000000000000000F03F000000000000004')
45  * returns a GSERIALIZED object
46  */
48 Datum LWGEOM_in(PG_FUNCTION_ARGS)
49 {
50  char *input = PG_GETARG_CSTRING(0);
51  int32 geom_typmod = -1;
52  char *str = input;
53  LWGEOM_PARSER_RESULT lwg_parser_result;
54  LWGEOM *lwgeom;
55  GSERIALIZED *ret;
56  int srid = 0;
57 
58  if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
59  geom_typmod = PG_GETARG_INT32(2);
60  }
61 
62  lwgeom_parser_result_init(&lwg_parser_result);
63 
64  /* Empty string. */
65  if ( str[0] == '\0' ) {
66  ereport(ERROR,(errmsg("parse error - invalid geometry")));
67  PG_RETURN_NULL();
68  }
69 
70  /* Starts with "SRID=" */
71  if( strncasecmp(str,"SRID=",5) == 0 )
72  {
73  /* Roll forward to semi-colon */
74  char *tmp = str;
75  while ( tmp && *tmp != ';' )
76  tmp++;
77 
78  /* Check next character to see if we have WKB */
79  if ( tmp && *(tmp+1) == '0' )
80  {
81  /* Null terminate the SRID= string */
82  *tmp = '\0';
83  /* Set str to the start of the real WKB */
84  str = tmp + 1;
85  /* Move tmp to the start of the numeric part */
86  tmp = input + 5;
87  /* Parse out the SRID number */
88  srid = atoi(tmp);
89  }
90  }
91 
92  /* WKB? Let's find out. */
93  if ( str[0] == '0' )
94  {
95  size_t hexsize = strlen(str);
96  unsigned char *wkb = bytes_from_hexbytes(str, hexsize);
97  /* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */
98  lwgeom = lwgeom_from_wkb(wkb, hexsize/2, LW_PARSER_CHECK_NONE);
99  /* If we picked up an SRID at the head of the WKB set it manually */
100  if ( srid ) lwgeom_set_srid(lwgeom, srid);
101  /* Add a bbox if necessary */
102  if ( lwgeom_needs_bbox(lwgeom) ) lwgeom_add_bbox(lwgeom);
103  pfree(wkb);
104  ret = geometry_serialize(lwgeom);
105  lwgeom_free(lwgeom);
106  }
107  /* WKT then. */
108  else
109  {
110  if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE )
111  {
112  PG_PARSER_ERROR(lwg_parser_result);
113  PG_RETURN_NULL();
114  }
115  lwgeom = lwg_parser_result.geom;
116  if ( lwgeom_needs_bbox(lwgeom) )
117  lwgeom_add_bbox(lwgeom);
118  ret = geometry_serialize(lwgeom);
119  lwgeom_parser_result_free(&lwg_parser_result);
120  }
121 
122  if ( geom_typmod >= 0 )
123  {
124  ret = postgis_valid_typmod(ret, geom_typmod);
125  POSTGIS_DEBUG(3, "typmod and geometry were consistent");
126  }
127  else
128  {
129  POSTGIS_DEBUG(3, "typmod was -1");
130  }
131 
132  /* Don't free the parser result (and hence lwgeom) until we have done */
133  /* the typemod check with lwgeom */
134 
135  PG_RETURN_POINTER(ret);
136 
137 }
138 
139 /*
140  * LWGEOM_to_latlon(GEOMETRY, text)
141  * NOTE: Geometry must be a point. It is assumed that the coordinates
142  * of the point are in a lat/lon projection, and they will be
143  * normalized in the output to -90-90 and -180-180.
144  *
145  * The text parameter is a format string containing the format for the
146  * resulting text, similar to a date format string. Valid tokens
147  * are "D" for degrees, "M" for minutes, "S" for seconds, and "C" for
148  * cardinal direction (NSEW). DMS tokens may be repeated to indicate
149  * desired width and precision ("SSS.SSSS" means " 1.0023").
150  * "M", "S", and "C" are optional. If "C" is omitted, degrees are
151  * shown with a "-" sign if south or west. If "S" is omitted,
152  * minutes will be shown as decimal with as many digits of precision
153  * as you specify. If "M" is omitted, degrees are shown as decimal
154  * with as many digits precision as you specify.
155  *
156  * If the format string is omitted (null or 0-length) a default
157  * format will be used.
158  *
159  * returns text
160  */
162 Datum LWGEOM_to_latlon(PG_FUNCTION_ARGS)
163 {
164  /* Get the parameters */
165  GSERIALIZED *pg_lwgeom = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
166  text *format_text = PG_GETARG_TEXT_P(1);
167 
168  LWGEOM *lwgeom;
169  char *format_str = NULL;
170 
171  char * formatted_str;
172  text * formatted_text;
173  char * tmp;
174 
175  /* Only supports points. */
176  uint8_t geom_type = gserialized_get_type(pg_lwgeom);
177  if (POINTTYPE != geom_type)
178  {
179  lwerror("Only points are supported, you tried type %s.", lwtype_name(geom_type));
180  }
181  /* Convert to LWGEOM type */
182  lwgeom = lwgeom_from_gserialized(pg_lwgeom);
183 
184  if (format_text == NULL) {
185  lwerror("ST_AsLatLonText: invalid format string (null");
186  PG_RETURN_NULL();
187  }
188 
189  format_str = text2cstring(format_text);
190  assert(format_str != NULL);
191 
192  /* The input string supposedly will be in the database encoding,
193  so convert to UTF-8. */
194  tmp = (char *)pg_do_encoding_conversion(
195  (uint8_t *)format_str, strlen(format_str), GetDatabaseEncoding(), PG_UTF8);
196  assert(tmp != NULL);
197  if ( tmp != format_str ) {
198  pfree(format_str);
199  format_str = tmp;
200  }
201 
202  /* Produce the formatted string. */
203  formatted_str = lwpoint_to_latlon((LWPOINT *)lwgeom, format_str);
204  assert(formatted_str != NULL);
205  pfree(format_str);
206 
207  /* Convert the formatted string from UTF-8 back to database encoding. */
208  tmp = (char *)pg_do_encoding_conversion(
209  (uint8_t *)formatted_str, strlen(formatted_str),
210  PG_UTF8, GetDatabaseEncoding());
211  assert(tmp != NULL);
212  if ( tmp != formatted_str) {
213  pfree(formatted_str);
214  formatted_str = tmp;
215  }
216 
217  /* Convert to the postgres output string type. */
218  formatted_text = cstring2text(formatted_str);
219  pfree(formatted_str);
220 
221  PG_RETURN_POINTER(formatted_text);
222 }
223 
224 /*
225  * LWGEOM_out(lwgeom) --> cstring
226  * output is 'SRID=#;<wkb in hex form>'
227  * ie. 'SRID=-99;0101000000000000000000F03F0000000000000040'
228  * WKB is machine endian
229  * if SRID=-1, the 'SRID=-1;' will probably not be present.
230  */
232 Datum LWGEOM_out(PG_FUNCTION_ARGS)
233 {
234  GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
235  LWGEOM *lwgeom;
236  char *hexwkb;
237  size_t hexwkb_size;
238 
239  lwgeom = lwgeom_from_gserialized(geom);
240  hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &hexwkb_size);
241  lwgeom_free(lwgeom);
242 
243  PG_RETURN_CSTRING(hexwkb);
244 }
245 
246 /*
247  * AsHEXEWKB(geom, string)
248  */
250 Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS)
251 {
252  GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
253  LWGEOM *lwgeom;
254  char *hexwkb;
255  size_t hexwkb_size;
256  uint8_t variant = 0;
257  text *result;
258  text *type;
259  size_t text_size;
260 
261  /* If user specified endianness, respect it */
262  if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
263  {
264  type = PG_GETARG_TEXT_P(1);
265 
266  if ( ! strncmp(VARDATA(type), "xdr", 3) ||
267  ! strncmp(VARDATA(type), "XDR", 3) )
268  {
269  variant = variant | WKB_XDR;
270  }
271  else
272  {
273  variant = variant | WKB_NDR;
274  }
275  }
276 
277  /* Create WKB hex string */
278  lwgeom = lwgeom_from_gserialized(geom);
279  hexwkb = lwgeom_to_hexwkb(lwgeom, variant | WKB_EXTENDED, &hexwkb_size);
280  lwgeom_free(lwgeom);
281 
282  /* Prepare the PgSQL text return type */
283  text_size = hexwkb_size - 1 + VARHDRSZ;
284  result = palloc(text_size);
285  memcpy(VARDATA(result), hexwkb, hexwkb_size - 1);
286  SET_VARSIZE(result, text_size);
287 
288  /* Clean up and return */
289  pfree(hexwkb);
290  PG_FREE_IF_COPY(geom, 0);
291  PG_RETURN_TEXT_P(result);
292 }
293 
294 
295 /*
296  * LWGEOM_to_text(lwgeom) --> text
297  * output is 'SRID=#;<wkb in hex form>'
298  * ie. 'SRID=-99;0101000000000000000000F03F0000000000000040'
299  * WKB is machine endian
300  * if SRID=-1, the 'SRID=-1;' will probably not be present.
301  */
303 Datum LWGEOM_to_text(PG_FUNCTION_ARGS)
304 {
305  GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
306  LWGEOM *lwgeom;
307  char *hexwkb;
308  size_t hexwkb_size;
309  text *result;
310 
311  /* Generate WKB hex text */
312  lwgeom = lwgeom_from_gserialized(geom);
313  hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &hexwkb_size);
314  lwgeom_free(lwgeom);
315 
316  /* Copy into text obect */
317  result = cstring2text(hexwkb);
318  pfree(hexwkb);
319 
320  /* Clean up and return */
321  PG_FREE_IF_COPY(geom, 0);
322  PG_RETURN_TEXT_P(result);
323 }
324 
325 /*
326  * LWGEOMFromWKB(wkb, [SRID] )
327  * NOTE: wkb is in *binary* not hex form.
328  *
329  * NOTE: this function parses EWKB (extended form)
330  * which also contains SRID info.
331  */
333 Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
334 {
335  bytea *bytea_wkb = (bytea*)PG_GETARG_BYTEA_P(0);
336  int32 srid = 0;
337  GSERIALIZED *geom;
338  LWGEOM *lwgeom;
339  uint8_t *wkb = (uint8_t*)VARDATA(bytea_wkb);
340 
341  lwgeom = lwgeom_from_wkb(wkb, VARSIZE(bytea_wkb)-VARHDRSZ, LW_PARSER_CHECK_ALL);
342 
343  if ( ( PG_NARGS()>1) && ( ! PG_ARGISNULL(1) ))
344  {
345  srid = PG_GETARG_INT32(1);
346  lwgeom_set_srid(lwgeom, srid);
347  }
348 
349  if ( lwgeom_needs_bbox(lwgeom) )
350  lwgeom_add_bbox(lwgeom);
351 
352  geom = geometry_serialize(lwgeom);
353  lwgeom_free(lwgeom);
354  PG_FREE_IF_COPY(bytea_wkb, 0);
355  PG_RETURN_POINTER(geom);
356 }
357 
358 /*
359  * WKBFromLWGEOM(lwgeom) --> wkb
360  * this will have no 'SRID=#;'
361  */
363 Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
364 {
365  GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
366  LWGEOM *lwgeom;
367  uint8_t *wkb;
368  size_t wkb_size;
369  uint8_t variant = 0;
370  bytea *result;
371  text *type;
372 
373  /* If user specified endianness, respect it */
374  if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
375  {
376  type = PG_GETARG_TEXT_P(1);
377 
378  if ( ! strncmp(VARDATA(type), "xdr", 3) ||
379  ! strncmp(VARDATA(type), "XDR", 3) )
380  {
381  variant = variant | WKB_XDR;
382  }
383  else
384  {
385  variant = variant | WKB_NDR;
386  }
387  }
388 
389  /* Create WKB hex string */
390  lwgeom = lwgeom_from_gserialized(geom);
391  wkb = lwgeom_to_wkb(lwgeom, variant | WKB_EXTENDED , &wkb_size);
392  lwgeom_free(lwgeom);
393 
394  /* Prepare the PgSQL text return type */
395  result = palloc(wkb_size + VARHDRSZ);
396  memcpy(VARDATA(result), wkb, wkb_size);
397  SET_VARSIZE(result, wkb_size+VARHDRSZ);
398 
399  /* Clean up and return */
400  pfree(wkb);
401  PG_FREE_IF_COPY(geom, 0);
402  PG_RETURN_BYTEA_P(result);
403 }
404 
405 
406 /* puts a bbox inside the geometry */
408 Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS)
409 {
410  GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
412  LWGEOM *lwgeom;
413 
414  lwgeom = lwgeom_from_gserialized(geom);
415  lwgeom_add_bbox(lwgeom);
416  result = geometry_serialize(lwgeom);
417 
418  PG_FREE_IF_COPY(geom, 0);
419  PG_RETURN_POINTER(result);
420 }
421 
422 /* removes a bbox from a geometry */
424 Datum LWGEOM_dropBBOX(PG_FUNCTION_ARGS)
425 {
426  GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
427 
428  /* No box? we're done already! */
429  if ( ! gserialized_has_bbox(geom) )
430  PG_RETURN_POINTER(geom);
431 
432  PG_RETURN_POINTER(gserialized_drop_gidx(geom));
433 }
434 
435 
436 /* for the wkt parser */
437 void elog_ERROR(const char* string)
438 {
439  elog(ERROR, "%s", string);
440 }
441 
442 /*
443 * This just does the same thing as the _in function,
444 * except it has to handle a 'text' input. First
445 * unwrap the text into a cstring, then call
446 * geometry_in
447 */
449 Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS)
450 {
451  text *wkt_text = PG_GETARG_TEXT_P(0);
452  char *wkt;
453  Datum result;
454 
455  /* Unwrap the PgSQL text type into a cstring */
456  wkt = text2cstring(wkt_text);
457 
458  /* Now we call over to the geometry_in function */
459  result = DirectFunctionCall1(LWGEOM_in, CStringGetDatum(wkt));
460 
461  /* Return null on null */
462  if ( ! result )
463  PG_RETURN_NULL();
464 
465  PG_RETURN_DATUM(result);
466 }
467 
468 
469 /*
470  * This function must advance the StringInfo.cursor pointer
471  * and leave it at the end of StringInfo.buf. If it fails
472  * to do so the backend will raise an exception with message:
473  * ERROR: incorrect binary data format in bind parameter #
474  *
475  */
477 Datum LWGEOM_recv(PG_FUNCTION_ARGS)
478 {
479  StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
480  int32 geom_typmod = -1;
481  GSERIALIZED *geom;
482  LWGEOM *lwgeom;
483 
484  if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
485  geom_typmod = PG_GETARG_INT32(2);
486  }
487 
488  lwgeom = lwgeom_from_wkb((uint8_t*)buf->data, buf->len, LW_PARSER_CHECK_ALL);
489 
490  if ( lwgeom_needs_bbox(lwgeom) )
491  lwgeom_add_bbox(lwgeom);
492 
493  /* Set cursor to the end of buffer (so the backend is happy) */
494  buf->cursor = buf->len;
495 
496  geom = geometry_serialize(lwgeom);
497  lwgeom_free(lwgeom);
498 
499  if ( geom_typmod >= 0 )
500  {
501  geom = postgis_valid_typmod(geom, geom_typmod);
502  POSTGIS_DEBUG(3, "typmod and geometry were consistent");
503  }
504  else
505  {
506  POSTGIS_DEBUG(3, "typmod was -1");
507  }
508 
509 
510  PG_RETURN_POINTER(geom);
511 }
512 
513 
514 
516 Datum LWGEOM_send(PG_FUNCTION_ARGS)
517 {
518  POSTGIS_DEBUG(2, "LWGEOM_send called");
519 
520  PG_RETURN_POINTER(
521  DatumGetPointer(
522  DirectFunctionCall1(
523  WKBFromLWGEOM,
524  PG_GETARG_DATUM(0)
525  )));
526 }
527 
529 Datum LWGEOM_to_bytea(PG_FUNCTION_ARGS)
530 {
531  POSTGIS_DEBUG(2, "LWGEOM_to_bytea called");
532 
533  PG_RETURN_POINTER(
534  DatumGetPointer(
535  DirectFunctionCall1(
536  WKBFromLWGEOM,
537  PG_GETARG_DATUM(0)
538  )));
539 }
540 
542 Datum LWGEOM_from_bytea(PG_FUNCTION_ARGS)
543 {
545 
546  POSTGIS_DEBUG(2, "LWGEOM_from_bytea start");
547 
548  result = (GSERIALIZED *)DatumGetPointer(DirectFunctionCall1(
549  LWGEOMFromWKB, PG_GETARG_DATUM(0)));
550 
551  PG_RETURN_POINTER(result);
552 }
553 
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:56
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Definition: lwout_wkb.c:776
Datum LWGEOM_to_bytea(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:529
Datum LWGEOM_to_latlon(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:162
GSERIALIZED * postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod)
Check the consistency of the metadata we want to enforce in the typmod: srid, type and dimensionality...
Datum LWGEOM_recv(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:477
#define WKB_NDR
Definition: liblwgeom.h:1770
uint8_t * bytes_from_hexbytes(const char *hexbuf, size_t hexsize)
Definition: lwin_wkb.c:69
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:250
char * lwpoint_to_latlon(const LWPOINT *p, const char *format)
Definition: lwprint.c:391
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1006
Datum LWGEOM_to_text(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:303
Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:333
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:825
int gserialized_has_bbox(const GSERIALIZED *gser)
Check if a GSERIALIZED has a bounding box without deserializing first.
Definition: g_serialized.c:20
static int input(void)
char ** result
Definition: liblwgeom.h:218
#define LW_FAILURE
Definition: liblwgeom.h:54
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:1706
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:164
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
Definition: lwout_wkb.c:692
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
Datum LWGEOM_out(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:232
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM...
Definition: liblwgeom.h:1713
char * text2cstring(const text *textptr)
Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:363
#define WKB_EXTENDED
Definition: liblwgeom.h:1769
Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:408
PG_FUNCTION_INFO_V1(LWGEOM_in)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:819
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition: lwgeom.c:555
void elog_ERROR(const char *string)
Definition: lwgeom_inout.c:437
#define WKB_XDR
Definition: liblwgeom.h:1771
Datum LWGEOM_in(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:48
void lwgeom_set_srid(LWGEOM *geom, int srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:449
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:1707
LWGEOM * lwgeom_from_wkb(const uint8_t *wkb, const size_t wkb_size, const char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
Definition: lwin_wkb.c:728
Datum LWGEOM_from_bytea(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:542
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
Definition: lwgeom.c:1059
Datum LWGEOM_dropBBOX(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:424
Datum LWGEOM_send(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:516
This library is the generic geometry handling section of PostGIS.