PostGIS  2.2.7dev-r@@SVN_REVISION@@
geography_inout.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * Copyright 2009-2011 Paul Ramsey <pramsey@cleverelephant.ca>
5  *
6  * This is free software; you can redistribute and/or modify it under
7  * the terms of the GNU General Public Licence. See the COPYING file.
8  *
9  **********************************************************************/
10 
11 #include "postgres.h"
12 
13 #include "../postgis_config.h"
14 
15 #include <math.h>
16 #include <float.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <errno.h>
20 
21 #include "utils/elog.h"
22 #include "utils/array.h"
23 #include "utils/builtins.h" /* for pg_atoi */
24 #include "lib/stringinfo.h" /* For binary input */
25 #include "catalog/pg_type.h" /* for CSTRINGOID */
26 
27 #include "liblwgeom.h" /* For standard geometry types. */
28 #include "lwgeom_pg.h" /* For debugging macros. */
29 #include "geography.h" /* For utility functions. */
30 #include "lwgeom_export.h" /* For export functions. */
31 #include "lwgeom_transform.h"
32 
33 Datum geography_in(PG_FUNCTION_ARGS);
34 Datum geography_out(PG_FUNCTION_ARGS);
35 
36 Datum geography_as_text(PG_FUNCTION_ARGS);
37 Datum geography_from_text(PG_FUNCTION_ARGS);
38 Datum geography_as_geojson(PG_FUNCTION_ARGS);
39 Datum geography_as_gml(PG_FUNCTION_ARGS);
40 Datum geography_as_kml(PG_FUNCTION_ARGS);
41 Datum geography_as_svg(PG_FUNCTION_ARGS);
42 Datum geography_from_binary(PG_FUNCTION_ARGS);
43 Datum geography_from_geometry(PG_FUNCTION_ARGS);
44 Datum geometry_from_geography(PG_FUNCTION_ARGS);
45 Datum geography_send(PG_FUNCTION_ARGS);
46 Datum geography_recv(PG_FUNCTION_ARGS);
47 
49 
56 {
57  if ( ! (
58  type == POINTTYPE ||
59  type == LINETYPE ||
60  type == POLYGONTYPE ||
61  type == MULTIPOINTTYPE ||
62  type == MULTILINETYPE ||
63  type == MULTIPOLYGONTYPE ||
64  type == COLLECTIONTYPE
65  ) )
66  {
67  ereport(ERROR, (
68  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
69  errmsg("Geography type does not support %s", lwtype_name(type) )));
70 
71  }
72 }
73 
75 {
76  GSERIALIZED *g_ser = NULL;
77 
78  /* Set geodetic flag */
79  lwgeom_set_geodetic(lwgeom, true);
80 
81  /* Check that this is a type we can handle */
82  geography_valid_type(lwgeom->type);
83 
84  /* Force the geometry to have valid geodetic coordinate range. */
85  lwgeom_nudge_geodetic(lwgeom);
86  if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE )
87  {
88  ereport(NOTICE, (
89  errmsg_internal("Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
90  );
91  }
92 
93  /* Force default SRID to the default */
94  if ( (int)lwgeom->srid <= 0 )
95  lwgeom->srid = SRID_DEFAULT;
96 
97  /*
98  ** Serialize our lwgeom and set the geodetic flag so subsequent
99  ** functions do the right thing.
100  */
101  g_ser = geography_serialize(lwgeom);
102 
103  /* Check for typmod agreement */
104  if ( geog_typmod >= 0 )
105  {
106  g_ser = postgis_valid_typmod(g_ser, geog_typmod);
107  POSTGIS_DEBUG(3, "typmod and geometry were consistent");
108  }
109  else
110  {
111  POSTGIS_DEBUG(3, "typmod was -1");
112  }
113 
114  return g_ser;
115 }
116 
117 
118 /*
119 ** geography_in(cstring) returns *GSERIALIZED
120 */
122 Datum geography_in(PG_FUNCTION_ARGS)
123 {
124  char *str = PG_GETARG_CSTRING(0);
125  /* Datum geog_oid = PG_GETARG_OID(1); Not needed. */
126  int32 geog_typmod = -1;
127  LWGEOM_PARSER_RESULT lwg_parser_result;
128  LWGEOM *lwgeom = NULL;
129  GSERIALIZED *g_ser = NULL;
130 
131  if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
132  geog_typmod = PG_GETARG_INT32(2);
133  }
134 
135  lwgeom_parser_result_init(&lwg_parser_result);
136 
137  /* Empty string. */
138  if ( str[0] == '\0' )
139  ereport(ERROR,(errmsg("parse error - invalid geometry")));
140 
141  /* WKB? Let's find out. */
142  if ( str[0] == '0' )
143  {
144  /* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */
146  /* Error out if something went sideways */
147  if ( ! lwgeom )
148  ereport(ERROR,(errmsg("parse error - invalid geometry")));
149  }
150  /* WKT then. */
151  else
152  {
153  if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE )
154  PG_PARSER_ERROR(lwg_parser_result);
155 
156  lwgeom = lwg_parser_result.geom;
157  }
158 
159  /* Error on any SRID != default */
160  srid_is_latlong(fcinfo, lwgeom->srid);
161 
162  /* Convert to gserialized */
163  g_ser = gserialized_geography_from_lwgeom(lwgeom, geog_typmod);
164 
165  /* Clean up temporary object */
166  lwgeom_free(lwgeom);
167 
168 
169  PG_RETURN_POINTER(g_ser);
170 }
171 
172 /*
173 ** geography_out(*GSERIALIZED) returns cstring
174 */
176 Datum geography_out(PG_FUNCTION_ARGS)
177 {
178  LWGEOM *lwgeom = NULL;
179  GSERIALIZED *g = NULL;
180  char *hexwkb;
181 
182  g = PG_GETARG_GSERIALIZED_P(0);
183  lwgeom = lwgeom_from_gserialized(g);
184  hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, 0);
185  lwgeom_free(lwgeom);
186 
187  PG_RETURN_CSTRING(hexwkb);
188 }
189 
190 
191 /*
192 ** geography_as_gml(*GSERIALIZED) returns text
193 */
195 Datum geography_as_gml(PG_FUNCTION_ARGS)
196 {
197  LWGEOM *lwgeom = NULL;
198  GSERIALIZED *g = NULL;
199  char *gml;
200  text *result;
201  int version;
202  char *srs;
203  int srid = SRID_DEFAULT;
204  int precision = DBL_DIG;
205  int option=0;
206  int lwopts = LW_GML_IS_DIMS;
207  static const char *default_prefix = "gml:";
208  const char *prefix = default_prefix;
209  char *prefix_buf = "";
210  text *prefix_text, *id_text = NULL;
211  const char *id=NULL;
212  char *id_buf;
213 
214 
215  /* Get the version */
216  version = PG_GETARG_INT32(0);
217  if ( version != 2 && version != 3 )
218  {
219  elog(ERROR, "Only GML 2 and GML 3 are supported");
220  PG_RETURN_NULL();
221  }
222 
223  /* Get the geography */
224  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
225  g = PG_GETARG_GSERIALIZED_P(1);
226 
227  /* Convert to lwgeom so we can run the old functions */
228  lwgeom = lwgeom_from_gserialized(g);
229 
230  /* Retrieve precision if any (default is max) */
231  if (PG_NARGS() >2 && !PG_ARGISNULL(2))
232  {
233  precision = PG_GETARG_INT32(2);
234  /* TODO: leave this to liblwgeom */
235  if ( precision > DBL_DIG )
236  precision = DBL_DIG;
237  else if ( precision < 0 ) precision = 0;
238  }
239 
240  /* retrieve option */
241  if (PG_NARGS() >3 && !PG_ARGISNULL(3))
242  option = PG_GETARG_INT32(3);
243 
244 
245  /* retrieve prefix */
246  if (PG_NARGS() >4 && !PG_ARGISNULL(4))
247  {
248  prefix_text = PG_GETARG_TEXT_P(4);
249  if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
250  {
251  prefix = "";
252  }
253  else
254  {
255  /* +2 is one for the ':' and one for term null */
256  prefix_buf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
257  memcpy(prefix_buf, VARDATA(prefix_text),
258  VARSIZE(prefix_text)-VARHDRSZ);
259  /* add colon and null terminate */
260  prefix_buf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
261  prefix_buf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
262  prefix = prefix_buf;
263  }
264  }
265 
266  /* retrieve id */
267  if (PG_NARGS() >5 && !PG_ARGISNULL(5))
268  {
269  id_text = PG_GETARG_TEXT_P(5);
270  if ( VARSIZE(id_text)-VARHDRSZ == 0 )
271  {
272  id = "";
273  }
274  else
275  {
276  id_buf = palloc(VARSIZE(id_text)-VARHDRSZ+1);
277  memcpy(id_buf, VARDATA(id_text), VARSIZE(id_text)-VARHDRSZ);
278  prefix_buf[VARSIZE(id_text)-VARHDRSZ+1] = '\0';
279  id = id_buf;
280  }
281  }
282 
283  if (option & 1) srs = getSRSbySRID(srid, false);
284  else srs = getSRSbySRID(srid, true);
285  if (!srs)
286  {
287  elog(ERROR, "SRID %d unknown in spatial_ref_sys table", SRID_DEFAULT);
288  PG_RETURN_NULL();
289  }
290 
291  /* Revert lat/lon only with long SRS */
292  if (option & 1) lwopts |= LW_GML_IS_DEGREE;
293  if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
294 
295  if (version == 2)
296  gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
297  else
298  gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id);
299 
300  lwgeom_free(lwgeom);
301  PG_FREE_IF_COPY(g, 1);
302 
303  /* Return null on null */
304  if ( ! gml )
305  PG_RETURN_NULL();
306 
307  /* Turn string result into text for return */
308  result = cstring2text(gml);
309  lwfree(gml);
310 
311  PG_RETURN_TEXT_P(result);
312 }
313 
314 
315 /*
316 ** geography_as_kml(*GSERIALIZED) returns text
317 */
319 Datum geography_as_kml(PG_FUNCTION_ARGS)
320 {
321  GSERIALIZED *g = NULL;
322  LWGEOM *lwgeom = NULL;
323  char *kml;
324  text *result;
325  int version;
326  int precision = DBL_DIG;
327  static const char *default_prefix = "";
328  char *prefixbuf;
329  const char* prefix = default_prefix;
330  text *prefix_text;
331 
332 
333  /* Get the version */
334  version = PG_GETARG_INT32(0);
335  if ( version != 2)
336  {
337  elog(ERROR, "Only KML 2 is supported");
338  PG_RETURN_NULL();
339  }
340 
341  /* Get the geometry */
342  if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
343  g = PG_GETARG_GSERIALIZED_P(1);
344 
345  /* Convert to lwgeom so we can run the old functions */
346  lwgeom = lwgeom_from_gserialized(g);
347 
348  /* Retrieve precision if any (default is max) */
349  if (PG_NARGS() >2 && !PG_ARGISNULL(2))
350  {
351  precision = PG_GETARG_INT32(2);
352  /* TODO: leave this to liblwgeom */
353  if ( precision > DBL_DIG )
354  precision = DBL_DIG;
355  else if ( precision < 0 ) precision = 0;
356  }
357 
358  /* retrieve prefix */
359  if (PG_NARGS() >3 && !PG_ARGISNULL(3))
360  {
361  prefix_text = PG_GETARG_TEXT_P(3);
362  if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
363  {
364  prefix = "";
365  }
366  else
367  {
368  /* +2 is one for the ':' and one for term null */
369  prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
370  memcpy(prefixbuf, VARDATA(prefix_text),
371  VARSIZE(prefix_text)-VARHDRSZ);
372  /* add colon and null terminate */
373  prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
374  prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
375  prefix = prefixbuf;
376  }
377  }
378 
379  kml = lwgeom_to_kml2(lwgeom, precision, prefix);
380 
381  lwgeom_free(lwgeom);
382  PG_FREE_IF_COPY(g, 1);
383 
384  if ( ! kml )
385  PG_RETURN_NULL();
386 
387  result = cstring2text(kml);
388  lwfree(kml);
389 
390  PG_RETURN_TEXT_P(result);
391 }
392 
393 
394 /*
395 ** geography_as_svg(*GSERIALIZED) returns text
396 */
398 Datum geography_as_svg(PG_FUNCTION_ARGS)
399 {
400  GSERIALIZED *g = NULL;
401  LWGEOM *lwgeom = NULL;
402  char *svg;
403  text *result;
404  int relative = 0;
405  int precision=DBL_DIG;
406 
407  if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
408 
409  g = PG_GETARG_GSERIALIZED_P(0);
410 
411  /* Convert to lwgeom so we can run the old functions */
412  lwgeom = lwgeom_from_gserialized(g);
413 
414  /* check for relative path notation */
415  if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
416  relative = PG_GETARG_INT32(1) ? 1:0;
417 
418  if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
419  {
420  precision = PG_GETARG_INT32(2);
421  /* TODO: leave this to liblwgeom */
422  if ( precision > DBL_DIG )
423  precision = DBL_DIG;
424  else if ( precision < 0 ) precision = 0;
425  }
426 
427  svg = lwgeom_to_svg(lwgeom, precision, relative);
428 
429  lwgeom_free(lwgeom);
430  PG_FREE_IF_COPY(g, 0);
431 
432  result = cstring2text(svg);
433  lwfree(svg);
434 
435  PG_RETURN_TEXT_P(result);
436 }
437 
438 
439 /*
440 ** geography_as_geojson(*GSERIALIZED) returns text
441 */
443 Datum geography_as_geojson(PG_FUNCTION_ARGS)
444 {
445  LWGEOM *lwgeom = NULL;
446  GSERIALIZED *g = NULL;
447  char *geojson;
448  text *result;
449  int version;
450  int option = 0;
451  int has_bbox = 0;
452  int precision = DBL_DIG;
453  char * srs = NULL;
454 
455  /* Get the version */
456  version = PG_GETARG_INT32(0);
457  if ( version != 1)
458  {
459  elog(ERROR, "Only GeoJSON 1 is supported");
460  PG_RETURN_NULL();
461  }
462 
463  /* Get the geography */
464  if (PG_ARGISNULL(1) ) PG_RETURN_NULL();
465  g = PG_GETARG_GSERIALIZED_P(1);
466 
467  /* Convert to lwgeom so we can run the old functions */
468  lwgeom = lwgeom_from_gserialized(g);
469 
470  /* Retrieve precision if any (default is max) */
471  if (PG_NARGS() >2 && !PG_ARGISNULL(2))
472  {
473  precision = PG_GETARG_INT32(2);
474  /* TODO: leave this to liblwgeom */
475  if ( precision > DBL_DIG )
476  precision = DBL_DIG;
477  else if ( precision < 0 ) precision = 0;
478  }
479 
480  /* Retrieve output option
481  * 0 = without option (default)
482  * 1 = bbox
483  * 2 = short crs
484  * 4 = long crs
485  */
486  if (PG_NARGS() >3 && !PG_ARGISNULL(3))
487  option = PG_GETARG_INT32(3);
488 
489  if (option & 2 || option & 4)
490  {
491  /* Geography only handle srid SRID_DEFAULT */
492  if (option & 2) srs = getSRSbySRID(SRID_DEFAULT, true);
493  if (option & 4) srs = getSRSbySRID(SRID_DEFAULT, false);
494 
495  if (!srs)
496  {
497  elog(ERROR, "SRID SRID_DEFAULT unknown in spatial_ref_sys table");
498  PG_RETURN_NULL();
499  }
500  }
501 
502  if (option & 1) has_bbox = 1;
503 
504  geojson = lwgeom_to_geojson(lwgeom, srs, precision, has_bbox);
505  lwgeom_free(lwgeom);
506  PG_FREE_IF_COPY(g, 1);
507  if (srs) pfree(srs);
508 
509  result = cstring2text(geojson);
510  lwfree(geojson);
511 
512  PG_RETURN_TEXT_P(result);
513 }
514 
515 
516 /*
517 ** geography_from_text(*char) returns *GSERIALIZED
518 **
519 ** Convert text (varlena) to cstring and then call geography_in().
520 */
522 Datum geography_from_text(PG_FUNCTION_ARGS)
523 {
524  LWGEOM_PARSER_RESULT lwg_parser_result;
525  GSERIALIZED *g_ser = NULL;
526  text *wkt_text = PG_GETARG_TEXT_P(0);
527 
528  /* Extract the cstring from the varlena */
529  char *wkt = text2cstring(wkt_text);
530 
531  /* Pass the cstring to the input parser, and magic occurs! */
532  if ( lwgeom_parse_wkt(&lwg_parser_result, wkt, LW_PARSER_CHECK_ALL) == LW_FAILURE )
533  PG_PARSER_ERROR(lwg_parser_result);
534 
535  /* Error on any SRID != default */
536  srid_is_latlong(fcinfo, lwg_parser_result.geom->srid);
537 
538  /* Clean up string */
539  pfree(wkt);
540  g_ser = gserialized_geography_from_lwgeom(lwg_parser_result.geom, -1);
541 
542  /* Clean up temporary object */
543  lwgeom_free(lwg_parser_result.geom);
544 
545  PG_RETURN_POINTER(g_ser);
546 }
547 
548 /*
549 ** geography_from_binary(*char) returns *GSERIALIZED
550 */
552 Datum geography_from_binary(PG_FUNCTION_ARGS)
553 {
554  char *wkb_bytea = (char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
555  GSERIALIZED *gser = NULL;
556  size_t wkb_size = VARSIZE(wkb_bytea);
557  uint8_t *wkb = (uint8_t*)VARDATA(wkb_bytea);
558  LWGEOM *lwgeom = lwgeom_from_wkb(wkb, wkb_size, LW_PARSER_CHECK_NONE);
559 
560  if ( ! lwgeom )
561  lwpgerror("Unable to parse WKB");
562 
563  /* Error on any SRID != default */
564  srid_is_latlong(fcinfo, lwgeom->srid);
565 
566  gser = gserialized_geography_from_lwgeom(lwgeom, -1);
567  lwgeom_free(lwgeom);
568  PG_RETURN_POINTER(gser);
569 }
570 
571 
573 Datum geography_from_geometry(PG_FUNCTION_ARGS)
574 {
575  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
576  LWGEOM *lwgeom = NULL;
577  GSERIALIZED *g_ser = NULL;
578 
580 
581  lwgeom = lwgeom_from_gserialized(geom);
582 
583  /* Force default SRID */
584  if ( (int)lwgeom->srid <= 0 )
585  {
586  lwgeom->srid = SRID_DEFAULT;
587  }
588 
589  /* Error on any SRID != default */
590  srid_is_latlong(fcinfo, lwgeom->srid);
591 
592  /* Force the geometry to have valid geodetic coordinate range. */
593  lwgeom_nudge_geodetic(lwgeom);
594  if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE )
595  {
596  ereport(NOTICE, (
597  errmsg_internal("Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
598  );
599  }
600 
601  /*
602  ** Serialize our lwgeom and set the geodetic flag so subsequent
603  ** functions do the right thing.
604  */
605  lwgeom_set_geodetic(lwgeom, true);
606 
607  /* Recalculate the boxes after re-setting the geodetic bit */
608  lwgeom_drop_bbox(lwgeom);
609  lwgeom_add_bbox(lwgeom);
610 
611  g_ser = geography_serialize(lwgeom);
612 
613  /*
614  ** Replace the unaligned lwgeom with a new aligned one based on GSERIALIZED.
615  */
616  lwgeom_free(lwgeom);
617 
618  PG_FREE_IF_COPY(geom, 0);
619  PG_RETURN_POINTER(g_ser);
620 
621 }
622 
624 Datum geometry_from_geography(PG_FUNCTION_ARGS)
625 {
626  LWGEOM *lwgeom = NULL;
627  GSERIALIZED *ret = NULL;
628  GSERIALIZED *g_ser = PG_GETARG_GSERIALIZED_P(0);
629 
630  lwgeom = lwgeom_from_gserialized(g_ser);
631 
632  /* Recalculate the boxes after re-setting the geodetic bit */
633  lwgeom_set_geodetic(lwgeom, false);
634  lwgeom_drop_bbox(lwgeom);
635  lwgeom_add_bbox(lwgeom);
636 
637  /* We want "geometry" to think all our "geography" has an SRID, and the
638  implied SRID is the default, so we fill that in if our SRID is actually unknown. */
639  if ( (int)lwgeom->srid <= 0 )
640  lwgeom->srid = SRID_DEFAULT;
641 
642  ret = geometry_serialize(lwgeom);
643  lwgeom_free(lwgeom);
644 
645  PG_RETURN_POINTER(ret);
646 }
647 
649 Datum geography_recv(PG_FUNCTION_ARGS)
650 {
651  StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
652  int32 geog_typmod = -1;
653  LWGEOM *lwgeom = NULL;
654  GSERIALIZED *g_ser = NULL;
655 
656  if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
657  geog_typmod = PG_GETARG_INT32(2);
658  }
659 
660  lwgeom = lwgeom_from_wkb((uint8_t*)buf->data, buf->len, LW_PARSER_CHECK_ALL);
661 
662  /* Error on any SRID != default */
663  srid_is_latlong(fcinfo, lwgeom->srid);
664 
665  g_ser = gserialized_geography_from_lwgeom(lwgeom, geog_typmod);
666 
667  /* Clean up temporary object */
668  lwgeom_free(lwgeom);
669 
670  /* Set cursor to the end of buffer (so the backend is happy) */
671  buf->cursor = buf->len;
672 
673  PG_RETURN_POINTER(g_ser);
674 }
675 
676 
678 Datum geography_send(PG_FUNCTION_ARGS)
679 {
680  LWGEOM *lwgeom = NULL;
681  GSERIALIZED *g = NULL;
682  size_t size_result;
683  uint8_t *wkb;
684  bytea *result;
685 
686  g = PG_GETARG_GSERIALIZED_P(0);
687  lwgeom = lwgeom_from_gserialized(g);
688  wkb = lwgeom_to_wkb(lwgeom, WKB_EXTENDED, &size_result);
689  lwgeom_free(lwgeom);
690 
691  result = palloc(size_result + VARHDRSZ);
692  SET_VARSIZE(result, size_result + VARHDRSZ);
693  memcpy(VARDATA(result), wkb, size_result);
694  pfree(wkb);
695 
696  PG_RETURN_POINTER(result);
697 }
#define LINETYPE
Definition: liblwgeom.h:71
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:55
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Definition: lwout_wkb.c:834
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:218
unsigned int int32
Definition: shpopen.c:273
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...
void lwfree(void *mem)
Definition: lwutil.c:214
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
char * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
Definition: lwout_svg.c:42
#define POLYGONTYPE
Definition: liblwgeom.h:72
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
#define MULTIPOINTTYPE
Definition: liblwgeom.h:73
#define SRID_DEFAULT
Definition: liblwgeom.h:179
Datum geography_as_geojson(PG_FUNCTION_ARGS)
Datum geography_recv(PG_FUNCTION_ARGS)
int lwgeom_nudge_geodetic(LWGEOM *geom)
Gently move coordinates of LWGEOM if they are close enough into geodetic range.
Definition: lwgeodetic.c:2991
PG_FUNCTION_INFO_V1(geography_in)
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:586
int32_t srid
Definition: liblwgeom.h:383
#define LW_FAILURE
Definition: liblwgeom.h:64
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:1869
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:188
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:750
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM...
Definition: liblwgeom.h:1876
int lwgeom_force_geodetic(LWGEOM *geom)
Force coordinates of LWGEOM into geodetic range (-180, -90, 180, 90)
Definition: lwgeodetic.c:2809
Datum geography_in(PG_FUNCTION_ARGS)
Datum geography_as_text(PG_FUNCTION_ARGS)
char * text2cstring(const text *textptr)
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:34
uint8_t precision
Definition: cu_in_twkb.c:25
Datum geography_as_gml(PG_FUNCTION_ARGS)
Datum geometry_from_geography(PG_FUNCTION_ARGS)
Datum geography_as_svg(PG_FUNCTION_ARGS)
#define WKB_EXTENDED
Definition: liblwgeom.h:1932
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
Definition: lwgeom.c:858
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
Definition: lwin_wkb.c:779
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:75
char * getSRSbySRID(int srid, bool short_crs)
Definition: lwgeom_export.c:40
Datum geography_from_geometry(PG_FUNCTION_ARGS)
#define LW_GML_IS_DIMS
Macros for specifying GML options.
Definition: liblwgeom.h:1469
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum geography_out(PG_FUNCTION_ARGS)
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:865
void geography_valid_type(uint8_t type)
The geography type only support POINT, LINESTRING, POLYGON, MULTI* variants of same, and GEOMETRYCOLLECTION.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:70
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition: lwgeom.c:599
Datum geography_from_text(PG_FUNCTION_ARGS)
Datum geography_send(PG_FUNCTION_ARGS)
uint8_t type
Definition: liblwgeom.h:380
GSERIALIZED * gserialized_geography_from_lwgeom(LWGEOM *lwgeom, int32 geog_typmod)
Datum geography_from_binary(PG_FUNCTION_ARGS)
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition: lwout_gml.c:723
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:1870
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:754
#define MULTILINETYPE
Definition: liblwgeom.h:74
#define COLLECTIONTYPE
Definition: liblwgeom.h:76
This library is the generic geometry handling section of PostGIS.
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
Definition: lwout_kml.c:31
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
Definition: liblwgeom.h:1471
Datum geography_as_kml(PG_FUNCTION_ARGS)