#define TYPE_HASZ(t) ( ((t)&0x20)>>5 )
#define TYPE_HASM(t) ( ((t)&0x10)>>4 )
-#define TYPE_HASBBOX(t) ((t)&0x80)
-#define TYPE_HASSRID(t) (((t)&0x40))
+#define TYPE_HASBBOX(t) ( ((t)&0x80)>>7 )
+#define TYPE_HASSRID(t) ( (((t)&0x40))>>6 )
#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2)
#define TYPE_GETTYPE(t) ((t)&0x0F)
#define TYPE_GETZM(t) (((t)&0x30)>>4)
extern double lwgeom_pointarray_length(POINTARRAY *pts);
extern void lwgeom_force2d_recursive(char *serialized, char *optr, size_t *retsize);
extern void lwgeom_force3dz_recursive(char *serialized, char *optr, size_t *retsize);
-extern void lwgeom_force3dm_recursive(char *serialized, char *optr, size_t *retsize);
+extern void lwgeom_force3dm_recursive(unsigned char *serialized, char *optr, size_t *retsize);
extern void lwgeom_force4d_recursive(char *serialized, char *optr, size_t *retsize);
extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
lwgeom_inspect(const char *serialized_form)
{
LWGEOM_INSPECTED *result = lwalloc(sizeof(LWGEOM_INSPECTED));
+ unsigned char typefl = (unsigned char)serialized_form[0];
unsigned char type;
char **sub_geoms;
const char *loc;
int t;
+#ifdef DEBUG
+ lwnotice("lwgeom_inspect: serialized@%p", serialized_form);
+#endif
+
if (serialized_form == NULL)
return NULL;
result->type = (unsigned char) serialized_form[0];
result->SRID = -1; // assume
- type = lwgeom_getType( (unsigned char) serialized_form[0]);
+ type = lwgeom_getType(typefl);
loc = serialized_form+1;
+ if ( lwgeom_hasBBOX(typefl) )
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if ( lwgeom_hasSRID(typefl) )
+ {
+ result->SRID = get_int32(loc);
+ loc += 4;
+ }
+
if ( (type==POINTTYPE) || (type==LINETYPE) || (type==POLYGONTYPE) )
{
- if (lwgeom_hasSRID((unsigned char) serialized_form[0]) )
- {
- result->SRID = get_int32(loc);
- }
//simple geometry (point/line/polygon)-- not multi!
result->ngeometries = 1;
sub_geoms = (char**) lwalloc(sizeof(char*));
// its a GeometryCollection or multi* geometry
- if (lwgeom_hasBBOX((unsigned char) serialized_form[0]))
- {
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if (lwgeom_hasSRID((unsigned char) serialized_form[0]) )
- {
- result->SRID= get_int32(loc);
- loc += 4;
- }
-
result->ngeometries = get_uint32(loc);
loc +=4;
#ifdef DEBUG
result->sub_geoms = sub_geoms;
sub_geoms[0] = (char *)loc;
#ifdef DEBUG
- lwnotice("subgeom[0] @ %p", sub_geoms[0]);
+ lwnotice("subgeom[0] @ %p (+%d)", sub_geoms[0], sub_geoms[0]-serialized_form);
#endif
for (t=1;t<result->ngeometries; t++)
{
int sub_length = lwgeom_size_subgeom(sub_geoms[t-1], -1);//-1 = entire object
sub_geoms[t] = sub_geoms[t-1] + sub_length;
#ifdef DEBUG
- lwnotice("subgeom[%d] @ %p (sub_length: %d)",
- t, sub_geoms[t], sub_length);
+ lwnotice("subgeom[%d] @ %p (+%d)",
+ t, sub_geoms[t], sub_geoms[0]-serialized_form);
#endif
}
return result;
}
-char *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+char *
+lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
{
if ((geom_number <0) || (geom_number >= inspected->ngeometries) )
+ {
+ lwerror("lwgeom_getsubgeometry_inspected: geom_number out of range");
return NULL;
+ }
return inspected->sub_geoms[geom_number];
}
// ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
// --> point
// gets the 8bit type of the geometry at location geom_number
-char lwgeom_getsubtype(char *serialized_form, int geom_number)
+char
+lwgeom_getsubtype(char *serialized_form, int geom_number)
{
//major cheat!!
char result;
* Return number bytes written in given int pointer.
*/
void
-lwgeom_force3dm_recursive(char *serialized, char *optr, size_t *retsize)
+lwgeom_force3dm_recursive(unsigned char *serialized, char *optr, size_t *retsize)
{
LWGEOM_INSPECTED *inspected;
int i,j,k;
int totsize=0;
int size=0;
int type;
+ unsigned char newtypefl;
LWPOINT *point = NULL;
LWLINE *line = NULL;
LWPOLY *poly = NULL;
point->point = &newpts;
TYPE_SETZM(point->type, 0, 1);
lwpoint_serialize_buf(point, optr, retsize);
+ lwfree(newpts.serialized_pointlist);
+ lwfree(point);
#ifdef DEBUG
lwnotice("lwgeom_force3dm_recursive returning");
line->points = &newpts;
TYPE_SETZM(line->type, 0, 1);
lwline_serialize_buf(line, optr, retsize);
+ lwfree(newpts.serialized_pointlist);
+ lwfree(line);
#ifdef DEBUG
lwnotice("lwgeom_force3dm_recursive returning");
poly->rings = nrings;
TYPE_SETZM(poly->type, 0, 1);
lwpoly_serialize_buf(poly, optr, retsize);
+ lwfree(poly);
+ // TODO: free nrigs[*]->serialized_pointlist
#ifdef DEBUG
lwnotice("lwgeom_force3dm_recursive returning");
// Add type
- optr[0] = lwgeom_makeType_full(0, 1, lwgeom_hasSRID(serialized[0]),
+ newtypefl = lwgeom_makeType_full(0, 1, lwgeom_hasSRID(serialized[0]),
type, lwgeom_hasBBOX(serialized[0]));
+ optr[0] = newtypefl;
optr++;
totsize++;
loc=serialized+1;
#ifdef DEBUG
- lwnotice("lwgeom_force3dm_recursive: added collection type (%s) - size:%d", lwgeom_typename(type), totsize);
+ lwnotice("lwgeom_force3dm_recursive: added collection type (%s[%s]) - size:%d", lwgeom_typename(type), lwgeom_typeflags(newtypefl), totsize);
#endif
+ if ( lwgeom_hasBBOX(serialized[0]) != lwgeom_hasBBOX(newtypefl) )
+ lwerror("typeflag mismatch in BBOX");
+ if ( lwgeom_hasSRID(serialized[0]) != lwgeom_hasSRID(newtypefl) )
+ lwerror("typeflag mismatch in SRID");
+
// Add BBOX if any
if (lwgeom_hasBBOX(serialized[0]))
{
#ifdef DEBUG
lwnotice("lwgeom_force3dm_recursive: inspecting subgeoms");
#endif
- // Now recurse for each suboject
+ // Now recurse for each subobject
inspected = lwgeom_inspect(serialized);
for (i=0; i<inspected->ngeometries; i++)
{
if ( retsize ) *retsize = totsize;
}
+
/*
* Write to already allocated memory 'optr' a 4d version of
* the given serialized form.
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
PG_LWGEOM *result;
int olddims;
- int32 size = 0;
+ size_t size = 0;
olddims = lwgeom_ndims(geom->type);
if ( olddims == 3 && TYPE_HASM(geom->type) ) PG_RETURN_POINTER(geom);
if ( olddims > 3 ) {
- result = (PG_LWGEOM *)lwalloc(geom->size);
+ size = geom->size;
} else {
// allocate double as memory a larger for safety
- result = (PG_LWGEOM *) lwalloc(geom->size*1.5);
+ size = geom->size * 1.5;
}
+ result = (PG_LWGEOM *)lwalloc(size);
+
+#ifdef DEBUG
+ lwnotice("LWGEOM_force_3dm: allocated %d bytes for result", size);
+#endif
lwgeom_force3dm_recursive(SERIALIZED_FORM(geom),
SERIALIZED_FORM(result), &size);
#ifdef DEBUG
- lwnotice("lwgeom_force3dm_recursive returned a %d sized geom",
- size);
+ lwnotice("LWGEOM_force_3dm: lwgeom_force3dm_recursive returned a %d sized geom", size);
#endif
// we can safely avoid this... memory will be freed at
byte* output_collection_2(byte* geom,int suppress);
byte* output_multipoint(byte* geom,int suppress);
void write_wkb_bytes(byte* ptr,int cnt);
-byte* output_wkb_point(byte* geom);
void write_wkb_int(int i);
byte* output_wkb_collection(byte* geom,outwkbfunc func);
byte* output_wkb_collection_2(byte* geom);
+byte* output_wkb_point(byte* geom);
byte* output_wkb(byte* geom);
//-- Globals -----------------------------------------------
-void ensure(int chars){
+/*
+ * Ensure there is enough space for chars bytes.
+ * Reallocate memory is this is not the case.
+ */
+void
+ensure(int chars){
int pos = out_pos - out_start;
to_end();
}
-void write_double(double val){
+void
+write_double(double val){
ensure(32);
if (lwgi)
sprintf(out_pos,"%.8g",val);
to_end();
}
-void write_int(int i){
+void
+write_int(int i){
ensure(32);
sprintf(out_pos,"%i",i);
to_end();
}
-int4 read_int(byte** geom){
+int4
+read_int(byte** geom)
+{
int4 ret;
#ifdef SHRINK_INTS
if ( getMachineEndian() == LITTLE_ENDIAN_CHECK ){
}
}
-byte* output_point(byte* geom,int supress){
+byte *
+output_point(byte* geom,int supress)
+{
int i;
for( i = 0 ; i < dims ; i++ ){
static char outchr[]={"0123456789ABCDEF" };
-void write_wkb_bytes(byte* ptr,int cnt){
+void
+write_wkb_bytes(byte* ptr,int cnt){
ensure(cnt*2);
while(cnt--){
}
byte *
-output_wkb_collection(byte* geom,outwkbfunc func){
+output_wkb_collection(byte* geom,outwkbfunc func)
+{
int cnt = read_int(&geom);
+#ifdef DEBUG
+ lwnotice("output_wkb_collection: %d iterations loop", cnt);
+#endif
write_wkb_int(cnt);
while(cnt--) geom=func(geom);
return geom;
byte *
output_wkb(byte* geom)
{
-
unsigned char type=*geom++;
int4 wkbtype;
+ byte endian;
dims = TYPE_NDIMS(type);
+#ifdef DEBUG
+ lwnotice("output_wkb: dims set to %d", dims);
+#endif
//Skip the bounding box
if ( TYPE_HASBBOX(type) ) {
}
if ( TYPE_HASSRID(type) ) {
- write_str("SRID=");write_int(read_int(&geom));write_str(";");
+ write_str("SRID=");
+ write_int(read_int(&geom));
+ write_str(";");
}
//type&=0x0f;
wkbtype |= WKBMOFFSET;
if ( getMachineEndian() != LITTLE_ENDIAN_CHECK ){
- byte endian=0;
+ endian=0;
write_wkb_bytes(&endian,1);
}
else{
- byte endian=1;
+ endian=1;
write_wkb_bytes(&endian,1);
}
geom=output_wkb_point(geom);
break;
case LINETYPE:
- geom = output_wkb_collection(geom,output_wkb_point);
+ geom=output_wkb_collection(geom,output_wkb_point);
break;
case POLYGONTYPE:
- geom = output_wkb_collection(geom,output_wkb_collection_2);
+ geom=output_wkb_collection(geom,output_wkb_collection_2);
break;
case MULTIPOINTTYPE:
case MULTILINETYPE:
unparse_WKB(byte* lw_geom,allocator alloc,freeor free)
{
+#ifdef DEBUG
+ lwnotice("unparse_WKB(%p,...) called", lw_geom);
+#endif
+
if (lw_geom==NULL)
return NULL;