32 LWDEBUG(2,
"Entered initiate_effectivearea");
72 static double triarea2d(
const double *P1,
const double *P2,
const double *P3)
74 return fabs(0.5*((P1[0]-P2[0])*(P3[1]-P2[1])-(P1[1]-P2[1])*(P3[0]-P2[0])));
81 static double triarea3d(
const double *P1,
const double *P2,
const double *P3)
83 LWDEBUG(2,
"Entered triarea3d");
84 double ax,bx,ay,by,az,bz,cx,cy,cz,
area;
97 area = fabs(0.5*(sqrt(cx*cx+cy*cy+cz*cz)));
105 static int cmpfunc (
const void * a,
const void * b)
115 return (v1 > v2) ? 1 : ((v1 < v2) ? -1 : 0);
134 double parentarea=((
areanode*) treearray[parent])->
area;
136 if(left<tree->usedSize)
138 leftarea=((
areanode*) treearray[left])->area;
139 if(parentarea>leftarea)
142 if(right<tree->usedSize)
144 rightarea=((
areanode*) treearray[right])->area;
145 if(rightarea<parentarea&&rightarea<leftarea)
151 tmp=treearray[parent];
152 treearray[parent]=treearray[swap];
158 if(swap<tree->usedSize)
159 down(tree,arealist,swap);
176 int parent=floor((c-1)/2);
181 tmp=treearray[parent];
182 treearray[parent]=treearray[c];
189 parent=floor((c-1)/2);
201 LWDEBUG(2,
"Entered minheap_pop");
209 down(tree,arealist,0);
221 int parent=floor((idx-1)/2);
224 up(tree,arealist,idx);
226 down(tree,arealist,idx);
236 LWDEBUG(2,
"Entered tune_areas");
242 double check_order_min_area = 0;
246 int current, before_current, after_current;
254 for (i=0;i<npoints;i++)
265 for (i=0;i<npoints;i++)
280 if (i<npoints-avoid_collaps)
286 lwerror(
"Oh no, this is a bug. For some reason the minHeap returned our points in the wrong order. Please file a ticket in PostGIS ticket system, or send a mial at the mailing list.Returned area = %lf, and last area = %lf",ea->
res_arealist[current],check_order_min_area);
312 if(after_current<npoints-1)
351 LWDEBUG(2,
"Entered ptarray_calc_areas");
371 for (i=1;i<(npoints)-1;i++)
391 for (i=1;i<(npoints)-1;i++)
396 tune_areas(ea,avoid_collaps,set_area, trshld);
404 LWDEBUG(2,
"Entered ptarray_set_effective_area");
453 LWDEBUG(2,
"Entered lwline_set_effective_area");
479 LWDEBUG(2,
"Entered lwpoly_set_effective_area");
482 int avoid_collapse=4;
492 for (i = 0; i < ipoly->
nrings; i++)
518 LWDEBUG(2,
"Entered lwcollection_set_effective_area");
530 for( i = 0; i < igeom->
ngeoms; i++ )
542 LWDEBUG(2,
"Entered lwgeom_set_effective_area");
static LWLINE * lwline_set_effective_area(const LWLINE *iline, int set_area, double trshld)
static double triarea2d(const double *P1, const double *P2, const double *P3)
Calculate the area of a triangle in 2d.
static void minheap_update(MINHEAP *tree, areanode *arealist, int idx)
The member of the minheap at index idx is changed.
static void up(MINHEAP *tree, __attribute__((__unused__)) areanode *e, int c)
Sift Up.
static LWPOLY * lwpoly_set_effective_area(const LWPOLY *ipoly, int set_area, double trshld)
static void down(MINHEAP *tree, areanode *arealist, int parent)
Sift Down.
static void destroy_minheap(MINHEAP tree)
static POINTARRAY * ptarray_set_effective_area(POINTARRAY *inpts, int avoid_collaps, int set_area, double trshld)
static areanode * minheap_pop(MINHEAP *tree, areanode *arealist)
Get a reference to the point with the smallest effective area from the root of the min heap.
static LWCOLLECTION * lwcollection_set_effective_area(const LWCOLLECTION *igeom, int set_area, double trshld)
static double triarea3d(const double *P1, const double *P2, const double *P3)
Calculate the area of a triangle in 3d space.
EFFECTIVE_AREAS * initiate_effectivearea(const POINTARRAY *inpts)
void destroy_effectivearea(EFFECTIVE_AREAS *ea)
static int cmpfunc(const void *a, const void *b)
We create the minheap by ordering the minheap array by the areas in the areanode structs that the min...
void ptarray_calc_areas(EFFECTIVE_AREAS *ea, int avoid_collaps, int set_area, double trshld)
We calculate the effective area for the first time.
LWGEOM * lwgeom_set_effective_area(const LWGEOM *igeom, int set_area, double trshld)
static void tune_areas(EFFECTIVE_AREAS *ea, int avoid_collaps, int set_area, double trshld)
To get the effective area, we have to check what area a point results in when all smaller areas are e...
static MINHEAP initiate_minheap(int npoints)
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
LWLINE * lwline_construct_empty(int srid, char hasz, char hasm)
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define FLAGS_GET_M(flags)
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
#define LW_TRUE
Return types for functions with status returns.
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
LWLINE * lwline_clone(const LWLINE *lwgeom)
int lwline_is_empty(const LWLINE *line)
int lwpoly_is_empty(const LWPOLY *poly)
int lwcollection_is_empty(const LWCOLLECTION *col)
Datum area(PG_FUNCTION_ARGS)
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
areanode * initial_arealist
Structure to hold pointarray and its arealist.
This structure holds a minheap tree that is used to keep track of what points that has the smallest e...
This structure is placed in an array with one member per point.