//find length of this serialized line
uint32 lwline_findlength(char *serialized_line)
{
- int type = (unsigned char) serialized_line[0];
- uint32 result =1; //type
- char *loc;
- uint32 npoints;
+ int type = (unsigned char) serialized_line[0];
+ uint32 result =1; //type
+ char *loc;
+ uint32 npoints;
- if ( lwgeom_getType(type) != LINETYPE)
- elog(ERROR,"lwline_findlength::attempt to find the length of a non-line");
+ if ( lwgeom_getType(type) != LINETYPE)
+ elog(ERROR,"lwline_findlength::attempt to find the length of a non-line");
loc = serialized_line+1;
//find length of this serialized polygon
uint32 lwpoly_findlength(char *serialized_poly)
{
- uint32 result = 1; // char type
- uint32 nrings;
- int ndims;
- int t;
- unsigned char type;
- uint32 npoints;
- char *loc;
+ uint32 result = 1; // char type
+ uint32 nrings;
+ int ndims;
+ int t;
+ unsigned char type;
+ uint32 npoints;
+ char *loc;
- if (serialized_poly == NULL)
- return -9999;
+ if (serialized_poly == NULL)
+ return -9999;
- type = (unsigned char) serialized_poly[0];
- ndims = lwgeom_ndims(type);
+ type = (unsigned char) serialized_poly[0];
+ ndims = lwgeom_ndims(type);
- if ( lwgeom_getType(type) != POLYGONTYPE)
- return -9999;
+ if ( lwgeom_getType(type) != POLYGONTYPE)
+ return -9999;
loc = serialized_poly+1;
if (lwgeom_hasBBOX(type))
{
+#ifdef DEBUG
+ elog(NOTICE, "lwpoly_findlength: has bbox");
+#endif
loc += sizeof(BOX2DFLOAT4);
result +=sizeof(BOX2DFLOAT4);
}
- if ( lwgeom_hasSRID(type))
- {
- loc +=4; // type + SRID
- result += 4;
- }
+ if ( lwgeom_hasSRID(type))
+ {
+#ifdef DEBUG
+ elog(NOTICE, "lwpoly_findlength: has srid");
+#endif
+ loc +=4; // type + SRID
+ result += 4;
+ }
- nrings = get_uint32(loc);
+ nrings = get_uint32(loc);
+ loc +=4;
+ result +=4;
+
+
+ for (t =0;t<nrings;t++)
+ {
+ //read in a single ring and make a PA
+ npoints = get_uint32(loc);
loc +=4;
result +=4;
-
- for (t =0;t<nrings;t++)
+ if (ndims == 3)
{
- //read in a single ring and make a PA
- npoints = get_uint32(loc);
- loc +=4;
- result +=4;
-
- if (ndims == 3)
- {
- loc += 24*npoints;
- result += 24*npoints;
- }
- else if (ndims == 2)
- {
- loc += 16*npoints;
- result += 16*npoints;
- }
- else if (ndims == 4)
- {
- loc += 32*npoints;
- result += 32*npoints;
- }
+ loc += 24*npoints;
+ result += 24*npoints;
+ }
+ else if (ndims == 2)
+ {
+ loc += 16*npoints;
+ result += 16*npoints;
}
+ else if (ndims == 4)
+ {
+ loc += 32*npoints;
+ result += 32*npoints;
+ }
+ }
return result;
}
sub_geoms = (char**) palloc(sizeof(char*));
sub_geoms[0] = serialized_form;
result->sub_geoms = sub_geoms;
+ return result;
}
- else
+
+ // its a GeometryCollection or multi* geometry
+
+ if (lwgeom_hasSRID((unsigned char) serialized_form[0]) )
{
- if (lwgeom_hasSRID((unsigned char) serialized_form[0]) )
- {
- result->SRID= get_int32(loc);
- loc += 4;
- }
- //its a GeometryCollection or multi* geometry
- result->ngeometries = get_uint32(loc);
- loc +=4;
- sub_geoms = (char**) palloc(sizeof(char*) * result->ngeometries );
- result->sub_geoms = sub_geoms;
- sub_geoms[0] = loc;
- for (t=1;t<result->ngeometries; t++)
- {
- int sub_length = lwgeom_seralizedformlength(sub_geoms[t-1], -1);//-1 = entire object
- sub_geoms[t] = sub_geoms[t-1] + sub_length;
- }
+ result->SRID= get_int32(loc);
+ loc += 4;
+ }
+
+ result->ngeometries = get_uint32(loc);
+ loc +=4;
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_inspect: geometry is a collection of %d elements",
+ result->ngeometries);
+#endif
+
+ sub_geoms = (char**) palloc(sizeof(char*) * result->ngeometries );
+ result->sub_geoms = sub_geoms;
+ sub_geoms[0] = loc;
+#ifdef DEBUG
+ elog(NOTICE, "subgeom[0] @ %i", sub_geoms[0]);
+#endif
+ for (t=1;t<result->ngeometries; t++)
+ {
+ int sub_length = lwgeom_seralizedformlength(sub_geoms[t-1], -1);//-1 = entire object
+ sub_geoms[t] = sub_geoms[t-1] + sub_length;
+#ifdef DEBUG
+ elog(NOTICE, "subgeom[%d] @ %i (sub_length: %d)",
+ t, sub_geoms[t], sub_length);
+#endif
}
return result;
int result = 1; //"type"
if (type == POINTTYPE)
+ {
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple: is a point");
+#endif
return lwpoint_findlength(serialized_form);
+ }
else if (type == LINETYPE)
+ {
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple: is a line");
+#endif
return lwline_findlength(serialized_form);
+ }
else if (type == POLYGONTYPE)
+ {
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple: is a polygon");
+#endif
return lwpoly_findlength(serialized_form);
+ }
- //handle all the multi* and geometrycollections the same
- //NOTE: for a geometry collection of GC of GC of GC we will be recursing...
+ if ( type == 0 )
+ {
+ elog(ERROR, "lwgeom_seralizedformlength_simple called with unknown-typed serialized geometry");
+ return 0;
+ }
+ //handle all the multi* and geometrycollections the same
+ //NOTE: for a geometry collection of GC of GC of GC we will be recursing...
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple called on a geoemtry with type %d", type);
+#endif
loc = serialized_form+1;
if (lwgeom_hasBBOX((unsigned char) serialized_form[0]))
{
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple: has bbox");
+#endif
+
loc += sizeof(BOX2DFLOAT4);
result +=sizeof(BOX2DFLOAT4);
}
if (lwgeom_hasSRID( (unsigned char) serialized_form[0]) )
{
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple: has srid");
+#endif
result +=4;
loc +=4;
}
ngeoms = get_uint32(loc);
loc +=4;
+ result += 4; // numgeoms
+
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple called on a geoemtry with %d elems (result so far: %d)", ngeoms, result);
+#endif
for (t=0;t<ngeoms;t++)
{
sub_size = lwgeom_seralizedformlength_simple(loc);
+#ifdef DEBUG
+ elog(NOTICE, " subsize %d", sub_size);
+#endif
loc += sub_size;
result += sub_size;
}
+#ifdef DEBUG
+ elog(NOTICE, "lwgeom_seralizedformlength_simple returning %d", result);
+#endif
return result;
}
PG_FUNCTION_INFO_V1(lwgeom_mem_size);
Datum lwgeom_mem_size(PG_FUNCTION_ARGS)
{
- char *geom = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
- int32 size = *((int32 *)geom);
+ LWGEOM *geom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ int32 size = geom->size;
+ int32 computed_size = lwgeom_seralizedformlength_simple(SERIALIZED_FORM(geom));
+ computed_size += 4; // varlena size
+ if ( size != computed_size )
+ {
+ elog(NOTICE, "varlena size (%d) != computed size+4 (%d)",
+ size, computed_size);
+ }
+
PG_FREE_IF_COPY(geom,0);
PG_RETURN_INT32(size);
}
* LWGEOM object
*/
char *
-lwgeom_summary_recursive(char *serialized)
+lwgeom_summary_recursive(char *serialized, int offset)
{
+ static int idx = 0;
LWGEOM_INSPECTED *inspected;
char *result;
char *ptr;
result = palloc(1);
result[0] = '\0';
+ if ( offset == 0 ) idx = 0;
+
inspected = lwgeom_inspect(serialized);
+
+ if (0) {
+ size += 57;
+ result = repalloc(result,size);
+ sprintf(tmp,
+ "Geometry (inspected) contains %i subgeoms\n",
+ inspected->ngeometries);
+ strcat(result,tmp);
+ }
+
//now have to do a scan of each object
for (j=0; j<inspected->ngeometries; j++)
{
LWLINE *line=NULL;
LWPOINT *point=NULL;
LWPOLY *poly=NULL;
- char *subgeom;
+ char *subgeom=NULL;
point = lwgeom_getpoint_inspected(inspected,j);
if (point !=NULL)
{
size += 30;
result = repalloc(result,size);
- sprintf(tmp,"Object %i is a POINT()\n",j);
+ sprintf(tmp,"Object %i is a POINT()\n",
+ idx++);
strcat(result,tmp);
continue;
}
{
size += 57*(poly->nrings+1);
result = repalloc(result,size);
- sprintf(tmp,"Object %i is a POLYGON() with %i rings\n",j,poly->nrings);
+ sprintf(tmp,"Object %i is a POLYGON() with %i rings\n",
+ idx++, poly->nrings);
strcat(result,tmp);
for (i=0; i<poly->nrings;i++)
{
result = repalloc(result,size);
sprintf(tmp,
"Object %i is a LINESTRING() with %i points\n",
- j, line->points->npoints);
+ idx++, line->points->npoints);
strcat(result,tmp);
continue;
}
subgeom = lwgeom_getsubgeometry_inspected(inspected, j);
if ( subgeom != NULL )
{
- ptr = lwgeom_summary_recursive(subgeom);
+ ptr = lwgeom_summary_recursive(subgeom, 1);
size += strlen(ptr);
result = repalloc(result,size);
strcat(result, ptr);
}
}
+ pfree_inspected(inspected);
return result;
}
char *result;
text *mytext;
- result = lwgeom_summary_recursive(SERIALIZED_FORM(geom));
+ result = lwgeom_summary_recursive(SERIALIZED_FORM(geom), 0);
// create a text obj to return
mytext = (text *) palloc(VARHDRSZ + strlen(result) );