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"
43 #include "lwgeom_cache.h"
44 #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_check_latlong(lwgeom->
srid);
184 PG_RETURN_POINTER(g_ser);
215 static const char *default_prefix =
"gml:";
216 const char *prefix = default_prefix;
217 char *prefix_buf =
"";
218 text *prefix_text, *id_text = NULL;
219 const char *
id = NULL;
228 Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
230 if (first_type != INT4OID)
237 version = PG_GETARG_INT32(argnum++);
238 if (version != 2 && version != 3)
240 elog(ERROR,
"Only GML 2 and GML 3 are supported");
246 g = PG_GETARG_GSERIALIZED_P(argnum++);
248 option = PG_GETARG_INT32(argnum++);
249 prefix_text = PG_GETARG_TEXT_P(argnum++);
250 id_text = PG_GETARG_TEXT_P(argnum++);
256 if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
259 prefix_buf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
260 memcpy(prefix_buf, VARDATA_ANY(prefix_text),
261 VARSIZE_ANY_EXHDR(prefix_text));
263 prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)] =
':';
264 prefix_buf[VARSIZE_ANY_EXHDR(prefix_text)+1] =
'\0';
272 if (VARSIZE_ANY_EXHDR(id_text) > 0)
274 id_buf = palloc(VARSIZE_ANY_EXHDR(id_text)+2);
275 memcpy(id_buf, VARDATA(id_text), VARSIZE_ANY_EXHDR(id_text));
276 id_buf[VARSIZE_ANY_EXHDR(id_text)+1] =
'\0';
281 srs = GetSRSCacheBySRID(fcinfo, srid,
false);
283 srs = GetSRSCacheBySRID(fcinfo, srid,
true);
286 elog(ERROR,
"SRID %d unknown in spatial_ref_sys table",
SRID_DEFAULT);
296 "Options %d passed to ST_AsGML(geography) sets "
297 "unsupported value 8",
301 if ((option & 4) || (option & 16) || (option & 32))
304 "Options %d passed to ST_AsGML(geography) but are only "
305 "applicable to ST_AsGML(geometry)",
330 static const char *default_prefix =
"";
332 const char *prefix = default_prefix;
335 text *prefix_text = PG_GETARG_TEXT_P(2);
342 if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
345 prefixbuf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
346 memcpy(prefixbuf, VARDATA(prefix_text),
347 VARSIZE_ANY_EXHDR(prefix_text));
349 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)] =
':';
350 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)+1] =
'\0';
360 PG_RETURN_TEXT_P(kml);
372 int relative = PG_GETARG_INT32(1) ? 1 : 0;
391 const char *srs = NULL;
394 int option = PG_GETARG_INT32(2);
407 if (option & 2 || option & 4)
417 elog(ERROR,
"SRID SRID_DEFAULT unknown in spatial_ref_sys table");
422 if (option & 1) has_bbox = 1;
426 PG_FREE_IF_COPY(g, 0);
428 PG_RETURN_TEXT_P(geojson);
442 text *wkt_text = PG_GETARG_TEXT_P(0);
445 char *wkt = text_to_cstring(wkt_text);
449 PG_PARSER_ERROR(lwg_parser_result);
452 srid_check_latlong(lwg_parser_result.
geom->
srid);
461 PG_RETURN_POINTER(g_ser);
470 char *wkb_bytea = (
char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
472 size_t wkb_size = VARSIZE(wkb_bytea);
473 uint8_t *wkb = (uint8_t*)VARDATA(wkb_bytea);
477 lwpgerror(
"Unable to parse WKB");
480 srid_check_latlong(lwgeom->
srid);
484 PG_RETURN_POINTER(gser);
492 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
498 if ( (
int)lwgeom->
srid <= 0 )
504 srid_check_latlong(lwgeom->
srid);
511 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
520 g_ser = geography_serialize(lwgeom);
525 PG_FREE_IF_COPY(geom, 0);
526 PG_RETURN_POINTER(g_ser);
544 if ( (
int)lwgeom->
srid <= 0 )
547 ret = geometry_serialize(lwgeom);
550 PG_RETURN_POINTER(ret);
556 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
557 int32 geog_typmod = -1;
561 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
562 geog_typmod = PG_GETARG_INT32(2);
568 srid_check_latlong(lwgeom->
srid);
576 buf->cursor = buf->len;
578 PG_RETURN_POINTER(g_ser);
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.
#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.
lwvarlena_t * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
lwvarlena_t * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
Takes a GEOMETRY and returns a SVG representation.
void lwgeom_free(LWGEOM *geom)
#define LW_PARSER_CHECK_NONE
lwvarlena_t * lwgeom_to_geojson(const LWGEOM *geo, const char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
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_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
lwvarlena_t * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
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.
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...
lwvarlena_t * lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant)
lwvarlena_t * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
This library is the generic geometry handling section of PostGIS.
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.