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),
84 errmsg(
"Geography type does not support %s",
lwtype_name(type) )));
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))
248 precision = PG_GETARG_INT32(2);
250 if ( precision > DBL_DIG )
252 else if ( precision < 0 ) precision = 0;
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';
302 elog(ERROR,
"SRID %d unknown in spatial_ref_sys table",
SRID_DEFAULT);
316 PG_FREE_IF_COPY(g, 1);
323 result = cstring2text(gml);
326 PG_RETURN_TEXT_P(result);
342 static const char *default_prefix =
"";
344 const char* prefix = default_prefix;
349 version = PG_GETARG_INT32(0);
352 elog(ERROR,
"Only KML 2 is supported");
357 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
358 g = PG_GETARG_GSERIALIZED_P(1);
364 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
366 precision = PG_GETARG_INT32(2);
368 if ( precision > DBL_DIG )
370 else if ( precision < 0 ) precision = 0;
374 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
376 prefix_text = PG_GETARG_TEXT_P(3);
377 if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
384 prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
385 memcpy(prefixbuf, VARDATA(prefix_text),
386 VARSIZE(prefix_text)-VARHDRSZ);
388 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] =
':';
389 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] =
'\0';
397 PG_FREE_IF_COPY(g, 1);
402 result = cstring2text(kml);
405 PG_RETURN_TEXT_P(result);
422 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
424 g = PG_GETARG_GSERIALIZED_P(0);
430 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
431 relative = PG_GETARG_INT32(1) ? 1:0;
433 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
435 precision = PG_GETARG_INT32(2);
437 if ( precision > DBL_DIG )
439 else if ( precision < 0 ) precision = 0;
445 PG_FREE_IF_COPY(g, 0);
447 result = cstring2text(svg);
450 PG_RETURN_TEXT_P(result);
471 version = PG_GETARG_INT32(0);
474 elog(ERROR,
"Only GeoJSON 1 is supported");
479 if (PG_ARGISNULL(1) ) PG_RETURN_NULL();
480 g = PG_GETARG_GSERIALIZED_P(1);
486 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
488 precision = PG_GETARG_INT32(2);
490 if ( precision > DBL_DIG )
492 else if ( precision < 0 ) precision = 0;
501 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
502 option = PG_GETARG_INT32(3);
504 if (option & 2 || option & 4)
512 elog(ERROR,
"SRID SRID_DEFAULT unknown in spatial_ref_sys table");
517 if (option & 1) has_bbox = 1;
521 PG_FREE_IF_COPY(g, 1);
524 result = cstring2text(geojson);
527 PG_RETURN_TEXT_P(result);
541 text *wkt_text = PG_GETARG_TEXT_P(0);
548 PG_PARSER_ERROR(lwg_parser_result);
551 srid_is_latlong(fcinfo, lwg_parser_result.
geom->
srid);
560 PG_RETURN_POINTER(g_ser);
569 char *wkb_bytea = (
char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
571 size_t wkb_size = VARSIZE(wkb_bytea);
576 lwpgerror(
"Unable to parse WKB");
579 srid_is_latlong(fcinfo, lwgeom->
srid);
583 PG_RETURN_POINTER(gser);
590 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
599 if ( (
int)lwgeom->
srid <= 0 )
605 srid_is_latlong(fcinfo, lwgeom->
srid);
612 errmsg_internal(
"Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
621 g_ser = geography_serialize(lwgeom);
626 PG_FREE_IF_COPY(geom, 0);
627 PG_RETURN_POINTER(g_ser);
646 if ( (
int)lwgeom->
srid <= 0 )
652 PG_RETURN_POINTER(ret);
658 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
659 int32 geog_typmod = -1;
663 if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
664 geog_typmod = PG_GETARG_INT32(2);
670 srid_is_latlong(fcinfo, lwgeom->
srid);
678 buf->cursor = buf->len;
680 PG_RETURN_POINTER(g_ser);
693 g = PG_GETARG_GSERIALIZED_P(0);
698 result = palloc(size_result + VARHDRSZ);
699 SET_VARSIZE(result, size_result + VARHDRSZ);
700 memcpy(VARDATA(result), wkb, size_result);
703 PG_RETURN_POINTER(result);
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
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.
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...
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.
void lwgeom_free(LWGEOM *geom)
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.
PG_FUNCTION_INFO_V1(geography_in)
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
#define LW_PARSER_CHECK_NONE
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
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.
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM...
int lwgeom_force_geodetic(LWGEOM *geom)
Force coordinates of LWGEOM into geodetic range (-180, -90, 180, 90)
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.
Datum geography_as_gml(PG_FUNCTION_ARGS)
Datum geometry_from_geography(PG_FUNCTION_ARGS)
Datum geography_as_svg(PG_FUNCTION_ARGS)
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
char * getSRSbySRID(int srid, bool short_crs)
Datum geography_from_geometry(PG_FUNCTION_ARGS)
#define LW_GML_IS_DIMS
Macros for specifying GML options.
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum geography_out(PG_FUNCTION_ARGS)
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
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.
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Datum geography_from_text(PG_FUNCTION_ARGS)
Datum geography_send(PG_FUNCTION_ARGS)
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)
#define LW_PARSER_CHECK_ALL
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 * 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.
Datum geography_as_kml(PG_FUNCTION_ARGS)