Datum postgis_typmod_type(PG_FUNCTION_ARGS) { int32 typmod = PG_GETARG_INT32(0); int32 type = TYPMOD_GET_TYPE(typmod); char *s = (char*)palloc(64); char *ptr = s; text *stext; /* Has type? */ if ( typmod < 0 || type == 0 ) ptr += sprintf(ptr, "Geometry"); else ptr += sprintf(ptr, "%s", lwtype_name(type)); /* Has Z? */ if ( typmod >= 0 && TYPMOD_GET_Z(typmod) ) ptr += sprintf(ptr, "%s", "Z"); /* Has M? */ if ( typmod >= 0 && TYPMOD_GET_M(typmod) ) ptr += sprintf(ptr, "%s", "M"); stext = cstring2text(s); pfree(s); PG_RETURN_TEXT_P(stext); }
Datum LWGEOM_asText(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; char *wkt; size_t wkt_size; text *result; POSTGIS_DEBUG(2, "Called."); geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); lwgeom = lwgeom_from_gserialized(geom); /* Write to WKT and free the geometry */ wkt = lwgeom_to_wkt(lwgeom, WKT_ISO, DBL_DIG, &wkt_size); lwgeom_free(lwgeom); POSTGIS_DEBUGF(3, "WKT size = %d, WKT length = %d", wkt_size, strlen(wkt)); /* Write to text and free the WKT */ result = cstring2text(wkt); pfree(wkt); /* Return the text */ PG_FREE_IF_COPY(geom, 0); PG_RETURN_TEXT_P(result); }
Datum RASTER_notSameAlignmentReason(PG_FUNCTION_ARGS) { const int set_count = 2; rt_pgraster *pgrast[2]; int pgrastpos[2] = {-1, -1}; rt_raster rast[2] = {NULL}; uint32_t i; uint32_t j; uint32_t k; int rtn; int aligned = 0; char *reason = NULL; text *result = NULL; for (i = 0, j = 0; i < set_count; i++) { /* pgrast is null, return null */ if (PG_ARGISNULL(j)) { for (k = 0; k < i; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(j), 0, sizeof(struct rt_raster_serialized_t)); pgrastpos[i] = j; j++; /* raster */ rast[i] = rt_raster_deserialize(pgrast[i], TRUE); if (!rast[i]) { for (k = 0; k <= i; k++) { if (k < i) rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } elog(ERROR, "RASTER_notSameAlignmentReason: Could not deserialize the %s raster", i < 1 ? "first" : "second"); PG_RETURN_NULL(); } } rtn = rt_raster_same_alignment( rast[0], rast[1], &aligned, &reason ); for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } if (rtn != ES_NONE) { elog(ERROR, "RASTER_notSameAlignmentReason: Could not test for alignment on the two rasters"); PG_RETURN_NULL(); } result = cstring2text(reason); PG_RETURN_TEXT_P(result); }
Datum postgis_libjson_version(PG_FUNCTION_ARGS) { #ifndef HAVE_LIBJSON PG_RETURN_NULL(); #else /* HAVE_LIBJSON */ const char *ver = "UNKNOWN"; text *result = cstring2text(ver); PG_RETURN_POINTER(result); #endif }
Datum LWGEOM_to_text(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom; char *hexwkb; size_t hexwkb_size; text *result; /* Generate WKB hex text */ lwgeom = lwgeom_from_gserialized(geom); hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &hexwkb_size); lwgeom_free(lwgeom); /* Copy into text obect */ result = cstring2text(hexwkb); pfree(hexwkb); /* Clean up and return */ PG_FREE_IF_COPY(geom, 0); PG_RETURN_TEXT_P(result); }
Datum geometry_geometrytype(PG_FUNCTION_ARGS) { GSERIALIZED *lwgeom; text *type_text; char *type_str = palloc(32); lwgeom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* Make it empty string to start */ *type_str = 0; /* Build up the output string */ strncat(type_str, "ST_", 32); strncat(type_str, lwtype_name(gserialized_get_type(lwgeom)), 32); /* Build a text type to store things in */ type_text = cstring2text(type_str); pfree(type_str); PG_FREE_IF_COPY(lwgeom, 0); PG_RETURN_TEXT_P(type_text); }
Datum geography_as_svg(PG_FUNCTION_ARGS) { GSERIALIZED *g = NULL; LWGEOM *lwgeom = NULL; char *svg; text *result; int relative = 0; int precision=DBL_DIG; if ( PG_ARGISNULL(0) ) PG_RETURN_NULL(); g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* Convert to lwgeom so we can run the old functions */ lwgeom = lwgeom_from_gserialized(g); /* check for relative path notation */ if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) ) relative = PG_GETARG_INT32(1) ? 1:0; if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) ) { precision = PG_GETARG_INT32(2); /* TODO: leave this to liblwgeom */ if ( precision > DBL_DIG ) precision = DBL_DIG; else if ( precision < 0 ) precision = 0; } svg = lwgeom_to_svg(lwgeom, precision, relative); lwgeom_free(lwgeom); PG_FREE_IF_COPY(g, 0); result = cstring2text(svg); lwfree(svg); PG_RETURN_TEXT_P(result); }
Datum geometry_geometrytype(PG_FUNCTION_ARGS) { GSERIALIZED *gser; text *type_text; static int type_str_len = 32; char type_str[type_str_len]; /* Read just the header from the toasted tuple */ gser = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, gserialized_max_header_size()); /* Make it empty string to start */ type_str[0] = 0; /* Build up the output string */ strncat(type_str, "ST_", type_str_len); strncat(type_str, lwtype_name(gserialized_get_type(gser)), type_str_len - 3); /* Build a text type to store things in */ type_text = cstring2text(type_str); PG_FREE_IF_COPY(gser, 0); PG_RETURN_TEXT_P(type_text); }
Datum geography_as_text(PG_FUNCTION_ARGS) { GSERIALIZED *g = NULL; LWGEOM *lwgeom = NULL; char *wkt = NULL; text *result = NULL; size_t len = 0; g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* Convert to lwgeom so we can run the old functions */ lwgeom = lwgeom_from_gserialized(g); /* Generate WKT */ wkt = lwgeom_to_wkt(lwgeom, WKT_ISO, DBL_DIG, &len); /* Copy into text obect */ result = cstring2text(wkt); pfree(wkt); lwgeom_free(lwgeom); PG_RETURN_TEXT_P(result); }
Datum geography_as_geojson(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; GSERIALIZED *g = NULL; char *geojson; text *result; int version; int option = 0; int has_bbox = 0; int precision = OUT_MAX_DOUBLE_PRECISION; char * srs = NULL; /* Get the version */ version = PG_GETARG_INT32(0); if ( version != 1) { elog(ERROR, "Only GeoJSON 1 is supported"); PG_RETURN_NULL(); } /* Get the geography */ if (PG_ARGISNULL(1) ) PG_RETURN_NULL(); g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); /* Convert to lwgeom so we can run the old functions */ lwgeom = lwgeom_from_gserialized(g); /* Retrieve precision if any (default is max) */ if (PG_NARGS() >2 && !PG_ARGISNULL(2)) { precision = PG_GETARG_INT32(2); if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision = OUT_MAX_DOUBLE_PRECISION; else if ( precision < 0 ) precision = 0; } /* Retrieve output option * 0 = without option (default) * 1 = bbox * 2 = short crs * 4 = long crs */ if (PG_NARGS() >3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3); if (option & 2 || option & 4) { /* Geography only handle srid SRID_DEFAULT */ if (option & 2) srs = getSRSbySRID(SRID_DEFAULT, true); if (option & 4) srs = getSRSbySRID(SRID_DEFAULT, false); if (!srs) { elog(ERROR, "SRID SRID_DEFAULT unknown in spatial_ref_sys table"); PG_RETURN_NULL(); } } if (option & 1) has_bbox = 1; geojson = lwgeom_to_geojson(lwgeom, srs, precision, has_bbox); lwgeom_free(lwgeom); PG_FREE_IF_COPY(g, 1); if (srs) pfree(srs); result = cstring2text(geojson); lwfree(geojson); PG_RETURN_TEXT_P(result); }
Datum geography_as_kml(PG_FUNCTION_ARGS) { GSERIALIZED *g = NULL; LWGEOM *lwgeom = NULL; char *kml; text *result; int version; int precision = OUT_MAX_DOUBLE_PRECISION; static const char *default_prefix = ""; char *prefixbuf; const char* prefix = default_prefix; text *prefix_text; /* Get the version */ version = PG_GETARG_INT32(0); if ( version != 2) { elog(ERROR, "Only KML 2 is supported"); PG_RETURN_NULL(); } /* Get the geometry */ if ( PG_ARGISNULL(1) ) PG_RETURN_NULL(); g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); /* Convert to lwgeom so we can run the old functions */ lwgeom = lwgeom_from_gserialized(g); /* Retrieve precision if any (default is max) */ if (PG_NARGS() >2 && !PG_ARGISNULL(2)) { precision = PG_GETARG_INT32(2); if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision = OUT_MAX_DOUBLE_PRECISION; else if ( precision < 0 ) precision = 0; } /* retrieve prefix */ if (PG_NARGS() >3 && !PG_ARGISNULL(3)) { prefix_text = PG_GETARG_TEXT_P(3); if ( VARSIZE(prefix_text)-VARHDRSZ == 0 ) { prefix = ""; } else { /* +2 is one for the ':' and one for term null */ prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2); memcpy(prefixbuf, VARDATA(prefix_text), VARSIZE(prefix_text)-VARHDRSZ); /* add colon and null terminate */ prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':'; prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0'; prefix = prefixbuf; } } kml = lwgeom_to_kml2(lwgeom, precision, prefix); lwgeom_free(lwgeom); PG_FREE_IF_COPY(g, 1); if ( ! kml ) PG_RETURN_NULL(); result = cstring2text(kml); lwfree(kml); PG_RETURN_TEXT_P(result); }
Datum geography_as_gml(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; GSERIALIZED *g = NULL; char *gml; text *result; int version; char *srs; int srid = SRID_DEFAULT; int precision = OUT_MAX_DOUBLE_PRECISION; int option=0; int lwopts = LW_GML_IS_DIMS; static const char *default_prefix = "gml:"; const char *prefix = default_prefix; char *prefix_buf = ""; text *prefix_text, *id_text = NULL; const char *id=NULL; char *id_buf; /* Get the version */ version = PG_GETARG_INT32(0); if ( version != 2 && version != 3 ) { elog(ERROR, "Only GML 2 and GML 3 are supported"); PG_RETURN_NULL(); } /* Get the geography */ if ( PG_ARGISNULL(1) ) PG_RETURN_NULL(); g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); /* Convert to lwgeom so we can run the old functions */ lwgeom = lwgeom_from_gserialized(g); /* Retrieve precision if any (default is max) */ if (PG_NARGS() >2 && !PG_ARGISNULL(2)) { precision = PG_GETARG_INT32(2); if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision = OUT_MAX_DOUBLE_PRECISION; else if ( precision < 0 ) precision = 0; } /* retrieve option */ if (PG_NARGS() >3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3); /* retrieve prefix */ if (PG_NARGS() >4 && !PG_ARGISNULL(4)) { prefix_text = PG_GETARG_TEXT_P(4); if ( VARSIZE(prefix_text)-VARHDRSZ == 0 ) { prefix = ""; } else { /* +2 is one for the ':' and one for term null */ prefix_buf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2); memcpy(prefix_buf, VARDATA(prefix_text), VARSIZE(prefix_text)-VARHDRSZ); /* add colon and null terminate */ prefix_buf[VARSIZE(prefix_text)-VARHDRSZ] = ':'; prefix_buf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0'; prefix = prefix_buf; } } /* retrieve id */ if (PG_NARGS() >5 && !PG_ARGISNULL(5)) { prefix_text = PG_GETARG_TEXT_P(5); if ( VARSIZE(id_text)-VARHDRSZ == 0 ) { id = ""; } else { id_buf = palloc(VARSIZE(id_text)-VARHDRSZ+1); memcpy(id_buf, VARDATA(id_text), VARSIZE(id_text)-VARHDRSZ); prefix_buf[VARSIZE(id_text)-VARHDRSZ+1] = '\0'; id = id_buf; } } if (option & 1) srs = getSRSbySRID(srid, false); else srs = getSRSbySRID(srid, true); if (!srs) { elog(ERROR, "SRID %d unknown in spatial_ref_sys table", SRID_DEFAULT); PG_RETURN_NULL(); } /* Revert lat/lon only with long SRS */ if (option & 1) lwopts |= LW_GML_IS_DEGREE; if (option & 2) lwopts &= ~LW_GML_IS_DIMS; if (version == 2) gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix); else gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id); lwgeom_free(lwgeom); PG_FREE_IF_COPY(g, 1); /* Return null on null */ if ( ! gml ) PG_RETURN_NULL(); /* Turn string result into text for return */ result = cstring2text(gml); lwfree(gml); PG_RETURN_TEXT_P(result); }
Datum LWGEOM_to_latlon(PG_FUNCTION_ARGS) { /* Get the parameters */ GSERIALIZED *pg_lwgeom = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); text *format_text = PG_GETARG_TEXT_P(1); LWGEOM *lwgeom; char *format_str = NULL; char * formatted_str; text * formatted_text; char * tmp; /* Only supports points. */ uint8_t geom_type = gserialized_get_type(pg_lwgeom); if (POINTTYPE != geom_type) { lwerror("Only points are supported, you tried type %s.", lwtype_name(geom_type)); } /* Convert to LWGEOM type */ lwgeom = lwgeom_from_gserialized(pg_lwgeom); if (format_text == NULL) { lwerror("ST_AsLatLonText: invalid format string (null"); PG_RETURN_NULL(); } format_str = text2cstring(format_text); assert(format_str != NULL); /* The input string supposedly will be in the database encoding, so convert to UTF-8. */ tmp = (char *)pg_do_encoding_conversion( (uint8_t *)format_str, strlen(format_str), GetDatabaseEncoding(), PG_UTF8); assert(tmp != NULL); if ( tmp != format_str ) { pfree(format_str); format_str = tmp; } /* Produce the formatted string. */ formatted_str = lwpoint_to_latlon((LWPOINT *)lwgeom, format_str); assert(formatted_str != NULL); pfree(format_str); /* Convert the formatted string from UTF-8 back to database encoding. */ tmp = (char *)pg_do_encoding_conversion( (uint8_t *)formatted_str, strlen(formatted_str), PG_UTF8, GetDatabaseEncoding()); assert(tmp != NULL); if ( tmp != formatted_str) { pfree(formatted_str); formatted_str = tmp; } /* Convert to the postgres output string type. */ formatted_text = cstring2text(formatted_str); pfree(formatted_str); PG_RETURN_POINTER(formatted_text); }
Datum postgis_sfcgal_version(PG_FUNCTION_ARGS) { const char *ver = lwgeom_sfcgal_version(); text *result = cstring2text(ver); PG_RETURN_POINTER(result); }
Datum postgis_proj_version(PG_FUNCTION_ARGS) { const char *ver = pj_get_release(); text *result = cstring2text(ver); PG_RETURN_POINTER(result); }