34 #include "catalog/pg_type.h" 35 #include "executor/spi.h" 37 #include "../postgis_config.h" 38 #include "lwgeom_pg.h" 63 if (SPI_OK_CONNECT != SPI_connect ())
65 elog(NOTICE,
"getSRSbySRID: could not connect to SPI manager");
71 snprintf(query, 256,
"SELECT auth_name||':'||auth_srid \ 72 FROM spatial_ref_sys WHERE srid='%d'", srid);
74 snprintf(query, 256,
"SELECT 'urn:ogc:def:crs:'||auth_name||'::'||auth_srid \ 75 FROM spatial_ref_sys WHERE srid='%d'", srid);
77 err = SPI_exec(query, 1);
80 elog(NOTICE,
"getSRSbySRID: error executing query %d", err);
86 if (SPI_processed <= 0)
93 srs = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
103 size = strlen(srs)+1;
104 srscopy = SPI_palloc(size);
105 memcpy(srscopy, srs, size);
123 "FROM spatial_ref_sys, " 124 "regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re " 125 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid";
126 Oid argtypes[] = {CSTRINGOID};
127 Datum values[] = {CStringGetDatum(srs)};
133 if (SPI_OK_CONNECT != SPI_connect())
135 elog(NOTICE,
"getSRIDbySRS: could not connect to SPI manager");
139 err = SPI_execute_with_args(query, 1, argtypes, values, NULL,
true, 1);
142 elog(NOTICE,
"getSRIDbySRS: error executing query %d", err);
148 if (SPI_processed <= 0)
152 "FROM spatial_ref_sys, " 153 "regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re " 154 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid";
156 err = SPI_execute_with_args(query, 1, argtypes, values, NULL,
true, 1);
159 elog(NOTICE,
"getSRIDbySRS: error executing query %d", err);
164 if (SPI_processed <= 0)
171 srid = atoi(SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1));
200 static const char* default_prefix =
"gml:";
201 const char* prefix = default_prefix;
202 const char* gml_id = NULL;
204 char *gml_id_buf, *prefix_buf;
205 text *prefix_text, *gml_id_text;
209 version = PG_GETARG_INT32(0);
210 if ( version != 2 && version != 3 )
212 elog(ERROR,
"Only GML 2 and GML 3 are supported");
217 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
218 geom = PG_GETARG_GSERIALIZED_P(1);
221 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
223 precision = PG_GETARG_INT32(2);
225 if ( precision > DBL_DIG )
227 else if ( precision < 0 ) precision = 0;
231 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
232 option = PG_GETARG_INT32(3);
235 if (PG_NARGS() >4 && !PG_ARGISNULL(4))
237 prefix_text = PG_GETARG_TEXT_P(4);
238 if ( VARSIZE(prefix_text) == VARHDRSZ )
244 len = VARSIZE(prefix_text)-VARHDRSZ;
245 prefix_buf = palloc(len + 2);
246 memcpy(prefix_buf, VARDATA(prefix_text), len);
248 prefix_buf[len] =
':';
249 prefix_buf[len+1] =
'\0';
254 if (PG_NARGS() >5 && !PG_ARGISNULL(5))
256 gml_id_text = PG_GETARG_TEXT_P(5);
257 if ( VARSIZE(gml_id_text) == VARHDRSZ )
263 len = VARSIZE(gml_id_text)-VARHDRSZ;
264 gml_id_buf = palloc(len+1);
265 memcpy(gml_id_buf, VARDATA(gml_id_text), len);
266 gml_id_buf[len] =
'\0';
285 else if (version == 2)
287 else if (version == 3 && lwopts & LW_GML_EXTENT)
289 else if (version == 3)
290 gml =
lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, gml_id);
293 PG_FREE_IF_COPY(geom, 1);
299 result = cstring2text(gml);
301 PG_RETURN_TEXT_P(result);
317 static const char* default_prefix =
"";
319 const char* prefix = default_prefix;
324 version = PG_GETARG_INT32(0);
327 elog(ERROR,
"Only KML 2 is supported");
332 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
333 geom = PG_GETARG_GSERIALIZED_P(1);
336 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
339 precision = PG_GETARG_INT32(2);
340 if ( precision > DBL_DIG )
342 else if ( precision < 0 ) precision = 0;
346 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
348 prefix_text = PG_GETARG_TEXT_P(3);
349 if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
356 prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
357 memcpy(prefixbuf, VARDATA(prefix_text),
358 VARSIZE(prefix_text)-VARHDRSZ);
360 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] =
':';
361 prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] =
'\0';
369 PG_FREE_IF_COPY(geom, 1);
374 result = cstring2text(kml);
377 PG_RETURN_POINTER(result);
395 return DirectFunctionCall2(
LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2));
397 return DirectFunctionCall3(
LWGEOM_asGeoJson, PG_GETARG_DATUM(1), PG_GETARG_DATUM(2), PG_GETARG_DATUM(3));
399 elog(ERROR,
"bad call in %s", __func__);
419 if ( PG_ARGISNULL(0) )
422 geom = PG_GETARG_GSERIALIZED_P(0);
425 if ( PG_NARGS() > 1 && !PG_ARGISNULL(1) )
427 precision = PG_GETARG_INT32(1);
428 if ( precision > DBL_DIG )
430 else if ( precision < 0 )
440 if ( PG_NARGS() > 2 && !PG_ARGISNULL(2) )
442 int option = PG_GETARG_INT32(2);
444 if ( option & 2 || option & 4 )
458 "SRID %i unknown in spatial_ref_sys table",
475 result = cstring2text(geojson);
478 PG_FREE_IF_COPY(geom, 0);
479 PG_RETURN_TEXT_P(result);
496 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
498 geom = PG_GETARG_GSERIALIZED_P(0);
501 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
502 relative = PG_GETARG_INT32(1) ? 1:0;
504 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
506 precision = PG_GETARG_INT32(2);
508 if ( precision > DBL_DIG )
510 else if ( precision < 0 ) precision = 0;
515 result = cstring2text(svg);
518 PG_FREE_IF_COPY(geom, 0);
520 PG_RETURN_TEXT_P(result);
538 static const char* default_defid =
"x3d:";
540 const char* defid = default_defid;
544 version = PG_GETARG_INT32(0);
547 elog(ERROR,
"Only X3D version 3 are supported");
552 if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
553 geom = PG_GETARG_GSERIALIZED_P(1);
556 if (PG_NARGS() >2 && !PG_ARGISNULL(2))
558 precision = PG_GETARG_INT32(2);
560 if ( precision > DBL_DIG )
562 else if ( precision < 0 ) precision = 0;
566 if (PG_NARGS() >3 && !PG_ARGISNULL(3))
567 option = PG_GETARG_INT32(3);
572 if (PG_NARGS() >4 && !PG_ARGISNULL(4))
574 defid_text = PG_GETARG_TEXT_P(4);
575 if ( VARSIZE(defid_text)-VARHDRSZ == 0 )
582 defidbuf = palloc(VARSIZE(defid_text)-VARHDRSZ+2);
583 memcpy(defidbuf, VARDATA(defid_text),
584 VARSIZE(defid_text)-VARHDRSZ);
586 defidbuf[VARSIZE(defid_text)-VARHDRSZ] =
':';
587 defidbuf[VARSIZE(defid_text)-VARHDRSZ+1] =
'\0';
600 PG_FREE_IF_COPY(geom, 0);
603 elog(ERROR,
"Only SRID 4326 is supported for geocoordinates.");
612 PG_FREE_IF_COPY(geom, 1);
614 result = cstring2text(x3d);
617 PG_RETURN_TEXT_P(result);
628 char *encodedpolyline;
632 if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
634 geom = PG_GETARG_GSERIALIZED_P(0);
636 PG_FREE_IF_COPY(geom, 0);
637 elog(ERROR,
"Only SRID 4326 is supported.");
642 if (PG_NARGS() > 1 && !PG_ARGISNULL(1))
644 precision = PG_GETARG_INT32(1);
645 if ( precision < 0 ) precision = 5;
650 PG_FREE_IF_COPY(geom, 0);
652 result = cstring2text(encodedpolyline);
655 PG_RETURN_TEXT_P(result);
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.
Datum LWGEOM_asX3D(PG_FUNCTION_ARGS)
#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)
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.
PG_FUNCTION_INFO_V1(LWGEOM_asGML)
Encode feature in GML.
void lwgeom_free(LWGEOM *geom)
Datum LWGEOM_asSVG(PG_FUNCTION_ARGS)
char * lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
#define LW_X3D_USE_GEOCOORDS
Datum LWGEOM_asGeoJson_old(PG_FUNCTION_ARGS)
#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_GML_EXTENT
For GML2 and GML3, output only extent of geometry.
Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS)
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
int getSRIDbySRS(const char *srs)
char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
char * getSRSbySRID(int srid, bool short_crs)
#define LW_GML_IS_DIMS
Macros for specifying GML options.
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
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)...
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.