28 #include "../postgis_config.h"
36 #include "utils/elog.h"
37 #include "utils/array.h"
38 #include "utils/builtins.h"
39 #include "lib/stringinfo.h"
40 #include "catalog/pg_type.h"
43 #include "lwgeom_pg.h"
46 #include "lwgeom_transform.h"
83 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
104 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
109 if ( (
int)lwgeom->
srid <= 0 )
116 g_ser = geography_serialize(lwgeom);
119 if ( geog_typmod >= 0 )
122 POSTGIS_DEBUG(3,
"typmod and geometry were consistent");
126 POSTGIS_DEBUG(3,
"typmod was -1");
139 char *str = PG_GETARG_CSTRING(0);
141 int32 geog_typmod = -1;
146 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
147 geog_typmod = PG_GETARG_INT32(2);
153 if ( str[0] ==
'\0' )
154 ereport(ERROR,(errmsg(
"parse error - invalid geometry")));
163 ereport(ERROR,(errmsg(
"parse error - invalid geometry")));
169 PG_PARSER_ERROR(lwg_parser_result);
171 lwgeom = lwg_parser_result.
geom;
175 srid_is_latlong(fcinfo, lwgeom->
srid);
184 PG_RETURN_POINTER(g_ser);
197 g = PG_GETARG_GSERIALIZED_P(0);
202 PG_RETURN_CSTRING(hexwkb);
222 static const char *default_prefix =
"gml:";
223 const char *prefix = default_prefix;
224 char *prefix_buf =
"";
225 text *prefix_text, *id_text = NULL;
231 version = PG_GETARG_INT32(0);
232 if ( version != 2 && version != 3 )
234 elog(ERROR,
"Only GML 2 and GML 3 are supported");
239 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
240 g = PG_GETARG_GSERIALIZED_P(1);
246 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
256 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
257 option = PG_GETARG_INT32(3);
261 if (PG_NARGS() >4 && !PG_ARGISNULL(4))
263 prefix_text = PG_GETARG_TEXT_P(4);
264 if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
271 prefix_buf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
272 memcpy(prefix_buf, VARDATA(prefix_text),
273 VARSIZE(prefix_text)-VARHDRSZ);
275 prefix_buf[VARSIZE(prefix_text)-VARHDRSZ] =
':';
276 prefix_buf[VARSIZE(prefix_text)-VARHDRSZ+1] =
'\0';
282 if (PG_NARGS() >5 && !PG_ARGISNULL(5))
284 id_text = PG_GETARG_TEXT_P(5);
285 if ( VARSIZE(id_text)-VARHDRSZ == 0 )
291 id_buf = palloc(VARSIZE(id_text)-VARHDRSZ+1);
292 memcpy(id_buf, VARDATA(id_text), VARSIZE(id_text)-VARHDRSZ);
293 prefix_buf[VARSIZE(id_text)-VARHDRSZ+1] =
'\0';
304 elog(ERROR,
"SRID %d unknown in spatial_ref_sys table",
SRID_DEFAULT);
314 "Options %d passed to ST_AsGML(geography) sets "
315 "unsupported value 8",
319 if ((option & 4) || (option & 16) || (option & 32))
322 "Options %d passed to ST_AsGML(geography) but are only "
323 "applicable to ST_AsGML(geometry)",
334 PG_FREE_IF_COPY(g, 1);
341 result = cstring_to_text(gml);
344 PG_RETURN_TEXT_P(result);
360 static const char *default_prefix =
"";
362 const char* prefix = default_prefix;
367 version = PG_GETARG_INT32(0);
370 elog(ERROR,
"Only KML 2 is supported");
375 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
376 g = PG_GETARG_GSERIALIZED_P(1);
382 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
392 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
394 prefix_text = PG_GETARG_TEXT_P(3);
395 if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
402 prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
403 memcpy(prefixbuf, VARDATA(prefix_text),
404 VARSIZE(prefix_text)-VARHDRSZ);
406 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] =
':';
407 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] =
'\0';
415 PG_FREE_IF_COPY(g, 1);
420 result = cstring_to_text(kml);
423 PG_RETURN_TEXT_P(result);
440 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
442 g = PG_GETARG_GSERIALIZED_P(0);
448 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
449 relative = PG_GETARG_INT32(1) ? 1:0;
451 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
463 PG_FREE_IF_COPY(g, 0);
465 result = cstring_to_text(svg);
468 PG_RETURN_TEXT_P(result);
489 version = PG_GETARG_INT32(0);
492 elog(ERROR,
"Only GeoJSON 1 is supported");
497 if (PG_ARGISNULL(1) ) PG_RETURN_NULL();
498 g = PG_GETARG_GSERIALIZED_P(1);
504 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
519 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
520 option = PG_GETARG_INT32(3);
522 if (option & 2 || option & 4)
532 elog(ERROR,
"SRID SRID_DEFAULT unknown in spatial_ref_sys table");
537 if (option & 1) has_bbox = 1;
541 PG_FREE_IF_COPY(g, 1);
544 result = cstring_to_text(geojson);
547 PG_RETURN_TEXT_P(result);
561 text *wkt_text = PG_GETARG_TEXT_P(0);
568 PG_PARSER_ERROR(lwg_parser_result);
571 srid_is_latlong(fcinfo, lwg_parser_result.
geom->
srid);
580 PG_RETURN_POINTER(g_ser);
589 char *wkb_bytea = (
char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
591 size_t wkb_size = VARSIZE(wkb_bytea);
596 lwpgerror(
"Unable to parse WKB");
599 srid_is_latlong(fcinfo, lwgeom->
srid);
603 PG_RETURN_POINTER(gser);
610 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
619 if ( (
int)lwgeom->
srid <= 0 )
625 srid_is_latlong(fcinfo, lwgeom->
srid);
632 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
641 g_ser = geography_serialize(lwgeom);
646 PG_FREE_IF_COPY(geom, 0);
647 PG_RETURN_POINTER(g_ser);
665 if ( (
int)lwgeom->
srid <= 0 )
671 PG_RETURN_POINTER(ret);
677 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
678 int32 geog_typmod = -1;
682 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
683 geog_typmod = PG_GETARG_INT32(2);
689 srid_is_latlong(fcinfo, lwgeom->
srid);
697 buf->cursor = buf->len;
699 PG_RETURN_POINTER(g_ser);
712 g = PG_GETARG_GSERIALIZED_P(0);
717 result = palloc(size_result + VARHDRSZ);
718 SET_VARSIZE(result, size_result + VARHDRSZ);
719 memcpy(VARDATA(result), wkb, size_result);
722 PG_RETURN_POINTER(result);
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
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 geography_as_kml(PG_FUNCTION_ARGS)
Datum geography_from_geometry(PG_FUNCTION_ARGS)
Datum geometry_from_geography(PG_FUNCTION_ARGS)
GSERIALIZED * gserialized_geography_from_lwgeom(LWGEOM *lwgeom, int32 geog_typmod)
Datum geography_in(PG_FUNCTION_ARGS)
Datum geography_recv(PG_FUNCTION_ARGS)
Datum geography_send(PG_FUNCTION_ARGS)
Datum geography_from_text(PG_FUNCTION_ARGS)
Datum geography_as_text(PG_FUNCTION_ARGS)
Datum geography_out(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(geography_in)
void geography_valid_type(uint8_t type)
The geography type only support POINT, LINESTRING, POLYGON, MULTI* variants of same,...
Datum geography_from_binary(PG_FUNCTION_ARGS)
Datum geography_as_gml(PG_FUNCTION_ARGS)
Datum geography_as_geojson(PG_FUNCTION_ARGS)
Datum geography_as_svg(PG_FUNCTION_ARGS)
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
char * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
#define LW_PARSER_CHECK_ALL
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
void lwgeom_free(LWGEOM *geom)
#define LW_PARSER_CHECK_NONE
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
int lwgeom_force_geodetic(LWGEOM *geom)
Force coordinates of LWGEOM into geodetic range (-180, -90, 180, 90)
#define LW_GML_IS_DIMS
Macros for specifying GML options.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
int lwgeom_nudge_geodetic(LWGEOM *geom)
Gently move coordinates of LWGEOM if they are close enough into geodetic range.
#define LW_TRUE
Return types for functions with status returns.
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.
char * lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
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...
This library is the generic geometry handling section of PostGIS.
char * getSRSbySRID(FunctionCallInfo fcinfo, int srid, bool short_crs)
char * text_to_cstring(const text *textptr)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.