Datum LWGEOM_from_WKB(PG_FUNCTION_ARGS) { GSERIALIZED *geom; int32 srid; GSERIALIZED *result = NULL; geom = (GSERIALIZED *)DatumGetPointer(DirectFunctionCall1( LWGEOMFromWKB, PG_GETARG_DATUM(0))); if ( gserialized_get_srid(geom) != SRID_UNKNOWN ) { elog(WARNING, "OGC WKB expected, EWKB provided - use GeometryFromEWKB() for this"); } /* read user-requested SRID if any */ if ( PG_NARGS() > 1 ) { srid = PG_GETARG_INT32(1); if ( srid != gserialized_get_srid(geom) ) gserialized_set_srid(geom, srid); } if ( ! result ) result = geom; PG_RETURN_POINTER(result); }
Datum LWGEOM_set_srid(PG_FUNCTION_ARGS) { GSERIALIZED *g = (GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); int srid = PG_GETARG_INT32(1); gserialized_set_srid(g, srid); PG_RETURN_POINTER(g); }
Datum LWGEOM_from_WKB(PG_FUNCTION_ARGS) { bytea *bytea_wkb = (bytea*)PG_GETARG_BYTEA_P(0); int32 srid = 0; GSERIALIZED *geom; LWGEOM *lwgeom; uint8_t *wkb = (uint8_t*)VARDATA(bytea_wkb); lwgeom = lwgeom_from_wkb(wkb, VARSIZE(bytea_wkb)-VARHDRSZ, LW_PARSER_CHECK_ALL); if ( lwgeom_needs_bbox(lwgeom) ) lwgeom_add_bbox(lwgeom); geom = geometry_serialize(lwgeom); lwgeom_free(lwgeom); PG_FREE_IF_COPY(bytea_wkb, 0); if ( gserialized_get_srid(geom) != SRID_UNKNOWN ) { elog(WARNING, "OGC WKB expected, EWKB provided - use GeometryFromEWKB() for this"); } if ( PG_NARGS() > 1 ) { srid = PG_GETARG_INT32(1); if ( srid != gserialized_get_srid(geom) ) gserialized_set_srid(geom, srid); } PG_RETURN_POINTER(geom); }
GSERIALIZED* gserialized_from_lwgeom(LWGEOM *geom, int is_geodetic, size_t *size) { size_t expected_size = 0; size_t return_size = 0; uint8_t *serialized = NULL; uint8_t *ptr = NULL; GSERIALIZED *g = NULL; assert(geom); /* ** See if we need a bounding box, add one if we don't have one. */ if ( (! geom->bbox) && lwgeom_needs_bbox(geom) && (!lwgeom_is_empty(geom)) ) { lwgeom_add_bbox(geom); } /* ** Harmonize the flags to the state of the lwgeom */ if ( geom->bbox ) FLAGS_SET_BBOX(geom->flags, 1); /* Set up the uint8_t buffer into which we are going to write the serialized geometry. */ expected_size = gserialized_from_lwgeom_size(geom); serialized = lwalloc(expected_size); ptr = serialized; /* Move past size, srid and flags. */ ptr += 8; /* Write in the serialized form of the gbox, if necessary. */ if ( geom->bbox ) ptr += gserialized_from_gbox(geom->bbox, ptr); /* Write in the serialized form of the geometry. */ ptr += gserialized_from_lwgeom_any(geom, ptr); /* Calculate size as returned by data processing functions. */ return_size = ptr - serialized; if ( expected_size != return_size ) /* Uh oh! */ { lwerror("Return size (%d) not equal to expected size (%d)!", return_size, expected_size); return NULL; } if ( size ) /* Return the output size to the caller if necessary. */ *size = return_size; g = (GSERIALIZED*)serialized; /* ** We are aping PgSQL code here, PostGIS code should use ** VARSIZE to set this for real. */ g->size = return_size << 2; /* Set the SRID! */ gserialized_set_srid(g, geom->srid); g->flags = geom->flags; return g; }
Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) { BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0); POINTARRAY *pa; GSERIALIZED *result; POINT4D pt; /** * Alter BOX3D cast so that a valid geometry is always * returned depending upon the size of the BOX3D. The * code makes the following assumptions: * - If the BOX3D is a single point then return a * POINT geometry * - If the BOX3D represents either a horizontal or * vertical line, return a LINESTRING geometry * - Otherwise return a POLYGON */ pa = ptarray_construct_empty(0, 0, 5); if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) ) { LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa); pt.x = box->xmin; pt.y = box->ymin; ptarray_append_point(pa, &pt, LW_TRUE); result = geometry_serialize(lwpoint_as_lwgeom(lwpt)); } else if (box->xmin == box->xmax || box->ymin == box->ymax) { LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa); pt.x = box->xmin; pt.y = box->ymin; ptarray_append_point(pa, &pt, LW_TRUE); pt.x = box->xmax; pt.y = box->ymax; ptarray_append_point(pa, &pt, LW_TRUE); result = geometry_serialize(lwline_as_lwgeom(lwline)); } else { LWPOLY *lwpoly = lwpoly_construct(SRID_UNKNOWN, NULL, 1, &pa); pt.x = box->xmin; pt.y = box->ymin; ptarray_append_point(pa, &pt, LW_TRUE); pt.x = box->xmin; pt.y = box->ymax; ptarray_append_point(pa, &pt, LW_TRUE); pt.x = box->xmax; pt.y = box->ymax; ptarray_append_point(pa, &pt, LW_TRUE); pt.x = box->xmax; pt.y = box->ymin; ptarray_append_point(pa, &pt, LW_TRUE); pt.x = box->xmin; pt.y = box->ymin; ptarray_append_point(pa, &pt, LW_TRUE); result = geometry_serialize(lwpoly_as_lwgeom(lwpoly)); } gserialized_set_srid(result, box->srid); PG_RETURN_POINTER(result); }