Datum geometry_geometrytype(PG_FUNCTION_ARGS) { PG_LWGEOM *lwgeom; char *type_text; char *type_str = palloc(32); size_t size; lwgeom = (PG_LWGEOM*)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, lwgeom_typename(lwgeom_getType(lwgeom->type)), 32); size = strlen(type_str) + VARHDRSZ; /* Build a text type to store things in */ type_text = lwalloc(size); memcpy(VARDATA(type_text),type_str, size - VARHDRSZ); pfree(type_str); SET_VARSIZE(type_text, size); PG_FREE_IF_COPY(lwgeom, 0); PG_RETURN_POINTER(type_text); }
char * lwpoly_summary(LWPOLY *poly, int offset) { char tmp[256]; size_t size = 64*(poly->nrings+1)+128; char *result; int i; char *pad=""; LWDEBUG(2, "lwpoly_summary called"); result = lwalloc(size); sprintf(result, "%*.s%s[%s] with %i rings\n", offset, pad, lwgeom_typename(TYPE_GETTYPE(poly->type)), lwgeom_typeflags(poly->type), poly->nrings); for (i=0; i<poly->nrings; i++) { sprintf(tmp,"%s ring %i has %i points\n", pad, i, poly->rings[i]->npoints); strcat(result,tmp); } LWDEBUG(3, "lwpoly_summary returning"); return result; }
char * lwcollection_summary(LWCOLLECTION *col, int offset) { size_t size = 128; char *result; char *tmp; int i; char *pad=""; LWDEBUG(2, "lwcollection_summary called"); result = (char *)lwalloc(size); sprintf(result, "%*.s%s[%s] with %d elements\n", offset, pad, lwgeom_typename(TYPE_GETTYPE(col->type)), lwgeom_typeflags(col->type), col->ngeoms); for (i=0; i<col->ngeoms; i++) { tmp = lwgeom_summary(col->geoms[i], offset+2); size += strlen(tmp)+1; result = lwrealloc(result, size); LWDEBUGF(4, "Reallocated %d bytes for result", size); strcat(result, tmp); lwfree(tmp); } LWDEBUG(3, "lwcollection_summary returning"); 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; }
/* * Returns an alloced string containing summary for the LWGEOM object */ char * lwpoint_summary(LWPOINT *point, int offset) { char *result; char *pad=""; result = lwalloc(128+offset); sprintf(result, "%*.s%s[%s]\n", offset, pad, lwgeom_typename(TYPE_GETTYPE(point->type)), lwgeom_typeflags(point->type)); return result; }
char * lwline_summary(LWLINE *line, int offset) { char *result; char *pad=""; result = lwalloc(128+offset); sprintf(result, "%*.s%s[%s] with %d points\n", offset, pad, lwgeom_typename(TYPE_GETTYPE(line->type)), lwgeom_typeflags(line->type), line->points->npoints); return result; }
/* * Construct a LWLINE from an array of LWPOINTs * LWLINE dimensions are large enough to host all input dimensions. */ LWLINE * lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points) { int zmflag=0; unsigned int i; POINTARRAY *pa; uchar *newpoints, *ptr; size_t ptsize, size; /* * Find output dimensions, check integrity */ for (i=0; i<npoints; i++) { if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE ) { lwerror("lwline_from_lwpointarray: invalid input type: %s", lwgeom_typename(TYPE_GETTYPE(points[i]->type))); return NULL; } if ( TYPE_HASZ(points[i]->type) ) zmflag |= 2; if ( TYPE_HASM(points[i]->type) ) zmflag |= 1; if ( zmflag == 3 ) break; } if ( zmflag == 0 ) ptsize=2*sizeof(double); else if ( zmflag == 3 ) ptsize=4*sizeof(double); else ptsize=3*sizeof(double); /* * Allocate output points array */ size = ptsize*npoints; newpoints = lwalloc(size); memset(newpoints, 0, size); ptr=newpoints; for (i=0; i<npoints; i++) { size=pointArray_ptsize(points[i]->point); memcpy(ptr, getPoint_internal(points[i]->point, 0), size); ptr+=ptsize; } pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints); return lwline_construct(SRID, NULL, pa); }
/* * 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; }
/* * 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; }
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) { lwerror("Only Circularstrings and Linestrings are currently 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; }