From: Sandro Santilli Date: Thu, 10 Feb 2005 17:41:55 +0000 (+0000) Subject: Dropped getbox2d_internal(). X-Git-Tag: pgis_1_0_0RC3~46 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=99425f8eaf9af7d5bfb018f4d37673d30b5343f7;p=postgis Dropped getbox2d_internal(). Removed all castings of getPoint() output, which has been renamed to getPoint_internal() and commented about danger of using it. Changed SERIALIZED_FORM() macro to use VARDATA() macro. All this changes are aimed at taking into account memory alignment constraints which might be the cause of recent crash bug reports. git-svn-id: http://svn.osgeo.org/postgis/trunk@1393 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index 2fd9ce6e9..39310a6ff 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -299,7 +299,12 @@ extern int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point); // You'll need to cast it to appropriate dimensioned point. // Note that if you cast to a higher dimensional point you'll // possibly corrupt the POINTARRAY. -extern uchar *getPoint(const POINTARRAY *pa, int n); +// +// WARNING: Don't cast this to a POINT ! +// it would not be reliable due to memory alignment constraints +// +extern uchar *getPoint_internal(const POINTARRAY *pa, int n); + //--- here is a macro equivalent, for speed... //#define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) @@ -424,7 +429,8 @@ char is_worth_caching_lwgeom_bbox(const LWGEOM *); * by most functions from an PG_LWGEOM struct. * (which is an PG_LWGEOM w/out int32 size casted to char *) */ -#define SERIALIZED_FORM(x) ((uchar *)(x))+4 +//#define SERIALIZED_FORM(x) ((uchar *)(x))+4 +#define SERIALIZED_FORM(x) (VARDATA((x))) /* @@ -731,7 +737,7 @@ extern BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2); // Returns a pointer to the BBOX internal to the serialized form. // READ-ONLY! // Or NULL if serialized form does not have a BBOX -extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form); +//extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form); // this function writes to 'box' and returns 0 if serialized_form // does not have a bounding box (empty geom) @@ -1019,10 +1025,10 @@ extern const uchar *lwgeom_typeflags(uchar type); // Construct an empty pointarray extern POINTARRAY *ptarray_construct(char hasz, char hasm, unsigned int npoints); -extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts); -extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts); -extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts); -extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts); +//extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts); +//extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts); +//extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts); +//extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts); extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims, unsigned int where); extern int ptarray_isclosed2d(const POINTARRAY *pa); diff --git a/lwgeom/lwgeom_api.c b/lwgeom/lwgeom_api.c index 6a0f2fef4..c6d0a31d2 100644 --- a/lwgeom/lwgeom_api.c +++ b/lwgeom/lwgeom_api.c @@ -311,12 +311,12 @@ BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2) // returns a pointer to internal storage, or NULL // if the serialized form does not have a BBOX. -BOX2DFLOAT4 * -getbox2d_internal(uchar *srl) -{ - if (TYPE_HASBBOX(srl[0])) return (BOX2DFLOAT4 *)(srl+1); - else return NULL; -} +//BOX2DFLOAT4 * +//getbox2d_internal(uchar *srl) +//{ +// if (TYPE_HASBBOX(srl[0])) return (BOX2DFLOAT4 *)(srl+1); +// else return NULL; +//} // same as getbox2d, but modifies box instead of returning result on the stack int @@ -401,7 +401,6 @@ int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point) { int size; - POINT4D *pt; if ( ! pa ) return 0; @@ -411,29 +410,9 @@ getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point) return 0; //error } + memset(point, 0, sizeof(POINT3DZ)); size = pointArray_ptsize(pa); - - pt = (POINT4D *)getPoint(pa, n); - - // Initialize point - point->x = pt->x; - point->y = pt->y; - point->z = NO_Z_VALUE; - point->m = NO_M_VALUE; - - if (TYPE_HASZ(pa->dims)) - { - point->z = pt->z; - if (TYPE_HASM(pa->dims)) - { - point->m = pt->m; - } - } - else if (TYPE_HASM(pa->dims)) - { - point->m = pt->z; - } - + memcpy(point, getPoint_internal(pa, n), size); return 1; } @@ -468,7 +447,6 @@ int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *op) { int size; - POINT4D *ip; if ( ! pa ) return 0; @@ -483,19 +461,17 @@ getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *op) return 0; //error } - size = pointArray_ptsize(pa); + /* initialize point */ + memset(op, 0, sizeof(POINT3DZ)); + /* copy */ + size = pointArray_ptsize(pa); #ifdef PGIS_DEBUG lwnotice("getPoint3dz_p: point size: %d", size); #endif - - ip = (POINT4D *)getPoint(pa, n); - op->x = ip->x; - op->y = ip->y; - if ( TYPE_HASZ(pa->dims) ) op->z = ip->z; - else op->z = NO_Z_VALUE; - + memcpy(op, getPoint_internal(pa, n), size); return 1; + } // copies a point from the point array into the parameter point @@ -505,7 +481,6 @@ int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *op) { int size; - POINT4D *ip; if ( ! pa ) return 0; @@ -520,26 +495,15 @@ getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *op) return 0; //error } - size = pointArray_ptsize(pa); + /* initialize point */ + memset(op, 0, sizeof(POINT3DM)); + /* copy */ + size = pointArray_ptsize(pa); #ifdef PGIS_DEBUG - lwnotice("getPoint3d_p: point size: %d", size); + lwnotice("getPoint3dz_p: point size: %d", size); #endif - - ip = (POINT4D *)getPoint(pa, n); - op->x = ip->x; - op->y = ip->y; - op->m = NO_M_VALUE; - - if ( TYPE_HASM(pa->dims) ) - { - if ( TYPE_HASZ(pa->dims) ) - { - op->m = ip->m; - } - else op->m = ip->z; - } - + memcpy(op, getPoint_internal(pa, n), size); return 1; } @@ -589,11 +553,10 @@ getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point) } // get a pointer to nth point of a POINTARRAY -// You'll need to cast it to appropriate dimensioned point. -// Note that if you cast to a higher dimensional point you'll -// possibly corrupt the POINTARRAY. +// You cannot safely cast this to a real POINT, due to memory alignment +// constraints. Use getPoint*_p for that. uchar * -getPoint(const POINTARRAY *pa, int n) +getPoint_internal(const POINTARRAY *pa, int n) { int size; @@ -623,12 +586,16 @@ pointArray_construct(uchar *points, char hasz, char hasm, uint32 npoints) { POINTARRAY *pa; + size_t size; pa = (POINTARRAY*)lwalloc(sizeof(POINTARRAY)); pa->dims = 0; TYPE_SETZM(pa->dims, hasz, hasm); pa->npoints = npoints; - pa->serialized_pointlist = points; + + size=(2+hasz+hasm)*sizeof(double)*npoints; + pa->serialized_pointlist = lwalloc(size); + memcpy(pa->serialized_pointlist, points, size); return pa; } @@ -1635,7 +1602,7 @@ void pfree_POINTARRAY(POINTARRAY *pa) void printPA(POINTARRAY *pa) { int t; - POINT4D *pt; + POINT4D pt; uchar *mflag; if ( TYPE_HASM(pa->dims) ) mflag = "M"; @@ -1648,18 +1615,18 @@ void printPA(POINTARRAY *pa) for (t =0; tnpoints;t++) { - pt = (POINT4D *)getPoint(pa,t); + getPoint4d_p(pa, t, &pt); if (TYPE_NDIMS(pa->dims) == 2) { - lwnotice(" %i : %lf,%lf",t,pt->x,pt->y); + lwnotice(" %i : %lf,%lf",t,pt.x,pt.y); } if (TYPE_NDIMS(pa->dims) == 3) { - lwnotice(" %i : %lf,%lf,%lf",t,pt->x,pt->y,pt->z); + lwnotice(" %i : %lf,%lf,%lf",t,pt.x,pt.y,pt.z); } if (TYPE_NDIMS(pa->dims) == 4) { - lwnotice(" %i : %lf,%lf,%lf,%lf",t,pt->x,pt->y,pt->z,pt->m); + lwnotice(" %i : %lf,%lf,%lf,%lf",t,pt.x,pt.y,pt.z,pt.m); } } @@ -2543,13 +2510,13 @@ ptarray_isccw(const POINTARRAY *pa) { int i; double area = 0; - POINT2D *p1, *p2; + POINT2D p1, p2; for (i=0; inpoints-1; i++) { - p1 = (POINT2D *)getPoint(pa, i); - p2 = (POINT2D *)getPoint(pa, i+1); - area += (p1->x * p2->y) - (p1->y * p2->x); + getPoint2d_p(pa, i, &p1); + getPoint2d_p(pa, i+1, &p2); + area += (p1.x * p2.y) - (p1.y * p2.x); } if ( area > 0 ) return 0; else return 1; diff --git a/lwgeom/lwgeom_box2dfloat4.c b/lwgeom/lwgeom_box2dfloat4.c index 7916ceb7f..5ebf10ad8 100644 --- a/lwgeom/lwgeom_box2dfloat4.c +++ b/lwgeom/lwgeom_box2dfloat4.c @@ -110,6 +110,7 @@ Datum LWGEOM_to_BOX2DFLOAT4(PG_FUNCTION_ARGS) { PG_RETURN_NULL(); // must be the empty geometry } + PG_RETURN_POINTER(result); } diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index 73f6199b6..124a2ab0e 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -38,7 +38,7 @@ void DP_findsplit2d(POINTARRAY *pts, int p1, int p2, int *split, double *dist) { int k; - POINT2D *pa, *pb, *pk; + POINT2D pa, pb, pk; double tmp; #if VERBOSE > 4 @@ -51,24 +51,24 @@ elog(NOTICE, "DP_findsplit called"); if (p1 + 1 < p2) { - pa = (POINT2D *)getPoint(pts, p1); - pb = (POINT2D *)getPoint(pts, p2); + getPoint2d_p(pts, p1, &pa); + getPoint2d_p(pts, p2, &pb); #if VERBOSE > 4 elog(NOTICE, "DP_findsplit: P%d(%f,%f) to P%d(%f,%f)", - p1, pa->x, pa->y, p2, pb->x, pb->y); + p1, pa.x, pa.y, p2, pb.x, pb.y); #endif for (k=p1+1; k 4 -elog(NOTICE, "DP_findsplit: P%d(%f,%f)", k, pk->x, pk->y); +elog(NOTICE, "DP_findsplit: P%d(%f,%f)", k, pk.x, pk.y); #endif /* distance computation */ - tmp = distance2d_pt_seg(pk, pa, pb); + tmp = distance2d_pt_seg(&pk, &pa, &pb); if (tmp > *dist) { @@ -114,7 +114,8 @@ DP_simplify2d(POINTARRAY *inpts, double epsilon) outpts->dims = inpts->dims; outpts->npoints=1; outpts->serialized_pointlist = (char *)palloc(ptsize*inpts->npoints); - memcpy(getPoint(outpts, 0), getPoint(inpts, 0), ptsize); + memcpy(getPoint_internal(outpts, 0), getPoint_internal(inpts, 0), + ptsize); #if VERBOSE > 3 elog(NOTICE, "DP_simplify: added P0 to simplified point array (size 1)"); @@ -133,8 +134,8 @@ DP_simplify2d(POINTARRAY *inpts, double epsilon) stack[++sp] = split; } else { outpts->npoints++; - memcpy(getPoint(outpts, outpts->npoints-1), - getPoint(inpts, stack[sp]), + memcpy(getPoint_internal(outpts, outpts->npoints-1), + getPoint_internal(inpts, stack[sp]), ptsize); #if VERBOSE > 3 elog(NOTICE, "DP_simplify: added P%d to simplified point array (size: %d)", stack[sp], outpts->npoints); @@ -385,13 +386,13 @@ Datum LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) length = lwgeom_pointarray_length2d(ipa); tlength = 0; for( i = 0; i < nsegs; i++ ) { - POINT2D *p1, *p2; + POINT2D p1, p2; - p1 = (POINT2D *)getPoint(ipa, i); - p2 = (POINT2D *)getPoint(ipa, i+1); + getPoint2d_p(ipa, i, &p1); + getPoint2d_p(ipa, i+1, &p2); /* Find the relative length of this segment */ - slength = distance2d_pt_pt(p1, p2)/length; + slength = distance2d_pt_pt(&p1, &p2)/length; /* If our target distance is before the total length we've seen * so far. create a new point some distance down the current @@ -399,8 +400,8 @@ Datum LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) */ if( distance < tlength + slength ) { double dseg = (distance - tlength) / slength; - pt.x = (p1->x) + ((p2->x - p1->x) * dseg); - pt.y = (p1->y) + ((p2->y - p1->y) * dseg); + pt.x = (p1.x) + ((p2.x - p1.x) * dseg); + pt.y = (p1.y) + ((p2.y - p1.y) * dseg); pt.z = 0; pt.m = 0; opa = pointArray_construct((char *)&pt, @@ -665,10 +666,10 @@ lwpoly_grid(LWPOLY *poly, gridspec *grid) POINTARRAY *newring; #ifdef CHECK_RING_IS_CLOSE - POINT2D *p1, *p2; - p1 = (POINT2D *)getPoint(ring, 0); - p2 = (POINT2D *)getPoint(ring, ring->npoints-1); - if ( ! SAMEPOINT(p1, p2) ) + POINT2D p1, p2; + getPoint2d_p(ring, 0, &p1); + getPoint2d_p(ring, ring->npoints-1, &p2); + if ( ! SAMEPOINT(&p1, &p2) ) elog(NOTICE, "Before gridding: first point != last point"); #endif @@ -686,9 +687,9 @@ lwpoly_grid(LWPOLY *poly, gridspec *grid) } #ifdef CHECK_RING_IS_CLOSE - p1 = (POINT2D *)getPoint(newring, 0); - p2 = (POINT2D *)getPoint(newring, newring->npoints-1); - if ( ! SAMEPOINT(p1, p2) ) + getPoint2d_p(newring, 0, &p2); + getPoint2d_p(newring, newring->npoints-1, &p2); + if ( ! SAMEPOINT(&p1, &p2) ) elog(NOTICE, "After gridding: first point != last point"); #endif @@ -729,11 +730,12 @@ elog(NOTICE, "grid_polygon3d: simplified polygon with %d rings", nrings); LWPOINT * lwpoint_grid(LWPOINT *point, gridspec *grid) { - POINT2D *p = (POINT2D *)getPoint(point->point, 0); + POINT2D p; + getPoint2d_p(point->point, 0, &p); double x, y; - x = rint((p->x - grid->ipx)/grid->xsize) * + x = rint((p.x - grid->ipx)/grid->xsize) * grid->xsize + grid->ipx; - y = rint((p->y - grid->ipy)/grid->ysize) * + y = rint((p.y - grid->ipy)/grid->ysize) * grid->ysize + grid->ipy; #if VERBOSE diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 86d0ffd1d..db7450276 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -87,22 +87,28 @@ void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff) { int i; + POINT3DZ p3d; + POINT2D p2d; if ( TYPE_HASZ(pa->dims) ) { for (i=0; inpoints; i++) { - POINT3DZ *p = (POINT3DZ *)getPoint(pa, i); - p->x += xoff; - p->y += yoff; - p->z += zoff; + getPoint3dz_p(pa, i, &p3d); + p3d.x += xoff; + p3d.y += yoff; + p3d.z += zoff; + memcpy(getPoint_internal(pa, i), &p3d, + sizeof(POINT3DZ)); } } else { for (i=0; inpoints; i++) { - POINT2D *p = (POINT2D *)getPoint(pa, i); - p->x += xoff; - p->y += yoff; + getPoint2d_p(pa, i, &p2d); + p2d.x += xoff; + p2d.y += yoff; + memcpy(getPoint_internal(pa, i), &p2d, + sizeof(POINT2D)); } } } @@ -1400,8 +1406,9 @@ Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS) for (i=0; ipoints->npoints; i++) { - POINT2D *p = (POINT2D *)getPoint(line1->points, i); - double dist = distance2d_pt_ptarray(p, line2->points); + POINT2D p; + getPoint2d_p(line1->points, i, &p); + double dist = distance2d_pt_ptarray(&p, line2->points); if (dist > maxdist) maxdist = dist; } @@ -1415,7 +1422,8 @@ Datum LWGEOM_translate(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); uchar *srl = SERIALIZED_FORM(geom); - BOX2DFLOAT4 *box; + BOX2DFLOAT4 box; + int hasbbox; double xoff = PG_GETARG_FLOAT8(1); double yoff = PG_GETARG_FLOAT8(2); @@ -1424,16 +1432,17 @@ Datum LWGEOM_translate(PG_FUNCTION_ARGS) lwgeom_translate_recursive(srl, xoff, yoff, zoff); /* COMPUTE_BBOX WHEN_SIMPLE */ - if ( (box = getbox2d_internal(srl)) ) + hasbbox=getbox2d_p(srl, &box); + if ( hasbbox ) { - box->xmin += xoff; - box->xmax += xoff; - box->ymin += yoff; - box->ymax += yoff; + box.xmin += xoff; + box.xmax += xoff; + box.ymin += yoff; + box.ymax += yoff; } // Construct PG_LWGEOM - geom = PG_LWGEOM_construct(srl, lwgeom_getsrid(srl), box?1:0); + geom = PG_LWGEOM_construct(srl, lwgeom_getsrid(srl), hasbbox); PG_RETURN_POINTER(geom); } @@ -1446,15 +1455,15 @@ Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS) double cy = PG_GETARG_FLOAT8(2); double rr = PG_GETARG_FLOAT8(3); LWPOINT *point; - POINT2D *pt; + POINT2D pt; geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); point = lwpoint_deserialize(SERIALIZED_FORM(geom)); if ( point == NULL ) PG_RETURN_NULL(); // not a point - pt = (POINT2D *)getPoint(point->point, 0); + getPoint2d_p(point->point, 0, &pt); - PG_RETURN_BOOL(lwgeom_pt_inside_circle(pt, cx, cy, rr)); + PG_RETURN_BOOL(lwgeom_pt_inside_circle(&pt, cx, cy, rr)); } void @@ -2253,7 +2262,7 @@ Datum centroid(PG_FUNCTION_ARGS) LWPOINT *point; PG_LWGEOM *result; POINTARRAY *ring, *pa; - POINT3DZ *p, cent; + POINT3DZ p, cent; int i,j,k; uint32 num_points_tot = 0; uchar *srl; @@ -2272,10 +2281,10 @@ Datum centroid(PG_FUNCTION_ARGS) ring = poly->rings[j]; for (k=0; knpoints-1; k++) { - p = (POINT3DZ *)getPoint(ring, k); - tot_x += p->x; - tot_y += p->y; - if ( TYPE_HASZ(ring->dims) ) tot_z += p->z; + getPoint3dz_p(ring, k, &p); + tot_x += p.x; + tot_y += p.y; + if ( TYPE_HASZ(ring->dims) ) tot_z += p.z; } num_points_tot += ring->npoints-1; } diff --git a/lwgeom/lwgeom_geos.c b/lwgeom/lwgeom_geos.c index f1fd5c109..6b6ca5e19 100644 --- a/lwgeom/lwgeom_geos.c +++ b/lwgeom/lwgeom_geos.c @@ -595,10 +595,15 @@ Datum convexhull(PG_FUNCTION_ARGS) PG_RETURN_NULL(); //never get here } - /* Have lwgeom bbox point to input one (if any) */ - lwout->bbox = getbox2d_internal(SERIALIZED_FORM(geom1)); - /* Mark lwgeom bbox to be externally owned */ - if ( lwout->bbox ) TYPE_SETHASBBOX(lwout->type, 0); + BOX2DFLOAT4 bbox; + + /* Copy input bbox if any */ + if ( getbox2d_p(SERIALIZED_FORM(geom1), &bbox) ) + { + lwout->bbox = &bbox; + /* Mark lwgeom bbox to be externally owned */ + TYPE_SETHASBBOX(lwout->type, 1); + } result = pglwgeom_serialize(lwout); if (result == NULL) @@ -1136,7 +1141,7 @@ Datum overlaps(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1152,13 +1157,13 @@ Datum overlaps(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax < box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->xmin > box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax < box1->ymin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin > box2->ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax < box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin > box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax < box1.ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin > box2.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1211,7 +1216,7 @@ Datum contains(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1227,13 +1232,13 @@ Datum contains(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmin < box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->xmax > box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin < box1->ymin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax > box1->ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin < box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax > box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin < box1.ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax > box1.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1286,7 +1291,7 @@ Datum within(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1302,13 +1307,13 @@ Datum within(PG_FUNCTION_ARGS) * geom2 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box1->xmin < box2->xmin ) PG_RETURN_BOOL(FALSE); - if ( box1->xmax > box2->xmax ) PG_RETURN_BOOL(FALSE); - if ( box1->ymin < box2->ymin ) PG_RETURN_BOOL(FALSE); - if ( box1->ymax > box2->ymax ) PG_RETURN_BOOL(FALSE); + if ( box1.xmin < box2.xmin ) PG_RETURN_BOOL(FALSE); + if ( box1.xmax > box2.xmax ) PG_RETURN_BOOL(FALSE); + if ( box1.ymin < box2.ymin ) PG_RETURN_BOOL(FALSE); + if ( box1.ymax > box2.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1362,7 +1367,7 @@ Datum crosses(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1378,13 +1383,13 @@ Datum crosses(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax < box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->xmin > box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax < box1->ymin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin > box2->ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax < box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin > box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax < box1.ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin > box2.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1438,7 +1443,7 @@ Datum intersects(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1454,13 +1459,13 @@ Datum intersects(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax < box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->xmin > box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax < box1->ymin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin > box2->ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax < box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin > box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax < box1.ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin > box2.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1511,7 +1516,7 @@ Datum touches(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1527,13 +1532,13 @@ Datum touches(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax < box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->xmin > box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax < box1->ymin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin > box2->ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax < box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin > box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax < box1.ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin > box2.ymax ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1586,7 +1591,7 @@ Datum disjoint(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1602,13 +1607,13 @@ Datum disjoint(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return TRUE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax < box1->xmin ) PG_RETURN_BOOL(TRUE); - if ( box2->xmin > box1->xmax ) PG_RETURN_BOOL(TRUE); - if ( box2->ymax < box1->ymin ) PG_RETURN_BOOL(TRUE); - if ( box2->ymin > box2->ymax ) PG_RETURN_BOOL(TRUE); + if ( box2.xmax < box1.xmin ) PG_RETURN_BOOL(TRUE); + if ( box2.xmin > box1.xmax ) PG_RETURN_BOOL(TRUE); + if ( box2.ymax < box1.ymin ) PG_RETURN_BOOL(TRUE); + if ( box2.ymin > box2.ymax ) PG_RETURN_BOOL(TRUE); } initGEOS(MAXIMUM_ALIGNOF); @@ -1820,7 +1825,7 @@ Datum geomequals(PG_FUNCTION_ARGS) PG_LWGEOM *geom2; Geometry *g1,*g2; bool result; - const BOX2DFLOAT4 *box1, *box2; + BOX2DFLOAT4 box1, box2; #ifdef PROFILE profstart(PROF_QRUN); @@ -1836,13 +1841,13 @@ Datum geomequals(PG_FUNCTION_ARGS) * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ - if ( (box1=getbox2d_internal(SERIALIZED_FORM(geom1))) && - (box2=getbox2d_internal(SERIALIZED_FORM(geom2))) ) + if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && + getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { - if ( box2->xmax != box1->xmax ) PG_RETURN_BOOL(FALSE); - if ( box2->xmin != box1->xmin ) PG_RETURN_BOOL(FALSE); - if ( box2->ymax != box1->ymax ) PG_RETURN_BOOL(FALSE); - if ( box2->ymin != box2->ymin ) PG_RETURN_BOOL(FALSE); + if ( box2.xmax != box1.xmax ) PG_RETURN_BOOL(FALSE); + if ( box2.xmin != box1.xmin ) PG_RETURN_BOOL(FALSE); + if ( box2.ymax != box1.ymax ) PG_RETURN_BOOL(FALSE); + if ( box2.ymin != box2.ymin ) PG_RETURN_BOOL(FALSE); } initGEOS(MAXIMUM_ALIGNOF); @@ -2037,7 +2042,7 @@ lwline_from_geometry(Geometry *g, char want3d) POINTARRAY *pa; LWLINE *line; int npoints; - POINT3D *pts, *ip, *op; + POINT3D *pts, *ip; int ptsize = want3d ? sizeof(POINT3D) : sizeof(POINT2D); int i; int SRID = GEOSGetSRID(g); @@ -2060,8 +2065,7 @@ lwline_from_geometry(Geometry *g, char want3d) for (i=0; ipoint, 0); + getPoint3dz_p(lwpoint->point, 0, &point); SRID = lwpoint->SRID; is3d = TYPE_HASZ(lwpoint->type); @@ -246,9 +246,9 @@ Geometry *PostGIS2GEOS_point(const LWPOINT *lwpoint) Coordinate *c; if (is3d) - c = new Coordinate(point->x, point->y, point->z); + c = new Coordinate(point.x, point.y, point.z); else - c = new Coordinate(point->x, point->y); + c = new Coordinate(point.x, point.y); Geometry *g = geomFactory->createPoint(*c); delete c; if (g==NULL) @@ -288,7 +288,7 @@ PostGIS2GEOS_linestring(const LWLINE *lwline) try{ uint32 t; Coordinate c; - POINT3D *p; + POINT3D p; //build coordinatelist & pre-allocate space #if GEOS_LAST_INTERFACE >= 2 @@ -300,15 +300,15 @@ PostGIS2GEOS_linestring(const LWLINE *lwline) { for (t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; - (*vc)[t].z = p->z; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; + (*vc)[t].z = p.z; #else - c.x = p->x; - c.y = p->y; - c.z = p->z; + c.x = p.x; + c.y = p.y; + c.z = p.z; coords->setAt(c ,t); #endif } @@ -317,14 +317,14 @@ PostGIS2GEOS_linestring(const LWLINE *lwline) { for (t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; (*vc)[t].z = DoubleNotANumber; #else - c.x = p->x; - c.y = p->y; + c.x = p.x; + c.y = p.y; c.z = DoubleNotANumber; coords->setAt(c ,t); #endif @@ -375,7 +375,7 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) LinearRing *outerRing; LinearRing *innerRing; CoordinateSequence *cl; - POINT3D *p; + POINT3D p; vector *innerRings; // make outerRing @@ -390,15 +390,15 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { for(t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; - (*vc)[t].z = p->z; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; + (*vc)[t].z = p.z; #else - c.x = p->x; - c.y = p->y; - c.z = p->z; + c.x = p.x; + c.y = p.y; + c.z = p.z; cl->setAt( c ,t); #endif } @@ -407,14 +407,14 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { for(t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; (*vc)[t].z = DoubleNotANumber; #else - c.x = p->x; - c.y = p->y; + c.x = p.x; + c.y = p.y; c.z = DoubleNotANumber; cl->setAt(c ,t); #endif @@ -443,15 +443,15 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { for(t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; - (*vc)[t].z = p->z; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; + (*vc)[t].z = p.z; #else - c.x = p->x; - c.y = p->y; - c.z = p->z; + c.x = p.x; + c.y = p.y; + c.z = p.z; cl->setAt(c ,t); #endif } @@ -460,14 +460,14 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { for(t=0; tnpoints; t++) { - p = (POINT3D *)getPoint(pa, t); + getPoint3dz_p(pa, t, &p); #if GEOS_LAST_INTERFACE >= 2 - (*vc)[t].x = p->x; - (*vc)[t].y = p->y; + (*vc)[t].x = p.x; + (*vc)[t].y = p.y; (*vc)[t].z = DoubleNotANumber; #else - c.x = p->x; - c.y = p->y; + c.x = p.x; + c.y = p.y; c.z = DoubleNotANumber; cl->setAt(c ,t); #endif diff --git a/lwgeom/lwgeom_gml.c b/lwgeom/lwgeom_gml.c index 8d68c17e7..bcf5593bf 100644 --- a/lwgeom/lwgeom_gml.c +++ b/lwgeom/lwgeom_gml.c @@ -411,7 +411,6 @@ static size_t pointArray_toGML(POINTARRAY *pa, char *output) { int i; - POINT4D *pt; char *ptr; ptr = output; @@ -420,23 +419,25 @@ pointArray_toGML(POINTARRAY *pa, char *output) { for (i=0; inpoints; i++) { - pt = (POINT4D *)getPoint(pa, i); + POINT2D pt; + getPoint2d_p(pa, i, &pt); if ( i ) ptr += sprintf(ptr, " "); ptr += sprintf(ptr, "%.*g,%.*g", - precision, pt->x, - precision, pt->y); + precision, pt.x, + precision, pt.y); } } else { for (i=0; inpoints; i++) { - pt = (POINT4D *)getPoint(pa, i); + POINT4D pt; + getPoint4d_p(pa, i, &pt); if ( i ) ptr += sprintf(ptr, " "); ptr += sprintf(ptr, "%.*g,%.*g,%.*g", - precision, pt->x, - precision, pt->y, - precision, pt->z); + precision, pt.x, + precision, pt.y, + precision, pt.z); } } @@ -503,6 +504,14 @@ getSRSbySRID(int SRID) /********************************************************************** * $Log$ + * Revision 1.10 2005/02/10 17:41:55 strk + * Dropped getbox2d_internal(). + * Removed all castings of getPoint() output, which has been renamed + * to getPoint_internal() and commented about danger of using it. + * Changed SERIALIZED_FORM() macro to use VARDATA() macro. + * All this changes are aimed at taking into account memory alignment + * constraints which might be the cause of recent crash bug reports. + * * Revision 1.9 2005/02/07 13:21:10 strk * Replaced DEBUG* macros with PGIS_DEBUG*, to avoid clashes with postgresql DEBUG * diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c index a26761236..91f8b39e3 100644 --- a/lwgeom/lwgeom_ogc.c +++ b/lwgeom/lwgeom_ogc.c @@ -327,7 +327,7 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) POINTARRAY *extring; LWLINE *line; PG_LWGEOM *result; - BOX2DFLOAT4 *bbox; + BOX2DFLOAT4 bbox, *bbox2; if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE ) { @@ -342,11 +342,13 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) // If the input geom has a bbox, use it for // the output geom, as exterior ring makes it up ! // COMPUTE_BBOX==WHEN_SIMPLE - bbox = getbox2d_internal(SERIALIZED_FORM(geom)); - if ( bbox ) bbox = box2d_clone(bbox); + if ( getbox2d_p(SERIALIZED_FORM(geom), &bbox) ) + { + bbox2 = &bbox; + } // This is a LWLINE constructed by exterior ring POINTARRAY - line = lwline_construct(poly->SRID, bbox, extring); + line = lwline_construct(poly->SRID, bbox2, extring); // Copy SRID from polygon line->SRID = poly->SRID; @@ -483,7 +485,8 @@ Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS) pfree_inspected(inspected); // Construct a point array - pts = pointArray_construct(getPoint(line->points, wanted_index-1), + pts = pointArray_construct(getPoint_internal(line->points, + wanted_index-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); // Construct an LWPOINT @@ -512,7 +515,7 @@ Datum LWGEOM_x_point(PG_FUNCTION_ARGS) PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWPOINT *point = NULL; - POINT2D *p; + POINT2D p; int i; geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); @@ -528,9 +531,9 @@ Datum LWGEOM_x_point(PG_FUNCTION_ARGS) if ( point == NULL ) PG_RETURN_NULL(); // Ok, now we have a point, let's get X - p = (POINT2D *)getPoint(point->point, 0); + getPoint2d_p(point->point, 0, &p); - PG_RETURN_FLOAT8(p->x); + PG_RETURN_FLOAT8(p.x); } // Y(GEOMETRY) -- find the first POINT(..) in GEOMETRY, returns its Y value. @@ -541,7 +544,7 @@ Datum LWGEOM_y_point(PG_FUNCTION_ARGS) PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWPOINT *point = NULL; - POINT2D *p; + POINT2D p; int i; geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); @@ -557,9 +560,9 @@ Datum LWGEOM_y_point(PG_FUNCTION_ARGS) if ( point == NULL ) PG_RETURN_NULL(); // Ok, now we have a point, let's get X - p = (POINT2D *)getPoint(point->point, 0); + getPoint2d_p(point->point, 0, &p); - PG_RETURN_FLOAT8(p->y); + PG_RETURN_FLOAT8(p.y); } // Z(GEOMETRY) -- find the first POINT(..) in GEOMETRY, returns its Z value. @@ -626,7 +629,7 @@ Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS) // Ok, now we have a line. // Construct a point array - pts = pointArray_construct(getPoint(line->points, 0), + pts = pointArray_construct(getPoint_internal(line->points, 0), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); @@ -677,7 +680,7 @@ Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS) // Construct a point array pts = pointArray_construct( - getPoint(line->points, line->points->npoints-1), + getPoint_internal(line->points, line->points->npoints-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); @@ -861,16 +864,16 @@ Datum LWGEOM_asBinary(PG_FUNCTION_ARGS) char line_is_closed(LWLINE *line) { - POINT4D *sp, *ep; + POINT3DZ sp, ep; - sp = (POINT4D *)getPoint(line->points, 0); - ep = (POINT4D *)getPoint(line->points, line->points->npoints-1); + 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 ( 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; + if ( sp.z != ep.z ) return 0; } return 1; diff --git a/lwgeom/lwgeom_spheroid.c b/lwgeom/lwgeom_spheroid.c index 006d7f91c..122934f5f 100644 --- a/lwgeom/lwgeom_spheroid.c +++ b/lwgeom/lwgeom_spheroid.c @@ -310,21 +310,24 @@ double lwgeom_pointarray_length_ellipse(POINTARRAY *pts, SPHEROID *sphere) * Computed 2d length of a POINTARRAY regardless of input dimensions * Uses ellipsoidal math to find the distance. */ -double lwgeom_pointarray_length2d_ellipse(POINTARRAY *pts, SPHEROID *sphere) +double +lwgeom_pointarray_length2d_ellipse(POINTARRAY *pts, SPHEROID *sphere) { double dist = 0.0; int i; + POINT2D frm; + POINT2D to; //elog(NOTICE, "lwgeom_pointarray_length2d_ellipse called"); if ( pts->npoints < 2 ) return 0.0; for (i=0; inpoints-1;i++) { - POINT2D *frm = (POINT2D *)getPoint(pts, i); - POINT2D *to = (POINT2D *)getPoint(pts, i+1); - dist += distance_ellipse(frm->y*M_PI/180.0, - frm->x*M_PI/180.0, to->y*M_PI/180.0, - to->x*M_PI/180.0, sphere); + getPoint2d_p(pts, i, &frm); + getPoint2d_p(pts, i+1, &to); + dist += distance_ellipse(frm.y*M_PI/180.0, + frm.x*M_PI/180.0, to.y*M_PI/180.0, + to.x*M_PI/180.0, sphere); } return dist; } @@ -492,7 +495,7 @@ Datum LWGEOM_distance_ellipsoid_point(PG_FUNCTION_ARGS) PG_LWGEOM *geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); SPHEROID *sphere = (SPHEROID *)PG_GETARG_POINTER(2); LWPOINT *point1, *point2; - POINT2D *p1, *p2; + POINT2D p1, p2; if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2)) { @@ -514,10 +517,10 @@ Datum LWGEOM_distance_ellipsoid_point(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - p1 = (POINT2D *)getPoint(point1->point, 0); - p2 = (POINT2D *)getPoint(point2->point, 0); - PG_RETURN_FLOAT8(distance_ellipse(p1->y*M_PI/180.0, - p1->x*M_PI/180.0, p2->y*M_PI/180.0, - p2->x*M_PI/180.0, sphere)); + getPoint2d_p(point1->point, 0, &p1); + getPoint2d_p(point2->point, 0, &p2); + PG_RETURN_FLOAT8(distance_ellipse(p1.y*M_PI/180.0, + p1.x*M_PI/180.0, p2.y*M_PI/180.0, + p2.x*M_PI/180.0, sphere)); } diff --git a/lwgeom/lwgeom_svg.c b/lwgeom/lwgeom_svg.c index 3e34ed916..db3a37532 100644 --- a/lwgeom/lwgeom_svg.c +++ b/lwgeom/lwgeom_svg.c @@ -85,7 +85,7 @@ geometry_to_svg(PG_LWGEOM *geometry, int svgrel, int precision) char *result; LWGEOM_INSPECTED *inspected; int t,u; - POINT2D *pt; + POINT2D pt; int size; int npts; @@ -117,16 +117,16 @@ geometry_to_svg(PG_LWGEOM *geometry, int svgrel, int precision) if (t) strcat(result, ","); - pt = (POINT2D *)getPoint(point->point, 0); + getPoint2d_p(point->point, 0, &pt); if (svgrel == 1) { //render circle - print_svg_coords(result, pt, precision); + print_svg_coords(result, &pt, precision); } else { //render circle - print_svg_circle(result, pt, precision); + print_svg_circle(result, &pt, precision); } } @@ -223,22 +223,22 @@ void print_svg_path_abs(char *result, POINTARRAY *pa, int precision) { int u; - POINT2D *pt; + POINT2D pt; char x[MAX_DIGS_DOUBLE+3]; char y[MAX_DIGS_DOUBLE+3]; result += strlen(result); for (u=0; unpoints; u++) { - pt = (POINT2D *)getPoint(pa, u); + getPoint2d_p(pa, u, &pt); if (u != 0) { result[0] = ' '; result++; } - sprintf(x, "%.*f", precision, pt->x); + sprintf(x, "%.*f", precision, pt.x); trim_trailing_zeros(x); - sprintf(y, "%.*f", precision, pt->y * -1); + sprintf(y, "%.*f", precision, pt.y * -1); trim_trailing_zeros(y); result+= sprintf(result,"%s %s", x, y); } @@ -249,17 +249,17 @@ void print_svg_path_rel(char *result, POINTARRAY *pa, int precision) { int u; - POINT2D *pt, *lpt; + POINT2D pt, lpt; char x[MAX_DIGS_DOUBLE+3]; char y[MAX_DIGS_DOUBLE+3]; result += strlen(result); - pt = (POINT2D *)getPoint(pa, 0); + getPoint2d_p(pa, 0, &pt); - sprintf(x, "%.*f", precision, pt->x); + sprintf(x, "%.*f", precision, pt.x); trim_trailing_zeros(x); - sprintf(y, "%.*f", precision, pt->y * -1); + sprintf(y, "%.*f", precision, pt.y * -1); trim_trailing_zeros(y); result += sprintf(result,"%s %s l", x, y); @@ -267,10 +267,10 @@ print_svg_path_rel(char *result, POINTARRAY *pa, int precision) lpt = pt; for (u=1; unpoints; u++) { - pt = (POINT2D *)getPoint(pa, u); - sprintf(x, "%.*f", precision, pt->x - lpt->x); + getPoint2d_p(pa, u, &pt); + sprintf(x, "%.*f", precision, pt.x - lpt.x); trim_trailing_zeros(x); - sprintf(y, "%.*f", precision, (pt->y - lpt->y) * -1); + sprintf(y, "%.*f", precision, (pt.y - lpt.y) * -1); trim_trailing_zeros(y); result+= sprintf(result," %s %s", x, y); lpt = pt; @@ -280,6 +280,14 @@ print_svg_path_rel(char *result, POINTARRAY *pa, int precision) /********************************************************************** * $Log$ + * Revision 1.8 2005/02/10 17:41:55 strk + * Dropped getbox2d_internal(). + * Removed all castings of getPoint() output, which has been renamed + * to getPoint_internal() and commented about danger of using it. + * Changed SERIALIZED_FORM() macro to use VARDATA() macro. + * All this changes are aimed at taking into account memory alignment + * constraints which might be the cause of recent crash bug reports. + * * Revision 1.7 2004/10/27 12:30:53 strk * AsSVG returns NULL on GEOMETRY COLLECTION input. * diff --git a/lwgeom/lwgeom_transform.c b/lwgeom/lwgeom_transform.c index 910c17100..8260804c2 100644 --- a/lwgeom/lwgeom_transform.c +++ b/lwgeom/lwgeom_transform.c @@ -174,13 +174,16 @@ lwgeom_transform_recursive(char *geom, PJ *inpj, PJ *outpj) LWLINE *line=NULL; LWPOINT *point=NULL; LWPOLY *poly=NULL; + POINT2D p; char *subgeom=NULL; point = lwgeom_getpoint_inspected(inspected,j); if (point != NULL) { - POINT2D *p = (POINT2D *) getPoint(point->point, 0); - transform_point(p, inpj, outpj); + getPoint2d_p(point->point, 0, &p); + transform_point(&p, inpj, outpj); + memcpy(getPoint_internal(point->point, 0), + &p, sizeof(POINT2D)); continue; } @@ -190,8 +193,10 @@ lwgeom_transform_recursive(char *geom, PJ *inpj, PJ *outpj) POINTARRAY *pts = line->points; for (i=0; inpoints; i++) { - POINT2D *p = (POINT2D *)getPoint(pts, i); - transform_point(p, inpj, outpj); + getPoint2d_p(pts, i, &p); + transform_point(&p, inpj, outpj); + memcpy(getPoint_internal(pts, i), + &p, sizeof(POINT2D)); } continue; } @@ -205,8 +210,10 @@ lwgeom_transform_recursive(char *geom, PJ *inpj, PJ *outpj) POINTARRAY *pts = poly->rings[i]; for (pi=0; pinpoints; pi++) { - POINT2D *p = (POINT2D *)getPoint(pts, pi); - transform_point(p, inpj, outpj); + getPoint2d_p(pts, pi, &p); + transform_point(&p, inpj, outpj); + memcpy(getPoint_internal(pts, pi), + &p, sizeof(POINT2D)); } } continue; diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index d9a7ddd3c..c355234b3 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -412,6 +412,8 @@ 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 @@ -429,48 +431,27 @@ lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points) if ( zmflag == 3 ) break; } - /* Allocate space for output pointarray */ - pa = ptarray_construct(zmflag&2, zmflag&1, npoints); - -#ifdef PGIS_DEBUG - lwnotice("lwline_from_lwpointarray: constructed pointarray for %d points, %d zmflag", - npoints, zmflag); -#endif + if ( zmflag == 0 ) ptsize=2*sizeof(double); + else if ( zmflag == 3 ) ptsize=4*sizeof(double); + else ptsize=3*sizeof(double); /* - * Fill pointarray + * Allocate output points array */ - switch (zmflag) + size = ptsize*npoints; + newpoints = lwalloc(size); + memset(newpoints, 0, size); + + ptr=newpoints; + for (i=0; ipoint, 0, - (POINT2D *)getPoint(pa, i)); - break; - - case 1: // 3dm - for (i=0; ipoint, 0, - (POINT3DM *)getPoint(pa, i)); - break; - - case 2: // 3dz - for (i=0; ipoint, 0, - (POINT3DZ *)getPoint(pa, i)); - break; - - case 3: // 4d - for (i=0; ipoint, 0, - (POINT4D *)getPoint(pa, i)); - break; - - default: - lwerror ("lwline_from_lwpointarray: unespected ZMflag: %d", zmflag); - return NULL; + 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); } @@ -483,49 +464,34 @@ lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint) unsigned int i; POINTARRAY *pa; char zmflag = TYPE_GETZM(mpoint->type); + size_t ptsize, size; + uchar *newpoints, *ptr; - /* Allocate space for output pointarray */ - pa = ptarray_construct(TYPE_HASZ(mpoint->type), - TYPE_HASM(mpoint->type), mpoint->ngeoms); + if ( zmflag == 0 ) ptsize=2*sizeof(double); + else if ( zmflag == 3 ) ptsize=4*sizeof(double); + else ptsize=3*sizeof(double); -#ifdef PGIS_DEBUG - lwnotice("lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag); -#endif + /* Allocate space for output points */ + size = ptsize*mpoint->ngeoms; + newpoints = lwalloc(size); + memset(newpoints, 0, size); - /* - * Fill pointarray - */ - switch (zmflag) + ptr=newpoints; + for (i=0; ingeoms; i++) { - case 0: // 2d - for (i=0; ingeoms; i++) - getPoint2d_p(mpoint->geoms[i]->point, 0, - (POINT2D *)getPoint(pa, i)); - break; - - case 1: // 3dm - for (i=0; ingeoms; i++) - getPoint3dm_p(mpoint->geoms[i]->point, 0, - (POINT3DM *)getPoint(pa, i)); - break; - - case 2: // 3dz - for (i=0; ingeoms; i++) - getPoint3dz_p(mpoint->geoms[i]->point, 0, - (POINT3DZ *)getPoint(pa, i)); - break; - - case 3: // 4d - for (i=0; ingeoms; i++) - getPoint4d_p(mpoint->geoms[i]->point, 0, - (POINT4D *)getPoint(pa, i)); - break; - - default: - lwerror ("lwline_from_lwmpoint: unespected ZMflag: %d", zmflag); - return NULL; + memcpy(ptr, + getPoint_internal(mpoint->geoms[i]->point, 0), + ptsize); + ptr+=ptsize; } + pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, + mpoint->ngeoms); + +#ifdef PGIS_DEBUG + lwnotice("lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag); +#endif + return lwline_construct(SRID, NULL, pa); } @@ -535,7 +501,8 @@ lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where) POINTARRAY *newpa; LWLINE *ret; - newpa = ptarray_addPoint(line->points, getPoint(point->point, 0), + newpa = ptarray_addPoint(line->points, + getPoint_internal(point->point, 0), TYPE_NDIMS(point->type), where); ret = lwline_construct(line->SRID, NULL, newpa); diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index 49ead83f9..9f2758ec7 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -173,21 +173,29 @@ lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point) LWPOINT * make_lwpoint2d(int SRID, double x, double y) { + POINT2D p; POINTARRAY *pa = ptarray_construct(0, 0, 1); - POINT2D *p = (POINT2D *)getPoint(pa, 0); - p->x = x; - p->y = y; + + p.x = x; + p.y = y; + + memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT2D)); + return lwpoint_construct(SRID, NULL, pa); } LWPOINT * make_lwpoint3dz(int SRID, double x, double y, double z) { + POINT3DZ p; POINTARRAY *pa = ptarray_construct(1, 0, 1); - POINT3DZ *p = (POINT3DZ *)getPoint(pa, 0); - p->x = x; - p->y = y; - p->z = z; + + p.x = x; + p.y = y; + p.z = z; + + memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DZ)); + return lwpoint_construct(SRID, NULL, pa); } @@ -195,10 +203,14 @@ LWPOINT * make_lwpoint3dm(int SRID, double x, double y, double m) { POINTARRAY *pa = ptarray_construct(0, 1, 1); - POINT3DM *p = (POINT3DM *)getPoint(pa, 0); - p->x = x; - p->y = y; - p->m = m; + POINT3DM p; + + p.x = x; + p.y = y; + p.m = m; + + memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DM)); + return lwpoint_construct(SRID, NULL, pa); } @@ -206,11 +218,15 @@ LWPOINT * make_lwpoint4d(int SRID, double x, double y, double z, double m) { POINTARRAY *pa = ptarray_construct(1, 1, 1); - POINT4D *p = (POINT4D *)getPoint(pa, 0); - p->x = x; - p->y = y; - p->z = z; - p->m = m; + POINT4D p; + + p.x = x; + p.y = y; + p.z = z; + p.m = m; + + memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT4D)); + return lwpoint_construct(SRID, NULL, pa); } diff --git a/lwgeom/measures.c b/lwgeom/measures.c index e406d6740..66c72eb8c 100644 --- a/lwgeom/measures.c +++ b/lwgeom/measures.c @@ -16,7 +16,7 @@ int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring) { int cn = 0; // the crossing number counter int i; - POINT2D *v1, *v2; + POINT2D v1, v2; #if INTEGRITY_CHECKS POINT2D first, last; @@ -37,26 +37,26 @@ int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring) #endif // loop through all edges of the polygon - v1 = (POINT2D *)getPoint(ring, 0); + getPoint2d_p(ring, 0, &v1); for (i=0; inpoints-1; i++) { double vt; - v2 = (POINT2D *)getPoint(ring, i+1); + getPoint2d_p(ring, i+1, &v2); // edge from vertex i to vertex i+1 if ( // an upward crossing - ((v1->y <= p->y) && (v2->y > p->y)) + ((v1.y <= p->y) && (v2.y > p->y)) // a downward crossing - || ((v1->y > p->y) && (v2->y <= p->y)) + || ((v1.y > p->y) && (v2.y <= p->y)) ) { - vt = (double)(p->y - v1->y) / (v2->y - v1->y); + vt = (double)(p->y - v1.y) / (v2.y - v1.y); // P.x x < v1->x + vt * (v2->x - v1->x)) + if (p->x < v1.x + vt * (v2.x - v1.x)) { // a valid crossing of y=p.y right of p.x ++cn; @@ -210,15 +210,15 @@ double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa) { double result = 0; int t; - POINT2D *start, *end; + POINT2D start, end; - start = (POINT2D *)getPoint(pa, 0); + getPoint2d_p(pa, 0, &start); for (t=1; tnpoints; t++) { double dist; - end = (POINT2D *)getPoint(pa, t); - dist = distance2d_pt_seg(p, start, end); + getPoint2d_p(pa, t, &end); + dist = distance2d_pt_seg(p, &start, &end); if (t==1) result = dist; else result = LW_MIN(result, dist); @@ -236,27 +236,27 @@ double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2) double result = 99999999999.9; char result_okay = 0; //result is a valid min int t,u; - POINT2D *start,*end; - POINT2D *start2,*end2; + POINT2D start, end; + POINT2D start2, end2; #ifdef PGIS_DEBUG lwnotice("distance2d_ptarray_ptarray called (points: %d-%d)", l1->npoints, l2->npoints); #endif - start = (POINT2D *)getPoint(l1, 0); + getPoint2d_p(l1, 0, &start); for (t=1; tnpoints; t++) //for each segment in L1 { - end = (POINT2D *)getPoint(l1, t); + getPoint2d_p(l1, t, &end); - start2 = (POINT2D *)getPoint(l2, 0); + getPoint2d_p(l2, 0, &start2); for (u=1; unpoints; u++) //for each segment in L2 { double dist; - end2 = (POINT2D *)getPoint(l2, u); + getPoint2d_p(l2, u, &end2); - dist = distance2d_seg_seg(start, end, start2, end2); + dist = distance2d_seg_seg(&start, &end, &start2, &end2); //printf("line_line; seg %i * seg %i, dist = %g\n",t,u,dist_this); if (result_okay) @@ -310,7 +310,7 @@ int pt_in_poly_2d(POINT2D *p, LWPOLY *poly) // polygon or inside a hole) double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly) { - POINT2D *pt; + POINT2D pt; int i; double mindist = 0; @@ -333,17 +333,17 @@ double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly) // No intersection, have to check if a point is // inside polygon - pt = (POINT2D *)getPoint(pa, 0); + getPoint2d_p(pa, 0, &pt); // Outside outer ring, so min distance to a ring // is the actual min distance - if ( ! pt_in_ring_2d(pt, poly->rings[0]) ) return mindist; + if ( ! pt_in_ring_2d(&pt, poly->rings[0]) ) return mindist; // Its in the outer ring. // Have to check if its inside a hole for (i=1; inrings; i++) { - if ( pt_in_ring_2d(pt, poly->rings[i]) ) + if ( pt_in_ring_2d(&pt, poly->rings[i]) ) { // Its inside a hole, then the actual // distance is the min ring distance @@ -356,16 +356,21 @@ double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly) double distance2d_point_point(LWPOINT *point1, LWPOINT *point2) { - POINT2D *p1 = (POINT2D *)getPoint(point1->point, 0); - POINT2D *p2 = (POINT2D *)getPoint(point2->point, 0); - return distance2d_pt_pt(p1, p2); + POINT2D p1; + POINT2D p2; + + getPoint2d_p(point1->point, 0, &p1); + getPoint2d_p(point2->point, 0, &p2); + + return distance2d_pt_pt(&p1, &p2); } double distance2d_point_line(LWPOINT *point, LWLINE *line) { - POINT2D *p = (POINT2D *)getPoint(point->point, 0); + POINT2D p; + getPoint2d_p(point->point, 0, &p); POINTARRAY *pa = line->points; - return distance2d_pt_ptarray(p, pa); + return distance2d_pt_ptarray(&p, pa); } double distance2d_line_line(LWLINE *line1, LWLINE *line2) @@ -380,7 +385,8 @@ double distance2d_line_line(LWLINE *line1, LWLINE *line2) // if so, then return dist to hole, else return 0 (point in polygon) double distance2d_point_poly(LWPOINT *point, LWPOLY *poly) { - POINT2D *p = (POINT2D *)getPoint(point->point, 0); + POINT2D p; + getPoint2d_p(point->point, 0, &p); int i; #ifdef PGIS_DEBUG @@ -388,12 +394,12 @@ double distance2d_point_poly(LWPOINT *point, LWPOLY *poly) #endif // Return distance to outer ring if not inside it - if ( ! pt_in_ring_2d(p, poly->rings[0]) ) + if ( ! pt_in_ring_2d(&p, poly->rings[0]) ) { #ifdef PGIS_DEBUG lwnotice(" not inside outer-ring"); #endif - return distance2d_pt_ptarray(p, poly->rings[0]); + return distance2d_pt_ptarray(&p, poly->rings[0]); } // Inside the outer ring. @@ -403,12 +409,12 @@ double distance2d_point_poly(LWPOINT *point, LWPOLY *poly) for (i=1; inrings; i++) { // Inside a hole. Distance = pt -> ring - if ( pt_in_ring_2d(p, poly->rings[i]) ) + if ( pt_in_ring_2d(&p, poly->rings[i]) ) { #ifdef PGIS_DEBUG lwnotice(" inside an hole"); #endif - return distance2d_pt_ptarray(p, poly->rings[i]); + return distance2d_pt_ptarray(&p, poly->rings[i]); } } @@ -425,7 +431,7 @@ double distance2d_point_poly(LWPOINT *point, LWPOLY *poly) // Find min distance ring-to-ring. double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2) { - POINT2D *pt; + POINT2D pt; double mindist = 0; int i; @@ -434,12 +440,14 @@ double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2) #endif // if poly1 inside poly2 return 0 - pt = (POINT2D *)getPoint(poly1->rings[0], 0); - if ( pt_in_poly_2d(pt, poly2) ) return 0.0; + //pt = (POINT2D *)getPoint(poly1->rings[0], 0); + getPoint2d_p(poly1->rings[0], 0, &pt); + if ( pt_in_poly_2d(&pt, poly2) ) return 0.0; // if poly2 inside poly1 return 0 - pt = (POINT2D *)getPoint(poly2->rings[0], 0); - if ( pt_in_poly_2d(pt, poly1) ) return 0.0; + //pt = (POINT2D *)getPoint(poly2->rings[0], 0); + getPoint2d_p(poly2->rings[0], 0, &pt); + if ( pt_in_poly_2d(&pt, poly1) ) return 0.0; #ifdef PGIS_DEBUG lwnotice(" polys not inside each other"); @@ -477,14 +485,18 @@ double lwgeom_pointarray_length2d(POINTARRAY *pts) { double dist = 0.0; int i; + POINT2D frm; + POINT2D to; if ( pts->npoints < 2 ) return 0.0; for (i=0; inpoints-1;i++) { - POINT2D *frm = (POINT2D *)getPoint(pts, i); - POINT2D *to = (POINT2D *)getPoint(pts, i+1); - dist += sqrt( ( (frm->x - to->x)*(frm->x - to->x) ) + - ((frm->y - to->y)*(frm->y - to->y) ) ); + //POINT2D *frm = (POINT2D *)getPoint(pts, i); + getPoint2d_p(pts, i, &frm); + //POINT2D *to = (POINT2D *)getPoint(pts, i+1); + getPoint2d_p(pts, i+1, &to); + dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) + + ((frm.y - to.y)*(frm.y - to.y) ) ); } return dist; } @@ -495,6 +507,8 @@ lwgeom_pointarray_length(POINTARRAY *pts) { double dist = 0.0; int i; + POINT3DZ frm; + POINT3DZ to; if ( pts->npoints < 2 ) return 0.0; @@ -503,11 +517,13 @@ lwgeom_pointarray_length(POINTARRAY *pts) for (i=0; inpoints-1;i++) { - POINT3DZ *frm = (POINT3DZ *)getPoint(pts, i); - POINT3DZ *to = (POINT3DZ *)getPoint(pts, i+1); - dist += sqrt( ( (frm->x - to->x)*(frm->x - to->x) ) + - ((frm->y - to->y)*(frm->y - to->y) ) + - ((frm->z - to->z)*(frm->z - to->z) ) ); + //POINT3DZ *frm = (POINT3DZ *)getPoint(pts, i); + //POINT3DZ *to = (POINT3DZ *)getPoint(pts, i+1); + getPoint3dz_p(pts, i, &frm); + getPoint3dz_p(pts, i+1, &to); + dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) + + ((frm.y - to.y)*(frm.y - to.y) ) + + ((frm.z - to.z)*(frm.z - to.z) ) ); } return dist; @@ -519,6 +535,8 @@ double lwgeom_polygon_area(LWPOLY *poly) { double poly_area=0.0; int i; + POINT2D p1; + POINT2D p2; #ifdef PGIS_DEBUG lwnotice("in lwgeom_polygon_area (%d rings)", poly->nrings); @@ -533,9 +551,11 @@ double lwgeom_polygon_area(LWPOLY *poly) //lwnotice(" rings %d has %d points", i, ring->npoints); for (j=0; jnpoints-1; j++) { - POINT2D *p1 = (POINT2D *)getPoint(ring, j); - POINT2D *p2 = (POINT2D *)getPoint(ring, j+1); - ringarea += ( p1->x * p2->y ) - ( p1->y * p2->x ); + //POINT2D *p1 = (POINT2D *)getPoint(ring, j); + //POINT2D *p2 = (POINT2D *)getPoint(ring, j+1); + getPoint2d_p(ring, j, &p1); + getPoint2d_p(ring, j+1, &p2); + ringarea += ( p1.x * p2.y ) - ( p1.y * p2.x ); } ringarea /= 2.0; diff --git a/lwgeom/ptarray.c b/lwgeom/ptarray.c index b9bc8317d..7ac04c18a 100644 --- a/lwgeom/ptarray.c +++ b/lwgeom/ptarray.c @@ -26,73 +26,73 @@ ptarray_construct(char hasz, char hasm, unsigned int npoints) } -POINTARRAY * -ptarray_construct2d(uint32 npoints, const POINT2D *pts) -{ - POINTARRAY *pa = ptarray_construct(0, 0, npoints); - uint32 i; - - for (i=0; ix = pts[i].x; - pap->y = pts[i].y; - } - - return pa; -} - -POINTARRAY * -ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts) -{ - POINTARRAY *pa = ptarray_construct(1, 0, npoints); - uint32 i; - - for (i=0; ix = pts[i].x; - pap->y = pts[i].y; - pap->z = pts[i].z; - } - - return pa; -} - -POINTARRAY * -ptarray_construct3dm(uint32 npoints, const POINT3DM *pts) -{ - POINTARRAY *pa = ptarray_construct(0, 1, npoints); - uint32 i; - - for (i=0; ix = pts[i].x; - pap->y = pts[i].y; - pap->m = pts[i].m; - } - - return pa; -} - -POINTARRAY * -ptarray_construct4d(uint32 npoints, const POINT4D *pts) -{ - POINTARRAY *pa = ptarray_construct(0, 1, npoints); - uint32 i; - - for (i=0; ix = pts[i].x; - pap->y = pts[i].y; - pap->z = pts[i].z; - pap->m = pts[i].m; - } - - return pa; -} +//POINTARRAY * +//ptarray_construct2d(uint32 npoints, const POINT2D *pts) +//{ +// POINTARRAY *pa = ptarray_construct(0, 0, npoints); +// uint32 i; +// +// for (i=0; ix = pts[i].x; +// pap->y = pts[i].y; +// } +// +// return pa; +//} +// +//POINTARRAY * +//ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts) +//{ +// POINTARRAY *pa = ptarray_construct(1, 0, npoints); +// uint32 i; +// +// for (i=0; ix = pts[i].x; +// pap->y = pts[i].y; +// pap->z = pts[i].z; +// } +// +// return pa; +//} +// +//POINTARRAY * +//ptarray_construct3dm(uint32 npoints, const POINT3DM *pts) +//{ +// POINTARRAY *pa = ptarray_construct(0, 1, npoints); +// uint32 i; +// +// for (i=0; ix = pts[i].x; +// pap->y = pts[i].y; +// pap->m = pts[i].m; +// } +// +// return pa; +//} +// +//POINTARRAY * +//ptarray_construct4d(uint32 npoints, const POINT4D *pts) +//{ +// POINTARRAY *pa = ptarray_construct(0, 1, npoints); +// uint32 i; +// +// for (i=0; ix = pts[i].x; +// pap->y = pts[i].y; +// pap->z = pts[i].z; +// pap->m = pts[i].m; +// } +// +// return pa; +//} void ptarray_reverse(POINTARRAY *pa) @@ -106,8 +106,8 @@ ptarray_reverse(POINTARRAY *pa) for (i=0; i<=mid; i++) { uchar *from, *to; - from = getPoint(pa, i); - to = getPoint(pa, (last-i)); + from = getPoint_internal(pa, i); + to = getPoint_internal(pa, (last-i)); memcpy((uchar *)&pbuf, to, ptsize); memcpy(to, from, ptsize); memcpy(from, (uchar *)&pbuf, ptsize); @@ -122,24 +122,26 @@ int ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result) { int t; - POINT2D *pt; + POINT2D pt; if (pa->npoints == 0) return 0; - pt = (POINT2D *)getPoint(pa, 0); + //pt = (POINT2D *)getPoint(pa, 0); + getPoint2d_p(pa, 0, &pt); - result->xmin = pt->x; - result->xmax = pt->x; - result->ymin = pt->y; - result->ymax = pt->y; + result->xmin = pt.x; + result->xmax = pt.x; + result->ymin = pt.y; + result->ymax = pt.y; for (t=1;tnpoints;t++) { - pt = (POINT2D *)getPoint(pa, t); - if (pt->x < result->xmin) result->xmin = pt->x; - if (pt->y < result->ymin) result->ymin = pt->y; - if (pt->x > result->xmax) result->xmax = pt->x; - if (pt->y > result->ymax) result->ymax = pt->y; + //pt = (POINT2D *)getPoint(pa, t); + getPoint2d_p(pa, t, &pt); + if (pt.x < result->xmin) result->xmin = pt.x; + if (pt.y < result->ymin) result->ymin = pt.y; + if (pt.x > result->xmax) result->xmax = pt.x; + if (pt.y > result->ymax) result->ymax = pt.y; } return 1; @@ -151,27 +153,29 @@ BOX2DFLOAT4 * ptarray_compute_bbox(const POINTARRAY *pa) { int t; - POINT2D *pt; + POINT2D pt; BOX2DFLOAT4 *result; if (pa->npoints == 0) return NULL; result = lwalloc(sizeof(BOX2DFLOAT4)); - pt = (POINT2D *)getPoint(pa, 0); + //pt = (POINT2D *)getPoint(pa, 0); + getPoint2d_p(pa, 0, &pt); - result->xmin = pt->x; - result->xmax = pt->x; - result->ymin = pt->y; - result->ymax = pt->y; + result->xmin = pt.x; + result->xmax = pt.x; + result->ymin = pt.y; + result->ymax = pt.y; for (t=1;tnpoints;t++) { - pt = (POINT2D *)getPoint(pa, t); - if (pt->x < result->xmin) result->xmin = pt->x; - if (pt->y < result->ymin) result->ymin = pt->y; - if (pt->x > result->xmax) result->xmax = pt->x; - if (pt->y > result->ymax) result->ymax = pt->y; + //pt = (POINT2D *)getPoint(pa, t); + getPoint2d_p(pa, t, &pt); + if (pt.x < result->xmin) result->xmin = pt.x; + if (pt.y < result->ymin) result->ymin = pt.y; + if (pt.x > result->xmax) result->xmax = pt.x; + if (pt.y > result->ymax) result->ymax = pt.y; } return result; @@ -185,7 +189,8 @@ POINTARRAY * ptarray_segmentize2d(POINTARRAY *ipa, double dist) { double segdist; - POINT4D *p1, *p2, *ip, *op; + POINT4D p1, p2; + void *ip, *op; POINT4D pbuf; POINTARRAY *opa; int maxpoints = ipa->npoints; @@ -202,28 +207,28 @@ ptarray_segmentize2d(POINTARRAY *ipa, double dist) // Add first point opa->npoints++; - p1 = (POINT4D *)getPoint(ipa, ipoff); - op = (POINT4D *)getPoint(opa, opa->npoints-1); - memcpy(op, p1, ptsize); + getPoint4d_p(ipa, ipoff, &p1); + op = getPoint_internal(opa, opa->npoints-1); + memcpy(op, &p1, ptsize); ipoff++; while (ipoffnpoints) { - p2 = (POINT4D *)getPoint(ipa, ipoff); + getPoint4d_p(ipa, ipoff, &p2); - segdist = distance2d_pt_pt((POINT2D *)p1, (POINT2D *)p2); + segdist = distance2d_pt_pt((POINT2D *)&p1, (POINT2D *)&p2); if (segdist > dist) // add an intermediate point { - pbuf.x = p1->x + (p2->x-p1->x)/segdist * dist; - pbuf.y = p1->y + (p2->y-p1->y)/segdist * dist; + pbuf.x = p1.x + (p2.x-p1.x)/segdist * dist; + pbuf.y = p1.y + (p2.y-p1.y)/segdist * dist; // might also compute z and m if available... ip = &pbuf; - p1 = ip; + memcpy(&p1, ip, ptsize); } else // copy second point { - ip = p2; + ip = &p2; p1 = p2; ipoff++; } @@ -236,7 +241,7 @@ ptarray_segmentize2d(POINTARRAY *ipa, double dist) maxpoints*ptsize ); } - op = (POINT4D *)getPoint(opa, opa->npoints-1); + op = getPoint_internal(opa, opa->npoints-1); memcpy(op, ip, ptsize); } @@ -257,7 +262,7 @@ ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2) for (i=0; inpoints; i++) { - if ( memcmp(getPoint(pa1, i), getPoint(pa2, i), ptsize) ) + if ( memcmp(getPoint_internal(pa1, i), getPoint_internal(pa2, i), ptsize) ) return 0; } @@ -301,14 +306,15 @@ ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims, unsigned int where) if ( where ) { - memcpy(getPoint(ret, 0), getPoint(pa, 0), ptsize*where); + memcpy(getPoint_internal(ret, 0), getPoint_internal(pa, 0), ptsize*where); } - memcpy(getPoint(ret, where), (uchar *)&pbuf, ptsize); + memcpy(getPoint_internal(ret, where), (uchar *)&pbuf, ptsize); if ( where+1 != ret->npoints ) { - memcpy(getPoint(ret, where+1), getPoint(pa, where), + memcpy(getPoint_internal(ret, where+1), + getPoint_internal(pa, where), ptsize*(pa->npoints-where)); } @@ -337,9 +343,11 @@ ptarray_clone(const POINTARRAY *in) int ptarray_isclosed2d(const POINTARRAY *in) { - POINT2D *p1, *p2; - p1 = (POINT2D *)getPoint(in, 0); - p2 = (POINT2D *)getPoint(in, in->npoints-1); - if ( p1->x != p2->x || p1->y != p2->y ) return 0; - else return 1; + //POINT2D *p1, *p2; + if ( memcmp(getPoint_internal(in, 0), getPoint_internal(in, in->npoints-1), sizeof(POINT2D)) ) return 0; + return 1; + //p1 = (POINT2D *)getPoint(in, 0); + //p2 = (POINT2D *)getPoint(in, in->npoints-1); + //if ( p1->x != p2->x || p1->y != p2->y ) return 0; + //else return 1; }