PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ LWGEOM_in()

Datum LWGEOM_in ( PG_FUNCTION_ARGS  )

Definition at line 85 of file lwgeom_inout.c.

86 {
87  char *input = PG_GETARG_CSTRING(0);
88  int32 geom_typmod = -1;
89  char *str = input;
90  LWGEOM_PARSER_RESULT lwg_parser_result;
91  LWGEOM *lwgeom;
92  GSERIALIZED *ret;
93  int32_t srid = 0;
94 
95  if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
96  geom_typmod = PG_GETARG_INT32(2);
97  }
98 
99  lwgeom_parser_result_init(&lwg_parser_result);
100 
101  /* Empty string. */
102  if ( str[0] == '\0' ) {
103  ereport(ERROR,(errmsg("parse error - invalid geometry")));
104  PG_RETURN_NULL();
105  }
106 
107  /* Starts with "SRID=" */
108  if( strncasecmp(str,"SRID=",5) == 0 )
109  {
110  /* Roll forward to semi-colon */
111  char *tmp = str;
112  while ( tmp && *tmp != ';' )
113  tmp++;
114 
115  /* Check next character to see if we have WKB */
116  if ( tmp && *(tmp+1) == '0' )
117  {
118  /* Null terminate the SRID= string */
119  *tmp = '\0';
120  /* Set str to the start of the real WKB */
121  str = tmp + 1;
122  /* Move tmp to the start of the numeric part */
123  tmp = input + 5;
124  /* Parse out the SRID number */
125  srid = atoi(tmp);
126  }
127  }
128 
129  /* WKB? Let's find out. */
130  if ( str[0] == '0' )
131  {
132  size_t hexsize = strlen(str);
133  unsigned char *wkb = bytes_from_hexbytes(str, hexsize);
134  /* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */
135  lwgeom = lwgeom_from_wkb(wkb, hexsize/2, LW_PARSER_CHECK_NONE);
136  /* Parser should throw error, but if not, catch here. */
137  if ( !lwgeom ) PG_RETURN_NULL();
138  /* If we picked up an SRID at the head of the WKB set it manually */
139  if ( srid ) lwgeom_set_srid(lwgeom, srid);
140  /* Add a bbox if necessary */
141  if ( lwgeom_needs_bbox(lwgeom) ) lwgeom_add_bbox(lwgeom);
142  lwfree(wkb);
143  ret = geometry_serialize(lwgeom);
144  lwgeom_free(lwgeom);
145  }
146  else if (str[0] == '{')
147  {
148  char *srs = NULL;
149  lwgeom = lwgeom_from_geojson(str, &srs);
150  if (srs)
151  {
152  srid = GetSRIDCacheBySRS(fcinfo, srs);
153  lwfree(srs);
154  lwgeom_set_srid(lwgeom, srid);
155  }
156  ret = geometry_serialize(lwgeom);
157  lwgeom_free(lwgeom);
158  }
159  /* WKT then. */
160  else
161  {
162  if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE )
163  {
164  PG_PARSER_ERROR(lwg_parser_result);
165  PG_RETURN_NULL();
166  }
167  lwgeom = lwg_parser_result.geom;
168  if ( lwgeom_needs_bbox(lwgeom) )
169  lwgeom_add_bbox(lwgeom);
170  ret = geometry_serialize(lwgeom);
171  lwgeom_parser_result_free(&lwg_parser_result);
172  }
173 
174  if ( geom_typmod >= 0 )
175  {
176  ret = postgis_valid_typmod(ret, geom_typmod);
177  POSTGIS_DEBUG(3, "typmod and geometry were consistent");
178  }
179  else
180  {
181  POSTGIS_DEBUG(3, "typmod was -1");
182  }
183 
184  /* Don't free the parser result (and hence lwgeom) until we have done */
185  /* the typemod check with lwgeom */
186 
187  PG_RETURN_POINTER(ret);
188 
189 }
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...
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:2147
LWGEOM * lwgeom_from_geojson(const char *geojson, char **srs)
Create an LWGEOM object from a GeoJSON representation.
Definition: lwin_geojson.c:411
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
Definition: lwgeom.c:1610
#define LW_FAILURE
Definition: liblwgeom.h:96
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2146
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:915
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
uint8_t * bytes_from_hexbytes(const char *hexbuf, size_t hexsize)
Definition: lwin_wkb.c:92
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
Definition: lwgeom.c:1271
void lwfree(void *mem)
Definition: lwutil.c:248
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:842
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition: lwgeom.c:695
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:921
#define str(s)
unsigned int int32
Definition: shpopen.c:54
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition: liblwgeom.h:2154

References bytes_from_hexbytes(), struct_lwgeom_parser_result::geom, LW_FAILURE, LW_PARSER_CHECK_ALL, LW_PARSER_CHECK_NONE, lwfree(), lwgeom_add_bbox(), lwgeom_free(), lwgeom_from_geojson(), lwgeom_from_wkb(), lwgeom_needs_bbox(), lwgeom_parse_wkt(), lwgeom_parser_result_free(), lwgeom_parser_result_init(), lwgeom_set_srid(), postgis_valid_typmod(), and str.

Referenced by parse_WKT_lwgeom().

Here is the call graph for this function:
Here is the caller graph for this function: