28 #include "../postgis_config.h"
35 #include "utils/elog.h"
36 #include "utils/array.h"
37 #include "utils/builtins.h"
38 #include "lib/stringinfo.h"
39 #include "catalog/pg_type.h"
42 #include "lwgeom_pg.h"
45 #include "lwgeom_transform.h"
82 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
103 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
108 if ( (
int)lwgeom->
srid <= 0 )
115 g_ser = geography_serialize(lwgeom);
118 if ( geog_typmod >= 0 )
121 POSTGIS_DEBUG(3,
"typmod and geometry were consistent");
125 POSTGIS_DEBUG(3,
"typmod was -1");
138 char *
str = PG_GETARG_CSTRING(0);
140 int32 geog_typmod = -1;
145 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
146 geog_typmod = PG_GETARG_INT32(2);
152 if (
str[0] ==
'\0' )
153 ereport(ERROR,(errmsg(
"parse error - invalid geometry")));
162 ereport(ERROR,(errmsg(
"parse error - invalid geometry")));
168 PG_PARSER_ERROR(lwg_parser_result);
170 lwgeom = lwg_parser_result.
geom;
174 srid_check_latlong(fcinfo, lwgeom->
srid);
183 PG_RETURN_POINTER(g_ser);
196 g = PG_GETARG_GSERIALIZED_P(0);
201 PG_RETURN_CSTRING(hexwkb);
221 static const char *default_prefix =
"gml:";
222 const char *prefix = default_prefix;
223 char *prefix_buf =
"";
224 text *prefix_text, *id_text = NULL;
225 const char *
id = NULL;
234 Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
237 if (first_type != INT4OID)
244 version = PG_GETARG_INT32(argnum++);
246 if (version != 2 && version != 3)
248 elog(ERROR,
"Only GML 2 and GML 3 are supported");
254 g = PG_GETARG_GSERIALIZED_P(argnum++);
256 option = PG_GETARG_INT32(argnum++);
257 prefix_text = PG_GETARG_TEXT_P(argnum++);
258 id_text = PG_GETARG_TEXT_P(argnum++);
270 if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
273 prefix_buf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
274 memcpy(prefix_buf, VARDATA_ANY(prefix_text),
275 VARSIZE_ANY_EXHDR(prefix_text));
277 prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)] =
':';
278 prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)+1] =
'\0';
286 if (VARSIZE_ANY_EXHDR(id_text) > 0)
288 id_buf = palloc(VARSIZE_ANY_EXHDR(id_text)+2);
289 memcpy(id_buf, VARDATA(id_text), VARSIZE_ANY_EXHDR(id_text));
290 id_buf[VARSIZE_ANY_EXHDR(id_text)+1] =
'\0';
300 elog(ERROR,
"SRID %d unknown in spatial_ref_sys table",
SRID_DEFAULT);
310 "Options %d passed to ST_AsGML(geography) sets "
311 "unsupported value 8",
315 if ((option & 4) || (option & 16) || (option & 32))
318 "Options %d passed to ST_AsGML(geography) but are only "
319 "applicable to ST_AsGML(geometry)",
330 PG_FREE_IF_COPY(g, argeom);
337 result = cstring_to_text(gml);
340 PG_RETURN_TEXT_P(result);
353 static const char *default_prefix =
"";
355 const char *prefix = default_prefix;
358 text *prefix_text = PG_GETARG_TEXT_P(2);
367 if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
370 prefixbuf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
371 memcpy(prefixbuf, VARDATA(prefix_text),
372 VARSIZE_ANY_EXHDR(prefix_text));
374 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)] =
':';
375 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)+1] =
'\0';
386 PG_FREE_IF_COPY(g, 0);
391 result = cstring_to_text(kml);
394 PG_RETURN_TEXT_P(result);
407 int relative = PG_GETARG_INT32(1) ? 1 : 0;
419 PG_FREE_IF_COPY(g, 0);
421 result = cstring_to_text(svg);
424 PG_RETURN_TEXT_P(result);
440 int option = PG_GETARG_INT32(2);
455 if (option & 2 || option & 4)
465 elog(ERROR,
"SRID SRID_DEFAULT unknown in spatial_ref_sys table");
470 if (option & 1) has_bbox = 1;
474 PG_FREE_IF_COPY(g, 0);
477 result = cstring_to_text(geojson);
480 PG_RETURN_TEXT_P(result);
494 text *wkt_text = PG_GETARG_TEXT_P(0);
501 PG_PARSER_ERROR(lwg_parser_result);
504 srid_check_latlong(fcinfo, lwg_parser_result.
geom->
srid);
513 PG_RETURN_POINTER(g_ser);
522 char *wkb_bytea = (
char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
524 size_t wkb_size = VARSIZE(wkb_bytea);
525 uint8_t *wkb = (uint8_t*)VARDATA(wkb_bytea);
529 lwpgerror(
"Unable to parse WKB");
532 srid_check_latlong(fcinfo, lwgeom->
srid);
536 PG_RETURN_POINTER(gser);
544 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
550 if ( (
int)lwgeom->
srid <= 0 )
556 srid_check_latlong(fcinfo, lwgeom->
srid);
563 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
572 g_ser = geography_serialize(lwgeom);
577 PG_FREE_IF_COPY(geom, 0);
578 PG_RETURN_POINTER(g_ser);
596 if ( (
int)lwgeom->
srid <= 0 )
602 PG_RETURN_POINTER(ret);
608 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
609 int32 geog_typmod = -1;
613 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
614 geog_typmod = PG_GETARG_INT32(2);
620 ereport(ERROR,(errmsg(
"recv error - invalid geometry")));
625 srid_check_latlong(fcinfo, lwgeom->
srid);
633 buf->cursor = buf->len;
635 PG_RETURN_POINTER(g_ser);
648 g = PG_GETARG_GSERIALIZED_P(0);
653 result = palloc(size_result + VARHDRSZ);
654 SET_VARSIZE(result, size_result + VARHDRSZ);
655 memcpy(VARDATA(result), wkb, size_result);
658 PG_RETURN_POINTER(result);
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)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
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, int32_t srid, bool short_crs)
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
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.