/* Find length of this serialized point */ size_t lwgeom_size_point(const uchar *serialized_point) { uint32 result = 1; uchar type; const uchar *loc; type = serialized_point[0]; if ( lwgeom_getType(type) != POINTTYPE) return 0; LWDEBUGF(2, "lwgeom_size_point called (%d)", result); loc = serialized_point+1; if (lwgeom_hasBBOX(type)) { loc += sizeof(BOX2DFLOAT4); result +=sizeof(BOX2DFLOAT4); LWDEBUGF(3, "lwgeom_size_point: has bbox (%d)", result); } if ( lwgeom_hasSRID(type)) { LWDEBUGF(3, "lwgeom_size_point: has srid (%d)", result); loc +=4; /* type + SRID */ result +=4; } result += lwgeom_ndims(type)*sizeof(double); return result; }
/* * given the LWGEOM serialized form (or a pointer into a muli* one) * construct a proper LWLINE. * serialized_form should point to the 8bit type format (with type = 2) * See serialized form doc */ LWLINE * lwline_deserialize(uchar *serialized_form) { uchar type; LWLINE *result; uchar *loc =NULL; uint32 npoints; POINTARRAY *pa; type = (uchar) serialized_form[0]; if ( lwgeom_getType(type) != LINETYPE) { lwerror("lwline_deserialize: attempt to deserialize a line which is really a %s", lwgeom_typename(type)); return NULL; } result = (LWLINE*) lwalloc(sizeof(LWLINE)) ; result->type = type; loc = serialized_form+1; if (lwgeom_hasBBOX(type)) { LWDEBUG(3, "lwline_deserialize: input has bbox"); result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); } else { result->bbox = NULL; /*lwnotice("line has NO bbox"); */ } if ( lwgeom_hasSRID(type)) { /*lwnotice("line has srid"); */ result->SRID = lw_get_int32(loc); loc +=4; /* type + SRID */ } else { /*lwnotice("line has NO srid"); */ result->SRID = -1; } /* we've read the type (1 byte) and SRID (4 bytes, if present) */ npoints = lw_get_uint32(loc); /*lwnotice("line npoints = %d", npoints); */ loc +=4; pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints); result->points = pa; return result; }
/* * Given the LWPOINT serialized form (or a pointer into a muli* one) * construct a proper LWPOINT. * serialized_form should point to the 8bit type format (with type = 1) * See serialized form doc */ LWPOINT * lwpoint_deserialize(uchar *serialized_form) { uchar type; int geom_type; LWPOINT *result; uchar *loc = NULL; POINTARRAY *pa; LWDEBUG(2, "lwpoint_deserialize called"); result = (LWPOINT*) lwalloc(sizeof(LWPOINT)) ; type = serialized_form[0]; geom_type = lwgeom_getType(type); if ( geom_type != POINTTYPE) { lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type)); return NULL; } result->type = type; loc = serialized_form+1; if (lwgeom_hasBBOX(type)) { LWDEBUG(3, "lwpoint_deserialize: input has bbox"); result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); } else { result->bbox = NULL; } if ( lwgeom_hasSRID(type)) { LWDEBUG(3, "lwpoint_deserialize: input has SRID"); result->SRID = lw_get_int32(loc); loc += 4; /* type + SRID */ } else { result->SRID = -1; } /* we've read the type (1 byte) and SRID (4 bytes, if present) */ pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1); result->point = pa; return result; }
LWCURVEPOLY * lwcurvepoly_deserialize(uchar *srl) { LWCURVEPOLY *result; LWGEOM_INSPECTED *insp; int type = lwgeom_getType(srl[0]); int i; LWDEBUG(3, "lwcurvepoly_deserialize called."); if (type != CURVEPOLYTYPE) { lwerror("lwcurvepoly_deserialize called on NON curvepoly: %d", type); return NULL; } insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWCURVEPOLY)); result->type = insp->type; result->SRID = insp->SRID; result->nrings = insp->ngeometries; result->rings = lwalloc(sizeof(LWGEOM *)*insp->ngeometries); if (lwgeom_hasBBOX(srl[0])) { result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4)); } else result->bbox = NULL; for (i = 0; i < insp->ngeometries; i++) { result->rings[i] = lwgeom_deserialize(insp->sub_geoms[i]); if (lwgeom_getType(result->rings[i]->type) != CIRCSTRINGTYPE && lwgeom_getType(result->rings[i]->type) != LINETYPE && lwgeom_getType(result->rings[i]->type) != COMPOUNDTYPE) { lwerror("Only Circular curves, Linestrings and Compound curves are supported as rings, not %s (%d)", lwgeom_typename(result->rings[i]->type), result->rings[i]->type); lwfree(result); lwfree(insp); return NULL; } if (TYPE_NDIMS(result->rings[i]->type) != TYPE_NDIMS(result->type)) { lwerror("Mixed dimensions (curvepoly %d, ring %d)", TYPE_NDIMS(result->type), i, TYPE_NDIMS(result->rings[i]->type)); lwfree(result); lwfree(insp); return NULL; } } return result; }
LWMPOLY * lwmpoly_deserialize(uchar *srl) { LWMPOLY *result; LWGEOM_INSPECTED *insp; int type = lwgeom_getType(srl[0]); int i; LWDEBUG(2, "lwmpoly_deserialize called"); if ( type != MULTIPOLYGONTYPE ) { lwerror("lwmpoly_deserialize called on NON multipoly: %d", type); return NULL; } insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOLY)); result->type = insp->type; result->SRID = insp->SRID; result->ngeoms = insp->ngeometries; if ( insp->ngeometries ) { result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries); } else { result->geoms = NULL; } if (lwgeom_hasBBOX(srl[0])) { result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4)); } else result->bbox = NULL; for (i=0; i<insp->ngeometries; i++) { result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]); if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) ) { lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)", TYPE_NDIMS(result->type), i, TYPE_NDIMS(result->geoms[i]->type) ); return NULL; } } return result; }
Datum LWGEOM_setSRID(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int newSRID = PG_GETARG_INT32(1); PG_LWGEOM *result; result = PG_LWGEOM_construct(SERIALIZED_FORM(geom), newSRID, lwgeom_hasBBOX(geom->type)); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
LWCOMPOUND * lwcompound_deserialize(uchar *serialized) { LWCOMPOUND *result; LWGEOM_INSPECTED *insp; int type = lwgeom_getType(serialized[0]); int i; if(type != COMPOUNDTYPE) { lwerror("lwcompound_deserialize called on non compound: %d", type); return NULL; } insp = lwgeom_inspect(serialized); result = lwalloc(sizeof(LWCOMPOUND)); result->type = insp->type; result->SRID = insp->SRID; result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries); if(lwgeom_hasBBOX(serialized[0])) { result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, serialized + 1, sizeof(BOX2DFLOAT4)); } else result->bbox = NULL; for(i = 0; i < insp->ngeometries; i++) { if(lwgeom_getType(insp->sub_geoms[i][0]) == LINETYPE) result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]); else result->geoms[i] = (LWGEOM *)lwcircstring_deserialize(insp->sub_geoms[i]); if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type)) { lwerror("Mixed dimensions (compound: %d, line/circularstring %d:%d)", TYPE_NDIMS(result->type), i, TYPE_NDIMS(result->geoms[i]->type) ); lwfree(result); return NULL; } } return result; }
/* find length of this serialized line */ size_t lwgeom_size_line(const uchar *serialized_line) { int type = (uchar) serialized_line[0]; uint32 result = 1; /*type */ const uchar *loc; uint32 npoints; LWDEBUG(2, "lwgeom_size_line called"); if ( lwgeom_getType(type) != LINETYPE) lwerror("lwgeom_size_line::attempt to find the length of a non-line"); loc = serialized_line+1; if (lwgeom_hasBBOX(type)) { loc += sizeof(BOX2DFLOAT4); result +=sizeof(BOX2DFLOAT4); } if ( lwgeom_hasSRID(type)) { loc += 4; /* type + SRID */ result +=4; } /* we've read the type (1 byte) and SRID (4 bytes, if present) */ npoints = lw_get_uint32(loc); result += sizeof(uint32); /* npoints */ result += TYPE_NDIMS(type) * sizeof(double) * npoints; LWDEBUGF(3, "lwgeom_size_line returning %d", result); return result; }
LWMCURVE * lwmcurve_deserialize(uchar *srl) { LWMCURVE *result; LWGEOM_INSPECTED *insp; int stype; int type = lwgeom_getType(srl[0]); int i; if (type != MULTICURVETYPE) { lwerror("lwmcurve_deserialize called on NON multicurve: %d", type); return NULL; } insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMCURVE)); result->type = insp->type; result->SRID = insp->SRID; result->ngeoms = insp->ngeometries; if ( insp->ngeometries ) { result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries); } else { result->geoms = NULL; } if (lwgeom_hasBBOX(srl[0])) { result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4)); } else result->bbox = NULL; for (i = 0; i < insp->ngeometries; i++) { stype = lwgeom_getType(insp->sub_geoms[i][0]); if (stype == CIRCSTRINGTYPE) { result->geoms[i] = (LWGEOM *)lwcircstring_deserialize(insp->sub_geoms[i]); } else if (stype == LINETYPE) { result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]); } else if (stype == COMPOUNDTYPE) { result->geoms[i] = (LWGEOM *)lwcompound_deserialize(insp->sub_geoms[i]); } else { lwerror("Only Circular strings, Line strings or Compound curves are permitted in a MultiCurve."); lwfree(result); lwfree(insp); return NULL; } if (TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type)) { lwerror("Mixed dimensions (multicurve: %d, curve %d:%d)", TYPE_NDIMS(result->type), i, TYPE_NDIMS(result->geoms[i]->type)); lwfree(result); lwfree(insp); return NULL; } } return result; }
/* * given the LWGEOM serialized form (or a point into a multi* one) * construct a proper LWCIRCSTRING. * serialized_form should point to the 8bit type format (with type = 8) * See serialized form doc */ LWCIRCSTRING * lwcircstring_deserialize(uchar *serialized_form) { uchar type; LWCIRCSTRING *result; uchar *loc=NULL; uint32 npoints; POINTARRAY *pa; type = (uchar)serialized_form[0]; if (lwgeom_getType(type) != CIRCSTRINGTYPE) { lwerror("lwcircstring_deserialize: attempt to deserialize a circularstring which is really a %s", lwgeom_typename(type)); return NULL; } result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING)); result->type = type; loc = serialized_form + 1; if (lwgeom_hasBBOX(type)) { LWDEBUG(3, "lwcircstring_deserialize: input has bbox"); result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); } else { LWDEBUG(3, "lwcircstring_deserialize: input lacks bbox"); result->bbox = NULL; } if (lwgeom_hasSRID(type)) { LWDEBUG(3, "lwcircstring_deserialize: input has srid"); result->SRID = lw_get_int32(loc); loc += 4; /* type + SRID */ } else { LWDEBUG(3, "lwcircstring_deserialize: input lacks srid"); result->SRID = -1; } /* we've read the type (1 byte) and SRID (4 bytes, if present) */ npoints = lw_get_uint32(loc); LWDEBUGF(3, "circstring npoints = %d", npoints); loc += 4; pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints); result->points = pa; return result; }
LWMSURFACE * lwmsurface_deserialize(uchar *srl) { LWMSURFACE *result; LWGEOM_INSPECTED *insp; int stype; int type = lwgeom_getType(srl[0]); int i; LWDEBUG(2, "lwmsurface_deserialize called"); if (type != MULTISURFACETYPE) { lwerror("lwmsurface_deserialize called on a non-multisurface: %d", type); return NULL; } insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMSURFACE)); result->type = insp->type; result->SRID = insp->SRID; result->ngeoms = insp->ngeometries; if ( insp->ngeometries ) { result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries); } else { result->geoms = NULL; } if (lwgeom_hasBBOX(srl[0])) { result->bbox = lwalloc(sizeof(BOX2DFLOAT4)); memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4)); } else result->bbox = NULL; for (i = 0; i < insp->ngeometries; i++) { stype = lwgeom_getType(insp->sub_geoms[i][0]); if (stype == POLYGONTYPE) { result->geoms[i] = (LWGEOM *)lwpoly_deserialize(insp->sub_geoms[i]); } else if (stype == CURVEPOLYTYPE) { result->geoms[i] = (LWGEOM *)lwcurvepoly_deserialize(insp->sub_geoms[i]); } else { lwerror("Only Polygons and Curved Polygons are supported in a MultiSurface."); lwfree(result); lwfree(insp); return NULL; } if (TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type)) { lwerror("Mixed dimensions (multisurface: %d, surface %d:%d", TYPE_NDIMS(result->type), i, TYPE_NDIMS(result->geoms[i]->type)); lwfree(result); lwfree(insp); return NULL; } } return result; }