mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 17:12:35 +00:00
Fixed bug in box3d computation.
Dropped obsoleted LWGEOM_EXPLODED structure and associated functions. git-svn-id: http://svn.osgeo.org/postgis/trunk@1555 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
7b327f64f2
commit
5115b8221c
|
@ -596,49 +596,6 @@ typedef struct
|
|||
|
||||
extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number);
|
||||
|
||||
/*
|
||||
* This structure is intended to be used for geometry collection construction.
|
||||
* Does not allow specification of collection structure
|
||||
* (serialization chooses the simpler form)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int SRID;
|
||||
uchar dims;
|
||||
uint32 npoints;
|
||||
uchar **points;
|
||||
uint32 nlines;
|
||||
uchar **lines;
|
||||
uint32 npolys;
|
||||
uchar **polys;
|
||||
} LWGEOM_EXPLODED;
|
||||
|
||||
void pfree_exploded(LWGEOM_EXPLODED *exploded);
|
||||
|
||||
// Returns a 'palloced' union of the two input exploded geoms.
|
||||
// Returns NULL if SRID or ndims do not match.
|
||||
LWGEOM_EXPLODED * lwexploded_sum(LWGEOM_EXPLODED *exp1, LWGEOM_EXPLODED *exp2);
|
||||
|
||||
/*
|
||||
* This function recursively scan the given serialized geometry
|
||||
* and returns a list of _all_ subgeoms in it (deep-first)
|
||||
*/
|
||||
extern LWGEOM_EXPLODED *lwgeom_explode(uchar *serialized);
|
||||
|
||||
/*
|
||||
* Return the length of the serialized form corresponding
|
||||
* to this exploded structure.
|
||||
*/
|
||||
extern size_t lwexploded_findlength(LWGEOM_EXPLODED *exp, int wantbbox);
|
||||
|
||||
// Serialize an LWGEOM_EXPLODED object.
|
||||
// SRID and ndims will be taken from exploded structure.
|
||||
// wantbbox will determine result bbox.
|
||||
extern uchar *lwexploded_serialize(LWGEOM_EXPLODED *exploded, int wantbbox);
|
||||
|
||||
// Same as lwexploded_serialize but writing to pre-allocated space
|
||||
extern void lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox, uchar *buf, size_t *retsize);
|
||||
|
||||
// note - for a simple type (ie. point), this will have sub_geom[0] = serialized_form.
|
||||
// for multi-geomtries sub_geom[0] will be a few bytes into the serialized form
|
||||
// This function just computes the length of each sub-object and pre-caches this info.
|
||||
|
@ -777,6 +734,7 @@ extern void pfree_POINTARRAY(POINTARRAY *pa);
|
|||
|
||||
extern uint32 get_uint32(const uchar *loc);
|
||||
extern int32 get_int32(const uchar *loc);
|
||||
extern void printBOX3D(BOX3D *b);
|
||||
extern void printPA(POINTARRAY *pa);
|
||||
extern void printLWPOINT(LWPOINT *point);
|
||||
extern void printLWLINE(LWLINE *line);
|
||||
|
@ -1042,7 +1000,6 @@ extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims, unsi
|
|||
extern int ptarray_isclosed2d(const POINTARRAY *pa);
|
||||
|
||||
extern int32 lwgeom_nrings_recursive(uchar *serialized);
|
||||
extern void dump_lwexploded(LWGEOM_EXPLODED *exploded);
|
||||
extern void ptarray_reverse(POINTARRAY *pa);
|
||||
|
||||
// Ensure every segment is at most 'dist' long.
|
||||
|
|
|
@ -8,14 +8,10 @@
|
|||
#include "liblwgeom.h"
|
||||
|
||||
//#define PGIS_DEBUG 1
|
||||
//#define PGIS_DEBUG_EXPLODED 1
|
||||
|
||||
// This is an implementation of the functions defined in lwgeom.h
|
||||
|
||||
//forward decs
|
||||
#ifdef PGIS_DEBUG_EXPLODED
|
||||
void checkexplodedsize(uchar *srl, LWGEOM_EXPLODED *exploded, int alloced, char wantbbox);
|
||||
#endif
|
||||
extern uchar *parse_lwg(const char* geometry, lwallocator allocfunc, lwreporter errfunc);
|
||||
|
||||
//*********************************************************************
|
||||
|
@ -1469,11 +1465,20 @@ lwnotice("compute_serialized_box3d: bbox found");
|
|||
result = NULL;
|
||||
for (t=0; t<ngeoms; t++)
|
||||
{
|
||||
if ( ! compute_serialized_box3d_p(loc, &b1) ) continue;
|
||||
if (result) nboxes += box3d_union_p(result, &b1, result);
|
||||
else {
|
||||
result = lwalloc(sizeof(BOX3D));
|
||||
memcpy(result, &b1, sizeof(BOX3D));
|
||||
if ( compute_serialized_box3d_p(loc, &b1) )
|
||||
{
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("Geom %d have box:"); printBOX3D(&b1);
|
||||
#endif
|
||||
if (result)
|
||||
{
|
||||
nboxes += box3d_union_p(result, &b1, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = lwalloc(sizeof(BOX3D));
|
||||
memcpy(result, &b1, sizeof(BOX3D));
|
||||
}
|
||||
}
|
||||
|
||||
sub_size = lwgeom_size(loc);
|
||||
|
@ -1510,6 +1515,12 @@ void pfree_POINTARRAY(POINTARRAY *pa)
|
|||
//** debugging routines
|
||||
|
||||
|
||||
void printBOX3D(BOX3D *box)
|
||||
{
|
||||
lwnotice("BOX3D: %g %g, %g %g", box->xmin, box->ymin,
|
||||
box->xmax, box->ymax);
|
||||
}
|
||||
|
||||
void printPA(POINTARRAY *pa)
|
||||
{
|
||||
int t;
|
||||
|
@ -1733,622 +1744,6 @@ pglwgeom_setSRID(PG_LWGEOM *lwgeom, int32 newSRID)
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
pfree_exploded(LWGEOM_EXPLODED *exploded)
|
||||
{
|
||||
if ( exploded->npoints )
|
||||
lwfree(exploded->points);
|
||||
if ( exploded->nlines )
|
||||
lwfree(exploded->lines);
|
||||
if ( exploded->npolys )
|
||||
lwfree(exploded->polys);
|
||||
lwfree(exploded);
|
||||
};
|
||||
|
||||
/*
|
||||
* This function recursively scan the given serialized geometry
|
||||
* and returns a list of _all_ subgeoms in it (deep-first)
|
||||
*/
|
||||
LWGEOM_EXPLODED *
|
||||
lwgeom_explode(uchar *serialized)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected;
|
||||
LWGEOM_EXPLODED *subexploded, *result;
|
||||
int i;
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode called");
|
||||
#endif
|
||||
|
||||
inspected = lwgeom_inspect(serialized);
|
||||
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode: serialized inspected");
|
||||
#endif
|
||||
|
||||
result = lwalloc(sizeof(LWGEOM_EXPLODED));
|
||||
result->points = lwalloc(1);
|
||||
result->lines = lwalloc(1);
|
||||
result->polys = lwalloc(1);
|
||||
result->npoints = 0;
|
||||
result->nlines = 0;
|
||||
result->npolys = 0;
|
||||
|
||||
if ( ! inspected->ngeometries )
|
||||
{
|
||||
lwfree(result->points);
|
||||
lwfree(result->lines);
|
||||
lwfree(result->polys);
|
||||
result->SRID = -1;
|
||||
result->dims = inspected->type;
|
||||
pfree_inspected(inspected);
|
||||
//lwnotice("lwgeom_explode: no geometries");
|
||||
return result;
|
||||
}
|
||||
|
||||
result->SRID = lwgeom_getsrid(serialized);
|
||||
result->dims = inspected->type; // will use ZM only
|
||||
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
|
||||
uchar *subgeom = inspected->sub_geoms[i];
|
||||
int type = lwgeom_getType(subgeom[0]);
|
||||
|
||||
if ( type == POINTTYPE )
|
||||
{
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode: it's a point");
|
||||
#endif
|
||||
result->points = lwrealloc(result->points,
|
||||
(result->npoints+1)*sizeof(uchar *));
|
||||
result->points[result->npoints] = subgeom;
|
||||
result->npoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( type == LINETYPE )
|
||||
{
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode: it's a line");
|
||||
#endif
|
||||
result->lines = lwrealloc(result->lines,
|
||||
(result->nlines+1)*sizeof(uchar *));
|
||||
result->lines[result->nlines] = subgeom;
|
||||
result->nlines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( type == POLYGONTYPE )
|
||||
{
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode: it's a polygon");
|
||||
#endif
|
||||
result->polys = lwrealloc(result->polys,
|
||||
(result->npolys+1)*sizeof(uchar *));
|
||||
result->polys[result->npolys] = subgeom;
|
||||
result->npolys++;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("type of subgeom %d is %d, recursing", i, type);
|
||||
#endif
|
||||
|
||||
// it's a multi geometry, recurse
|
||||
subexploded = lwgeom_explode(subgeom);
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("subgeom %d, exploded: %d point, %d lines, %d polys", i, subexploded->npoints, subexploded->nlines, subexploded->npolys);
|
||||
#endif
|
||||
|
||||
// Re-allocate adding space for new exploded geoms
|
||||
// (-1 because 1 was already allocated for the collection)
|
||||
// Copy subgeom pointers from subexploded to current
|
||||
// exploded.
|
||||
|
||||
if ( subexploded->npoints )
|
||||
{
|
||||
result->points = lwrealloc(result->points,
|
||||
sizeof(uchar *)*(result->npoints+subexploded->npoints-1));
|
||||
if ( ! result )
|
||||
lwerror("Out of virtual memory");
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwrealloc'ed exploded->points");
|
||||
#endif
|
||||
|
||||
memcpy(&(result->points[result->npoints]),
|
||||
subexploded->points,
|
||||
subexploded->npoints*sizeof(uchar *));
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("memcpied exploded->points");
|
||||
#endif
|
||||
|
||||
result->npoints += subexploded->npoints;
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("memcopied %d points from subexploded (exploded points: %d", subexploded->npoints, result->npoints);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( subexploded->nlines )
|
||||
{
|
||||
result->lines = lwrealloc(result->lines,
|
||||
sizeof(uchar *)*
|
||||
(result->nlines+subexploded->nlines-1));
|
||||
|
||||
memcpy(&(result->lines[result->nlines]),
|
||||
subexploded->lines,
|
||||
subexploded->nlines*sizeof(uchar *));
|
||||
|
||||
result->nlines += subexploded->nlines;
|
||||
}
|
||||
|
||||
if ( subexploded->npolys )
|
||||
{
|
||||
result->polys = lwrealloc(result->polys,
|
||||
sizeof(uchar *)*
|
||||
(result->npolys+subexploded->npolys-1));
|
||||
|
||||
memcpy(&(result->polys[result->npolys]),
|
||||
subexploded->polys,
|
||||
subexploded->npolys*sizeof(uchar *));
|
||||
|
||||
result->npolys += subexploded->npolys;
|
||||
}
|
||||
|
||||
// release subexploded memory
|
||||
pfree_exploded(subexploded);
|
||||
|
||||
}
|
||||
|
||||
pfree_inspected(inspected);
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwgeom_explode: returning");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns a 'lwalloced' union of the two input exploded geoms
|
||||
// Returns NULL if SRID or ndims do not match.
|
||||
LWGEOM_EXPLODED *
|
||||
lwexploded_sum(LWGEOM_EXPLODED *exp1, LWGEOM_EXPLODED *exp2)
|
||||
{
|
||||
LWGEOM_EXPLODED *expcoll;
|
||||
uchar *loc;
|
||||
|
||||
if ( TYPE_GETZM(exp1->dims) != TYPE_GETZM(exp2->dims) )
|
||||
{
|
||||
lwerror("lwexploded_sum: can't sum mixed DIMS geoms (%d/%d)",
|
||||
TYPE_GETZM(exp1->dims), TYPE_GETZM(exp2->dims));
|
||||
return NULL;
|
||||
}
|
||||
if ( exp1->SRID != exp2->SRID )
|
||||
{
|
||||
lwerror("lwexploded_sum: can't sum mixed SRID geoms (%d/%d)",
|
||||
exp1->SRID, exp2->SRID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expcoll = lwalloc(sizeof(LWGEOM_EXPLODED));
|
||||
|
||||
expcoll->npoints = exp1->npoints + exp2->npoints;
|
||||
if ( expcoll->npoints ) {
|
||||
expcoll->points = lwalloc(expcoll->npoints*sizeof(char *));
|
||||
loc = (char *)&(expcoll->points[0]);
|
||||
if ( exp1->npoints ) {
|
||||
memcpy(loc, exp1->points,
|
||||
exp1->npoints*sizeof(char *));
|
||||
loc += exp1->npoints*sizeof(char *);
|
||||
}
|
||||
if ( exp2->npoints ) {
|
||||
memcpy(loc, exp2->points,
|
||||
exp2->npoints*sizeof(char *));
|
||||
}
|
||||
}
|
||||
|
||||
expcoll->nlines = exp1->nlines + exp2->nlines;
|
||||
if ( expcoll->nlines ) {
|
||||
expcoll->lines = lwalloc(expcoll->nlines*sizeof(char *));
|
||||
loc = (char *)&(expcoll->lines[0]);
|
||||
if ( exp1->nlines ) {
|
||||
memcpy(loc, exp1->lines,
|
||||
exp1->nlines*sizeof(char *));
|
||||
loc += exp1->nlines*sizeof(char *);
|
||||
}
|
||||
if ( exp2->nlines ) {
|
||||
memcpy(loc, exp2->lines,
|
||||
exp2->nlines*sizeof(char *));
|
||||
}
|
||||
}
|
||||
|
||||
expcoll->npolys = exp1->npolys + exp2->npolys;
|
||||
if ( expcoll->npolys ) {
|
||||
expcoll->polys = lwalloc(expcoll->npolys*sizeof(char *));
|
||||
loc = (char *)&(expcoll->polys[0]);
|
||||
if ( exp1->npolys ) {
|
||||
memcpy(loc, exp1->polys,
|
||||
exp1->npolys*sizeof(char *));
|
||||
loc += exp1->npolys*sizeof(char *);
|
||||
}
|
||||
if ( exp2->npolys ) {
|
||||
memcpy(loc, exp2->polys,
|
||||
exp2->npolys*sizeof(char *));
|
||||
}
|
||||
}
|
||||
|
||||
expcoll->dims = exp1->dims;
|
||||
expcoll->SRID = exp1->SRID;
|
||||
|
||||
return expcoll;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialized a LWGEOM_EXPLODED structure
|
||||
*/
|
||||
uchar *
|
||||
lwexploded_serialize(LWGEOM_EXPLODED *exploded, int wantbbox)
|
||||
{
|
||||
size_t sizecom = 0;
|
||||
size_t size;
|
||||
uchar *result;
|
||||
|
||||
size = lwexploded_findlength(exploded, wantbbox);
|
||||
result = lwalloc(size);
|
||||
lwexploded_serialize_buf(exploded, wantbbox, result, &sizecom);
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwexploded_serialize: findlength:%d, serialize_buf:%d", size, sizecom);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialized a LWGEOM_EXPLODED structure into a
|
||||
* pre-allocated memory space.
|
||||
* Use lwexploded_findlength to know the required size
|
||||
* of the provided buffer.
|
||||
*/
|
||||
void
|
||||
lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox,
|
||||
uchar *buf, size_t *retsize)
|
||||
{
|
||||
size_t size=0;
|
||||
int i;
|
||||
int ntypes = 0;
|
||||
int ngeoms = 0;
|
||||
uchar *loc;
|
||||
int outtype = 0;
|
||||
LWPOLY *poly;
|
||||
LWLINE *line;
|
||||
LWPOINT *point;
|
||||
BOX2DFLOAT4 *box2d;
|
||||
BOX3D *box3d;
|
||||
|
||||
ngeoms = exploded->npoints + exploded->nlines + exploded->npolys;
|
||||
|
||||
if ( ngeoms == 0 )
|
||||
{
|
||||
lwgeom_constructempty_buf(exploded->SRID,
|
||||
TYPE_HASZ(exploded->dims), TYPE_HASM(exploded->dims),
|
||||
buf, retsize);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// For a single geometry just set SRID and BBOX (if requested)
|
||||
if ( ngeoms == 1 )
|
||||
{
|
||||
loc = buf;
|
||||
|
||||
if ( exploded->npoints ) {
|
||||
|
||||
if ( wantbbox && !
|
||||
lwgeom_hasBBOX(exploded->points[0][0]) )
|
||||
{
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
point = lwpoint_deserialize(exploded->points[0]);
|
||||
point->SRID = exploded->SRID;
|
||||
lwpoint_serialize_buf(point, loc, &size);
|
||||
pfree_point(point);
|
||||
}
|
||||
else if ( exploded->nlines ) {
|
||||
if ( wantbbox && !
|
||||
lwgeom_hasBBOX(exploded->lines[0][0]) )
|
||||
{
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
line = lwline_deserialize(exploded->lines[0]);
|
||||
line->SRID = exploded->SRID;
|
||||
lwline_serialize_buf(line, loc, &size);
|
||||
pfree_line(line);
|
||||
}
|
||||
else if ( exploded->npolys ) {
|
||||
if ( wantbbox && !
|
||||
lwgeom_hasBBOX(exploded->polys[0][0]) )
|
||||
{
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
poly = lwpoly_deserialize(exploded->polys[0]);
|
||||
poly->SRID = exploded->SRID;
|
||||
lwpoly_serialize_buf(poly, loc, &size);
|
||||
pfree_polygon(poly);
|
||||
|
||||
}
|
||||
else {
|
||||
if ( retsize ) *retsize = 0;
|
||||
return; // ERROR !!
|
||||
}
|
||||
|
||||
|
||||
// Now compute the bounding box and write it
|
||||
if ( wantbbox && ! lwgeom_hasBBOX(loc[0]) )
|
||||
{
|
||||
buf[0] = loc[0];
|
||||
TYPE_SETHASBBOX(buf[0], 1);
|
||||
box3d = compute_serialized_box3d(loc);
|
||||
box2d = box3d_to_box2df(box3d);
|
||||
loc = buf+1;
|
||||
memcpy(loc, box2d, sizeof(BOX2DFLOAT4));
|
||||
size += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
|
||||
if (retsize) *retsize = size;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( exploded->npoints ) {
|
||||
ntypes++;
|
||||
outtype = (exploded->npoints>1) ? MULTIPOINTTYPE : POINTTYPE;
|
||||
}
|
||||
if ( exploded->nlines ) {
|
||||
ntypes++;
|
||||
if ( outtype ) outtype = COLLECTIONTYPE;
|
||||
else outtype = (exploded->nlines>1) ? MULTILINETYPE : LINETYPE;
|
||||
}
|
||||
if ( exploded->npolys ) {
|
||||
ntypes++;
|
||||
if ( outtype ) outtype = COLLECTIONTYPE;
|
||||
else outtype = (exploded->npolys>1) ? MULTIPOLYGONTYPE : POLYGONTYPE;
|
||||
}
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice(" computed outtype: %d, ngeoms: %d", outtype, ngeoms);
|
||||
#endif
|
||||
|
||||
|
||||
loc = buf+1; // skip type
|
||||
|
||||
if ( wantbbox ) loc += sizeof(BOX2DFLOAT4); // skip box
|
||||
if ( exploded->SRID != -1 ) loc += 4; // skip SRID
|
||||
|
||||
// If we have more then one type of geom
|
||||
// write that number in the 'ngeoms' field of the
|
||||
// output serialized form (internal geoms would be multi themself).
|
||||
// Else rewind location pointer so to overwrite result type.
|
||||
if ( ntypes > 1 ) {
|
||||
memcpy(loc, &ntypes, 4);
|
||||
loc += 4;
|
||||
} else {
|
||||
loc--; // let the type be specified later.
|
||||
}
|
||||
|
||||
if ( exploded->npoints > 1 )
|
||||
{
|
||||
loc[0] = lwgeom_makeType_full(
|
||||
TYPE_HASZ(exploded->dims), TYPE_HASM(exploded->dims),
|
||||
0, MULTIPOINTTYPE, 0);
|
||||
loc++;
|
||||
memcpy(loc, &exploded->npoints, 4); // numpoints
|
||||
loc += 4;
|
||||
}
|
||||
// Serialize points stripping BBOX and SRID if any
|
||||
for (i=0; i<exploded->npoints; i++)
|
||||
{
|
||||
size_t subsize;
|
||||
point = lwpoint_deserialize(exploded->points[i]);
|
||||
point->SRID = -1;
|
||||
lwpoint_serialize_buf(point, loc, &subsize);
|
||||
pfree_point(point);
|
||||
loc += subsize;
|
||||
}
|
||||
|
||||
if ( exploded->nlines > 1 )
|
||||
{
|
||||
loc[0] = lwgeom_makeType_full(
|
||||
TYPE_HASZ(exploded->dims),
|
||||
TYPE_HASM(exploded->dims),
|
||||
0, MULTILINETYPE, 0);
|
||||
loc++;
|
||||
memcpy(loc, &exploded->nlines, 4); // numlines
|
||||
loc += 4;
|
||||
}
|
||||
// Serialize lines stripping BBOX and SRID if any
|
||||
for (i=0; i<exploded->nlines; i++)
|
||||
{
|
||||
size_t subsize;
|
||||
|
||||
line = lwline_deserialize(exploded->lines[i]);
|
||||
if ( line == NULL )
|
||||
{
|
||||
lwerror("Error deserializing %dnt line from exploded geom", i);
|
||||
return;
|
||||
}
|
||||
line->SRID = -1;
|
||||
lwline_serialize_buf(line, loc, &subsize);
|
||||
pfree_line(line);
|
||||
loc += subsize;
|
||||
}
|
||||
|
||||
if ( exploded->npolys > 1 )
|
||||
{
|
||||
loc[0] = lwgeom_makeType_full(
|
||||
TYPE_HASZ(exploded->dims),
|
||||
TYPE_HASM(exploded->dims),
|
||||
0, MULTIPOLYGONTYPE, 0);
|
||||
loc++;
|
||||
memcpy(loc, &exploded->npolys, 4); // numpolys
|
||||
loc += 4;
|
||||
}
|
||||
// Serialize polys stripping BBOX and SRID if any
|
||||
for (i=0; i<exploded->npolys; i++)
|
||||
{
|
||||
size_t subsize;
|
||||
|
||||
poly = lwpoly_deserialize(exploded->polys[i]);
|
||||
if ( poly == NULL )
|
||||
{
|
||||
lwerror("Error deserializing %dnt polygon from exploded geom", i);
|
||||
return;
|
||||
}
|
||||
poly->SRID = -1;
|
||||
lwpoly_serialize_buf(poly, loc, &subsize);
|
||||
pfree_polygon(poly);
|
||||
loc += subsize;
|
||||
}
|
||||
|
||||
// Register now the number of written bytes
|
||||
if (retsize) *retsize = (loc-buf);
|
||||
|
||||
// Ok. now we need to add type, SRID and bbox
|
||||
buf[0] = lwgeom_makeType_full(
|
||||
TYPE_HASZ(exploded->dims),
|
||||
TYPE_HASM(exploded->dims),
|
||||
(exploded->SRID!=-1), outtype, wantbbox);
|
||||
loc = buf+1;
|
||||
|
||||
if ( wantbbox )
|
||||
{
|
||||
box3d = compute_serialized_box3d(buf);
|
||||
box2d = box3d_to_box2df(box3d);
|
||||
memcpy(loc, box2d, sizeof(BOX2DFLOAT4));
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
|
||||
if ( exploded->SRID != -1 )
|
||||
{
|
||||
memcpy(loc, &(exploded->SRID), 4);
|
||||
loc += 4; // useless.. we've finished
|
||||
}
|
||||
|
||||
#ifdef PGIS_DEBUG
|
||||
lwnotice("lwexploded_serialize finished");
|
||||
lwnotice(" type: %d", lwgeom_getType(buf[0]));
|
||||
lwnotice(" SRID: %d", lwgeom_getsrid(buf));
|
||||
if ( lwgeom_hasBBOX(buf[0]) )
|
||||
{
|
||||
{
|
||||
BOX2DFLOAT4 boxbuf;
|
||||
getbox2d_p(buf, &boxbuf);
|
||||
lwnotice(" BBOX: %f,%f %f,%f",
|
||||
boxbuf.xmin, boxbuf.ymin,
|
||||
boxbuf.xmax, boxbuf.ymax);
|
||||
}
|
||||
}
|
||||
lwnotice(" numgeoms: %d", lwgeom_getnumgeometries(buf));
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PGIS_DEBUG_EXPLODED
|
||||
void
|
||||
checkexplodedsize(uchar *srl, LWGEOM_EXPLODED *exp, int alloced, char wantbbox)
|
||||
{
|
||||
lwnotice("exploded len: serialized:%d computed:%d alloced:%d",
|
||||
lwgeom_size(srl), lwexploded_findlength(exp, wantbbox),
|
||||
alloced);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
lwexploded_findlength(LWGEOM_EXPLODED *exploded, int wantbbox)
|
||||
{
|
||||
size_t size=0;
|
||||
char ntypes=0;
|
||||
uint32 i;
|
||||
|
||||
|
||||
// find sum of sizes of all geoms.
|
||||
// substract size of eventually embedded SRID and BBOXes
|
||||
if ( exploded->npoints )
|
||||
{
|
||||
ntypes++;
|
||||
for (i=0; i<exploded->npoints; i++)
|
||||
{
|
||||
size += lwgeom_size_point(exploded->points[i]);
|
||||
if ( lwgeom_hasBBOX(exploded->points[i][0]) )
|
||||
size -= sizeof(BOX2DFLOAT4);
|
||||
if ( lwgeom_hasSRID(exploded->points[i][0]) )
|
||||
size -= 4;
|
||||
}
|
||||
// add multigeom header size
|
||||
if ( exploded->npoints > 1 )
|
||||
{
|
||||
size += 1; // type
|
||||
size += 4; // numgeometries
|
||||
}
|
||||
}
|
||||
if ( exploded->nlines )
|
||||
{
|
||||
ntypes++;
|
||||
for (i=0; i<exploded->nlines; i++)
|
||||
{
|
||||
size += lwgeom_size_line(exploded->lines[i]);
|
||||
if ( lwgeom_hasBBOX(exploded->lines[i][0]) )
|
||||
size -= sizeof(BOX2DFLOAT4);
|
||||
if ( lwgeom_hasSRID(exploded->lines[i][0]) )
|
||||
size -= 4;
|
||||
}
|
||||
// add multigeom header size
|
||||
if ( exploded->nlines > 1 )
|
||||
{
|
||||
size += 1; // type
|
||||
size += 4; // numgeometries
|
||||
}
|
||||
}
|
||||
if ( exploded->npolys )
|
||||
{
|
||||
ntypes++;
|
||||
for (i=0; i<exploded->npolys; i++)
|
||||
{
|
||||
size += lwgeom_size_poly(exploded->polys[i]);
|
||||
if ( lwgeom_hasBBOX(exploded->polys[i][0]) )
|
||||
size -= sizeof(BOX2DFLOAT4);
|
||||
if ( lwgeom_hasSRID(exploded->polys[i][0]) )
|
||||
size -= 4;
|
||||
}
|
||||
// add multigeom header size
|
||||
if ( exploded->npolys > 1 )
|
||||
{
|
||||
size += 1; // type
|
||||
size += 4; // numgeometries
|
||||
}
|
||||
}
|
||||
|
||||
/* structure is empty */
|
||||
if ( ! ntypes ) return lwgeom_empty_length(exploded->SRID);
|
||||
|
||||
/* multi-typed geom (collection), add collection header */
|
||||
if ( ntypes > 1 )
|
||||
{
|
||||
size += 1; // type
|
||||
size += 4; // numgeometries
|
||||
}
|
||||
|
||||
/*
|
||||
* Add BBOX and SRID if required
|
||||
*/
|
||||
if ( exploded->SRID != -1 ) size += 4;
|
||||
if ( wantbbox ) size += sizeof(BOX2DFLOAT4);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
char
|
||||
ptarray_isccw(const POINTARRAY *pa)
|
||||
|
|
|
@ -231,6 +231,7 @@ Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS)
|
|||
BOX3D *result;
|
||||
|
||||
result = compute_serialized_box3d(SERIALIZED_FORM(lwgeom));
|
||||
if ( ! result ) PG_RETURN_NULL();
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
@ -369,7 +370,8 @@ Datum BOX3D_construct(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
//min(a,b)
|
||||
double LWGEOM_Mind(double a, double b)
|
||||
double
|
||||
LWGEOM_Mind(double a, double b)
|
||||
{
|
||||
if (a<b)
|
||||
return a;
|
||||
|
@ -377,9 +379,11 @@ double LWGEOM_Mind(double a, double b)
|
|||
}
|
||||
|
||||
//max(a,b)
|
||||
double LWGEOM_Maxd(double a, double b)
|
||||
double
|
||||
LWGEOM_Maxd(double a, double b)
|
||||
{
|
||||
if (b>a)
|
||||
return b;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue