static int lwcircstring_calculate_gbox(LWCIRCSTRING *curve, GBOX *gbox) { uchar flags = gflags(TYPE_HASZ(curve->type), TYPE_HASM(curve->type), 0); GBOX tmp; POINT4D p1, p2, p3; int i; if ( ! curve ) return G_FAILURE; if ( curve->points->npoints < 3 ) return G_FAILURE; tmp.flags = flags; /* Initialize */ gbox->xmin = gbox->ymin = gbox->zmin = gbox->mmin = MAXFLOAT; gbox->xmax = gbox->ymax = gbox->zmax = gbox->mmax = -1 * MAXFLOAT; for ( i = 2; i < curve->points->npoints; i += 2 ) { getPoint4d_p(curve->points, i-2, &p1); getPoint4d_p(curve->points, i-1, &p2); getPoint4d_p(curve->points, i, &p3); if (lwcircle_calculate_gbox(p1, p2, p3, &tmp) == G_FAILURE) continue; gbox_merge(&tmp, gbox); } return G_SUCCESS; }
char compound_is_closed(LWCOMPOUND *compound) { POINT3DZ sp, ep; LWGEOM *tmp; LWDEBUG(2, "compound_is_closed called."); tmp = compound->geoms[0]; if (lwgeom_getType(tmp->type) == LINETYPE) { getPoint3dz_p(((LWLINE *)tmp)->points, 0, &sp); } else { getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, 0, &sp); } tmp = compound->geoms[compound->ngeoms - 1]; if (lwgeom_getType(tmp->type) == LINETYPE) { getPoint3dz_p(((LWLINE *)tmp)->points, ((LWLINE *)tmp)->points->npoints - 1, &ep); } else { getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, ((LWCIRCSTRING *)tmp)->points->npoints - 1, &ep); } if (sp.x != ep.x) return 0; if (sp.y != ep.y) return 0; if (TYPE_HASZ(compound->type)) { if (sp.z != ep.z) return 0; } return 1; }
/* * Construct a new LWCIRCSTRING. points will *NOT* be copied * use SRID=-1 for unknown SRID (will have 8bit type's S = 0) */ LWCIRCSTRING * lwcircstring_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points) { LWCIRCSTRING *result; /* * The first arc requires three points. Each additional * arc requires two more points. Thus the minimum point count * is three, and the count must be odd. */ if (points->npoints % 2 != 1 || points->npoints < 3) { lwerror("lwcircstring_construct: invalid point count %d", points->npoints); return NULL; } result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING)); result->type = lwgeom_makeType_full( TYPE_HASZ(points->dims), TYPE_HASM(points->dims), (SRID!=-1), CIRCSTRINGTYPE, 0); result->SRID = SRID; result->points = points; result->bbox = bbox; 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; }
Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; POINTARRAY *pts; LWPOINT *point; PG_LWGEOM *result; int i, type; POSTGIS_DEBUG(2, "LWGEOM_startpoint_linestring called."); geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* * Curved polygons and compound curves are both collections * that should not be traversed looking for linestrings. */ type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { line = lwgeom_getline_inspected(inspected, i); if ( line ) break; } if ( line == NULL ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } /* Ok, now we have a line. */ /* Construct a point array */ pts = pointArray_construct(getPoint_internal(line->points, 0), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); lwgeom_release((LWGEOM *)line); /* Construct an LWPOINT */ point = lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Construct a PG_LWGEOM */ result = pglwgeom_serialize((LWGEOM *)point); lwgeom_release((LWGEOM *)point); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(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; }
/** * Re-write the measure ordinate (or add one, if it isn't already there) interpolating * the measure between the supplied start and end values. */ LWLINE* lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end) { int i = 0; int hasm = 0, hasz = 0; int npoints = 0; double length = 0.0; double length_so_far = 0.0; double m_range = m_end - m_start; double m; POINTARRAY *pa = NULL; POINT3DZ p1, p2; if ( TYPE_GETTYPE(lwline->type) != LINETYPE ) { lwerror("lwline_construct_from_lwline: only line types supported"); return NULL; } hasz = TYPE_HASZ(lwline->type); hasm = 1; /* Null points or npoints == 0 will result in empty return geometry */ if ( lwline->points ) { npoints = lwline->points->npoints; length = lwgeom_pointarray_length2d(lwline->points); getPoint3dz_p(lwline->points, 0, &p1); } pa = ptarray_construct(hasz, hasm, npoints); for ( i = 0; i < npoints; i++ ) { POINT4D q; POINT2D a, b; getPoint3dz_p(lwline->points, i, &p2); a.x = p1.x; a.y = p1.y; b.x = p2.x; b.y = p2.y; length_so_far += distance2d_pt_pt(&a, &b); if ( length > 0.0 ) m = m_start + m_range * length_so_far / length; else m = 0.0; q.x = p2.x; q.y = p2.y; q.z = p2.z; q.m = m; setPoint4d(pa, i, &q); p1 = p2; } return lwline_construct(lwline->SRID, NULL, pa); }
Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; POINTARRAY *pts; LWGEOM *point; PG_LWGEOM *result; int i, type; POSTGIS_DEBUG(2, "LWGEOM_endpoint_linestring called."); geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { line = lwgeom_getline_inspected(inspected, i); if ( line ) break; } lwinspected_release(inspected); if ( line == NULL ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } /* Ok, now we have a line. */ /* Construct a point array */ pts = pointArray_construct( getPoint_internal(line->points, line->points->npoints-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); lwgeom_release((LWGEOM *)line); /* Construct an LWPOINT */ point = (LWGEOM *)lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Serialize an PG_LWGEOM */ result = pglwgeom_serialize(point); lwgeom_release(point); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS) { PG_LWGEOM *lwgeom; char *text_ob; char *result; int32 size; uchar type; lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); text_ob = lwalloc(20+VARHDRSZ); result = text_ob+VARHDRSZ; type = lwgeom_getType(lwgeom->type); memset(VARDATA(text_ob), 0, 20); if (type == POINTTYPE) strcpy(result,"POINT"); else if (type == MULTIPOINTTYPE) strcpy(result,"MULTIPOINT"); else if (type == LINETYPE) strcpy(result,"LINESTRING"); else if (type == CIRCSTRINGTYPE) strcpy(result,"CIRCULARSTRING"); else if (type == COMPOUNDTYPE) strcpy(result, "COMPOUNDCURVE"); else if (type == MULTILINETYPE) strcpy(result,"MULTILINESTRING"); else if (type == MULTICURVETYPE) strcpy(result, "MULTICURVE"); else if (type == POLYGONTYPE) strcpy(result,"POLYGON"); else if (type == CURVEPOLYTYPE) strcpy(result,"CURVEPOLYGON"); else if (type == MULTIPOLYGONTYPE) strcpy(result,"MULTIPOLYGON"); else if (type == MULTISURFACETYPE) strcpy(result, "MULTISURFACE"); else if (type == COLLECTIONTYPE) strcpy(result,"GEOMETRYCOLLECTION"); else strcpy(result,"UNKNOWN"); if ( TYPE_HASM(lwgeom->type) && ! TYPE_HASZ(lwgeom->type) ) strcat(result, "M"); size = strlen(result) + VARHDRSZ ; SET_VARSIZE(text_ob, size); /* size of string */ PG_FREE_IF_COPY(lwgeom, 0); PG_RETURN_POINTER(text_ob); }
/* * 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); }
/* * Construct a new point. point will not be copied * use SRID=-1 for unknown SRID (will have 8bit type's S = 0) */ LWPOINT * lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point) { LWPOINT *result ; if (point == NULL) return NULL; /* error */ result = lwalloc(sizeof(LWPOINT)); result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0); result->SRID = SRID; result->point = point; result->bbox = bbox; return result; }
char circstring_is_closed(LWCIRCSTRING *curve) { POINT3DZ sp, ep; LWDEBUG(2, "circstring_is_closed called."); getPoint3dz_p(curve->points, 0, &sp); getPoint3dz_p(curve->points, curve->points->npoints-1, &ep); if (sp.x != ep.x) return 0; if (sp.y != ep.y) return 0; if (TYPE_HASZ(curve->type)) { if (sp.z != ep.z) return 0; } return 1; }
char line_is_closed(LWLINE *line) { POINT3DZ sp, ep; LWDEBUG(2, "line_is_closed called."); getPoint3dz_p(line->points, 0, &sp); getPoint3dz_p(line->points, line->points->npoints-1, &ep); if ( sp.x != ep.x ) return 0; if ( sp.y != ep.y ) return 0; if ( TYPE_HASZ(line->type) ) { if ( sp.z != ep.z ) return 0; } return 1; }
/* * Convert this point into its serialize form writing it into * the given buffer, and returning number of bytes written into * the given int pointer. * result's first char will be the 8bit type. See serialized form doc */ void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize) { int size=1; char hasSRID; uchar *loc; int ptsize = pointArray_ptsize(point->point); if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) ) lwerror("Dimensions mismatch in lwpoint"); LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf); /*printLWPOINT(point); */ hasSRID = (point->SRID != -1); if (hasSRID) size +=4; /*4 byte SRID */ if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */ size += sizeof(double)*TYPE_NDIMS(point->type); buf[0] = (uchar) lwgeom_makeType_full( TYPE_HASZ(point->type), TYPE_HASM(point->type), hasSRID, POINTTYPE, point->bbox?1:0); loc = buf+1; if (point->bbox) { memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); } if (hasSRID) { memcpy(loc, &point->SRID, sizeof(int32)); loc += 4; } /* copy in points */ memcpy(loc, getPoint_internal(point->point, 0), ptsize); if (retsize) *retsize = size; }
Datum LWGEOM_z_point(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWPOINT *point = NULL; POINT3DZ p; geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); if ( TYPE_GETTYPE(geom->type) != POINTTYPE ) lwerror("Argument to Z() must be a point"); point = lwgeom_getpoint(SERIALIZED_FORM(geom), 0); /* no Z in input */ if ( ! TYPE_HASZ(geom->type) ) PG_RETURN_NULL(); getPoint3dz_p(point->point, 0, &p); PG_FREE_IF_COPY(geom, 0); PG_RETURN_FLOAT8(p.z); }
/* * Construct a new LWLINE. points will *NOT* be copied * use SRID=-1 for unknown SRID (will have 8bit type's S = 0) */ LWLINE * lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points) { LWLINE *result; result = (LWLINE*) lwalloc(sizeof(LWLINE)); LWDEBUG(2, "lwline_construct called."); result->type = lwgeom_makeType_full( TYPE_HASZ(points->dims), TYPE_HASM(points->dims), (SRID!=-1), LINETYPE, 0); LWDEBUGF(3, "lwline_construct type=%d", result->type); result->SRID = SRID; result->points = points; result->bbox = bbox; return result; }
/* * convert this line into its serialize form writing it into * the given buffer, and returning number of bytes written into * the given int pointer. * result's first char will be the 8bit type. See serialized form doc */ void lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *retsize) { char hasSRID; uchar *loc; int ptsize; size_t size; LWDEBUGF(2, "lwline_serialize_buf(%p, %p, %p) called", line, buf, retsize); if (line == NULL) lwerror("lwline_serialize:: given null line"); if ( TYPE_GETZM(line->type) != TYPE_GETZM(line->points->dims) ) lwerror("Dimensions mismatch in lwline"); ptsize = pointArray_ptsize(line->points); hasSRID = (line->SRID != -1); buf[0] = (uchar) lwgeom_makeType_full( TYPE_HASZ(line->type), TYPE_HASM(line->type), hasSRID, LINETYPE, line->bbox ? 1 : 0); loc = buf+1; LWDEBUGF(3, "lwline_serialize_buf added type (%d)", line->type); if (line->bbox) { memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); LWDEBUG(3, "lwline_serialize_buf added BBOX"); } if (hasSRID) { memcpy(loc, &line->SRID, sizeof(int32)); loc += sizeof(int32); LWDEBUG(3, "lwline_serialize_buf added SRID"); } memcpy(loc, &line->points->npoints, sizeof(uint32)); loc += sizeof(uint32); LWDEBUGF(3, "lwline_serialize_buf added npoints (%d)", line->points->npoints); /*copy in points */ size = line->points->npoints*ptsize; memcpy(loc, getPoint_internal(line->points, 0), size); loc += size; LWDEBUGF(3, "lwline_serialize_buf copied serialized_pointlist (%d bytes)", ptsize * line->points->npoints); if (retsize) *retsize = loc-buf; /*printBYTES((uchar *)result, loc-buf); */ LWDEBUGF(3, "lwline_serialize_buf returning (loc: %p, size: %d)", loc, loc-buf); }
Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; int32 wanted_index; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; LWCIRCSTRING *curve = NULL; LWGEOM *tmp = NULL; POINTARRAY *pts; LWPOINT *point; uchar *serializedpoint; PG_LWGEOM *result; int i, type; wanted_index = PG_GETARG_INT32(1); if ( wanted_index < 1 ) PG_RETURN_NULL(); /* index out of range */ geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == COMPOUNDTYPE || type == CURVEPOLYTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } else { inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { tmp = lwgeom_getgeom_inspected(inspected, i); if (lwgeom_getType(tmp->type) == LINETYPE || lwgeom_getType(tmp->type) == CIRCSTRINGTYPE) break; } if ( tmp == NULL ) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } if (lwgeom_getType(tmp->type) == CIRCSTRINGTYPE) { curve = (LWCIRCSTRING *)tmp; if (wanted_index > curve->points->npoints) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } lwinspected_release(inspected); pts = pointArray_construct(getPoint_internal( curve->points, wanted_index-1), TYPE_HASZ(curve->type), TYPE_HASM(curve->type), 1); } else if (lwgeom_getType(tmp->type) == LINETYPE) { line = (LWLINE *)tmp; /* Ok, now we have a line. Let's see if it has enough points. */ if ( wanted_index > line->points->npoints ) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } lwinspected_release(inspected); /* Construct a point array */ pts = pointArray_construct(getPoint_internal(line->points, wanted_index-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); } else { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } } /* Construct an LWPOINT */ point = lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Serialized the point */ serializedpoint = lwpoint_serialize(point); /* And we construct the line * TODO: use serialize_buf above, instead .. */ result = PG_LWGEOM_construct(serializedpoint, pglwgeom_getSRID(geom), 0); pfree(point); pfree(serializedpoint); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_POINTER(result); }
/* * convert this circularstring into its serialized form writing it into * the given buffer, and returning number of bytes written into * the given int pointer. * result's first char will be the 8bit type. See serialized form doc */ void lwcircstring_serialize_buf(LWCIRCSTRING *curve, uchar *buf, size_t *retsize) { char hasSRID; uchar *loc; int ptsize; size_t size; LWDEBUGF(2, "lwcircstring_serialize_buf(%p, %p, %p) called", curve, buf, retsize); if (curve == NULL) { lwerror("lwcircstring_serialize:: given null curve"); return; } if (TYPE_GETZM(curve->type) != TYPE_GETZM(curve->points->dims)) { lwerror("Dimensions mismatch in lwcircstring"); return; } ptsize = pointArray_ptsize(curve->points); hasSRID = (curve->SRID != -1); buf[0] = (uchar)lwgeom_makeType_full( TYPE_HASZ(curve->type), TYPE_HASM(curve->type), hasSRID, CIRCSTRINGTYPE, curve->bbox ? 1 : 0); loc = buf+1; LWDEBUGF(3, "lwcircstring_serialize_buf added type (%d)", curve->type); if (curve->bbox) { memcpy(loc, curve->bbox, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); LWDEBUG(3, "lwcircstring_serialize_buf added BBOX"); } if (hasSRID) { memcpy(loc, &curve->SRID, sizeof(int32)); loc += sizeof(int32); LWDEBUG(3, "lwcircstring_serialize_buf added SRID"); } memcpy(loc, &curve->points->npoints, sizeof(uint32)); loc += sizeof(uint32); LWDEBUGF(3, "lwcircstring_serialize_buf added npoints (%d)", curve->points->npoints); /* copy in points */ size = curve->points->npoints * ptsize; memcpy(loc, getPoint_internal(curve->points, 0), size); loc += size; LWDEBUGF(3, "lwcircstring_serialize_buf copied serialized_pointlist (%d bytes)", ptsize * curve->points->npoints); if (retsize) *retsize = loc-buf; LWDEBUGF(3, "lwcircstring_serialize_buf returning (loc: %p, size: %d)", loc, loc-buf); }
/* * 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; }