34 #include "catalog/pg_type.h"
35 #include "executor/spi.h"
36 #include "utils/builtins.h"
38 #include "../postgis_config.h"
39 #include "lwgeom_pg.h"
62 static const uint16_t max_query_size = 512;
66 postgis_initialize_cache(fcinfo);
68 if (SPI_OK_CONNECT != SPI_connect ())
70 elog(NOTICE,
"getSRSbySRID: could not connect to SPI manager");
78 "SELECT auth_name||':'||auth_srid \
79 FROM %s WHERE srid='%d'",
80 postgis_spatial_ref_sys(),
85 "SELECT 'urn:ogc:def:crs:'||auth_name||'::'||auth_srid \
86 FROM %s WHERE srid='%d'",
87 postgis_spatial_ref_sys(),
90 err = SPI_exec(query, 1);
93 elog(NOTICE,
"getSRSbySRID: error executing query %d", err);
99 if (SPI_processed <= 0)
106 srs = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
116 size = strlen(srs)+1;
117 srscopy = SPI_palloc(size);
118 memcpy(srscopy, srs, size);
135 static const int16_t max_query_size = 512;
137 Oid argtypes[] = {CSTRINGOID};
138 Datum values[] = {CStringGetDatum(srs)};
141 postgis_initialize_cache(fcinfo);
146 "regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
147 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
148 postgis_spatial_ref_sys());
152 if (SPI_OK_CONNECT != SPI_connect())
154 elog(NOTICE,
"getSRIDbySRS: could not connect to SPI manager");
158 err = SPI_execute_with_args(query, 1, argtypes, values, NULL,
true, 1);
161 elog(NOTICE,
"getSRIDbySRS: error executing query %d", err);
167 if (SPI_processed <= 0)
173 "regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
174 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
175 postgis_spatial_ref_sys());
177 err = SPI_execute_with_args(query, 1, argtypes, values, NULL,
true, 1);
180 elog(NOTICE,
"getSRIDbySRS: error executing query %d", err);
185 if (SPI_processed <= 0)
192 srid = atoi(SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1));
215 static const char* default_prefix =
"gml:";
216 const char* prefix = default_prefix;
217 const char* gml_id = NULL;
219 char *gml_id_buf, *prefix_buf;
220 text *prefix_text, *gml_id_text;
224 version = PG_GETARG_INT32(0);
225 if ( version != 2 && version != 3 )
227 elog(ERROR,
"Only GML 2 and GML 3 are supported");
232 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
233 geom = PG_GETARG_GSERIALIZED_P(1);
236 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
247 if (PG_NARGS() > 3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3);
250 if (PG_NARGS() >4 && !PG_ARGISNULL(4))
252 prefix_text = PG_GETARG_TEXT_P(4);
253 if ( VARSIZE(prefix_text) == VARHDRSZ )
259 len = VARSIZE(prefix_text)-VARHDRSZ;
260 prefix_buf = palloc(len + 2);
261 memcpy(prefix_buf, VARDATA(prefix_text), len);
263 prefix_buf[len] =
':';
264 prefix_buf[len+1] =
'\0';
269 if (PG_NARGS() >5 && !PG_ARGISNULL(5))
271 gml_id_text = PG_GETARG_TEXT_P(5);
272 if ( VARSIZE(gml_id_text) == VARHDRSZ )
278 len = VARSIZE(gml_id_text)-VARHDRSZ;
279 gml_id_buf = palloc(len+1);
280 memcpy(gml_id_buf, VARDATA(gml_id_text), len);
281 gml_id_buf[len] =
'\0';
298 "Options %d passed to ST_AsGML(geography) sets "
299 "unsupported value 8",
323 lwgeom, srs,
precision, lwopts, prefix, gml_id);
327 PG_FREE_IF_COPY(geom, 1);
333 result = cstring_to_text(gml);
335 PG_RETURN_TEXT_P(result);
351 static const char* default_prefix =
"";
353 const char* prefix = default_prefix;
358 version = PG_GETARG_INT32(0);
361 elog(ERROR,
"Only KML 2 is supported");
366 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
367 geom = PG_GETARG_GSERIALIZED_P(1);
370 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
380 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
382 prefix_text = PG_GETARG_TEXT_P(3);
383 if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
390 prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
391 memcpy(prefixbuf, VARDATA(prefix_text),
392 VARSIZE(prefix_text)-VARHDRSZ);
394 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] =
':';
395 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] =
'\0';
403 PG_FREE_IF_COPY(geom, 1);
408 result = cstring_to_text(kml);
411 PG_RETURN_POINTER(result);
429 return DirectFunctionCall2(
LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2));
431 return DirectFunctionCall3(
LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2), PG_GETARG_DATUM(3));
433 elog(ERROR,
"bad call in %s", __func__);
453 if ( PG_ARGISNULL(0) )
456 geom = PG_GETARG_GSERIALIZED_P(0);
459 if ( PG_NARGS() > 1 && !PG_ARGISNULL(1) )
474 if ( PG_NARGS() > 2 && !PG_ARGISNULL(2) )
476 int option = PG_GETARG_INT32(2);
478 if ( option & 2 || option & 4 )
492 "SRID %i unknown in spatial_ref_sys table",
509 result = cstring_to_text(geojson);
512 PG_FREE_IF_COPY(geom, 0);
513 PG_RETURN_TEXT_P(result);
530 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
532 geom = PG_GETARG_GSERIALIZED_P(0);
535 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
536 relative = PG_GETARG_INT32(1) ? 1:0;
538 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
549 result = cstring_to_text(svg);
552 PG_FREE_IF_COPY(geom, 0);
554 PG_RETURN_TEXT_P(result);
572 static const char* default_defid =
"x3d:";
574 const char* defid = default_defid;
578 version = PG_GETARG_INT32(0);
581 elog(ERROR,
"Only X3D version 3 are supported");
586 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
587 geom = PG_GETARG_GSERIALIZED_P(1);
590 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
600 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
601 option = PG_GETARG_INT32(3);
606 if (PG_NARGS() >4 && !PG_ARGISNULL(4))
608 defid_text = PG_GETARG_TEXT_P(4);
609 if ( VARSIZE(defid_text)-VARHDRSZ == 0 )
616 defidbuf = palloc(VARSIZE(defid_text)-VARHDRSZ+2);
617 memcpy(defidbuf, VARDATA(defid_text),
618 VARSIZE(defid_text)-VARHDRSZ);
620 defidbuf[VARSIZE(defid_text)-VARHDRSZ] =
':';
621 defidbuf[VARSIZE(defid_text)-VARHDRSZ+1] =
'\0';
636 PG_FREE_IF_COPY(geom, 0);
639 elog(ERROR,
"Only SRID 4326 is supported for geocoordinates.");
648 PG_FREE_IF_COPY(geom, 1);
650 result = cstring_to_text(x3d);
653 PG_RETURN_TEXT_P(result);
664 char *encodedpolyline;
668 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
670 geom = PG_GETARG_GSERIALIZED_P(0);
672 PG_FREE_IF_COPY(geom, 0);
673 elog(ERROR,
"Only SRID 4326 is supported.");
678 if (PG_NARGS() > 1 && !PG_ARGISNULL(1))
686 PG_FREE_IF_COPY(geom, 0);
688 result = cstring_to_text(encodedpolyline);
691 PG_RETURN_TEXT_P(result);
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
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.
#define LW_GML_IS_DEGREE
For GML3 only, declare that datas are lat/lon.
void lwgeom_free(LWGEOM *geom)
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
char * lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid)
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
#define LW_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
#define LW_GML_IS_DIMS
Macros for specifying GML options.
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
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.
#define SRID_UNKNOWN
Unknown SRID value.
char * lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
#define LW_X3D_USE_GEOCOORDS
char * lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
This library is the generic geometry handling section of PostGIS.
PG_FUNCTION_INFO_V1(LWGEOM_asGML)
Encode feature in GML.
int getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
Datum LWGEOM_asGeoJson_old(PG_FUNCTION_ARGS)
Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS)
Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
Datum LWGEOM_asSVG(PG_FUNCTION_ARGS)
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
char * getSRSbySRID(FunctionCallInfo fcinfo, int srid, bool short_crs)
Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
Datum LWGEOM_asX3D(PG_FUNCTION_ARGS)