[GRASS-SVN] r54141 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Dec 2 04:43:14 PST 2012
Author: mmetz
Date: 2012-12-02 04:43:14 -0800 (Sun, 02 Dec 2012)
New Revision: 54141
Modified:
grass/trunk/lib/vector/Vlib/snap.c
Log:
Vlib: reduce memory consumption in Vect_snap_line()
Modified: grass/trunk/lib/vector/Vlib/snap.c
===================================================================
--- grass/trunk/lib/vector/Vlib/snap.c 2012-12-02 09:35:35 UTC (rev 54140)
+++ grass/trunk/lib/vector/Vlib/snap.c 2012-12-02 12:43:14 UTC (rev 54141)
@@ -22,6 +22,10 @@
#include <grass/vector.h>
#include <grass/glocale.h>
+/* translate segment to box and back */
+#define X1W 0x01 /* x1 is West, x2 East */
+#define Y1S 0x02 /* y1 is South, y2 North */
+#define Z1B 0x04 /* z1 is Bottom, z2 Top */
/* Vertex */
typedef struct
@@ -32,15 +36,8 @@
/* -1 - init value */
} XPNT;
-/* Segment */
typedef struct
{
- double x1, y1, z1, /* start point */
- x2, y2, z2; /* end point */
-} XSEG;
-
-typedef struct
-{
int anchor;
double along;
} NEW;
@@ -124,15 +121,6 @@
return 1;
}
-/* for ilist qsort'ing and bsearch'ing */
-static int cmp_int(const void *a, const void *b)
-{
- int ai = *(int *)a;
- int bi = *(int *)b;
-
- return (ai < bi ? -1 : (ai > bi));
-}
-
/*!
\brief Snap selected lines to existing vertex in threshold.
@@ -612,7 +600,7 @@
int segment; /* index in segments array */
int asegments; /* number of allocated segments */
int nvertices; /* number of vertices */
- XSEG *XSegs = NULL; /* Array of segments */
+ char *XSegs = NULL; /* Array of segments */
NEW2 *New = NULL; /* Array of new points */
int anew = 0, nnew; /* allocated new points , number of new points */
struct boxlist *List;
@@ -703,10 +691,13 @@
/* reference segments */
if (v) {
+ char sides = 0;
+
/* Box */
if (LPoints->x[v - 1] < LPoints->x[v]) {
rect.boundary[0] = LPoints->x[v - 1];
rect.boundary[3] = LPoints->x[v];
+ sides |= X1W;
}
else {
rect.boundary[0] = LPoints->x[v];
@@ -715,6 +706,7 @@
if (LPoints->y[v - 1] < LPoints->y[v]) {
rect.boundary[1] = LPoints->y[v - 1];
rect.boundary[4] = LPoints->y[v];
+ sides |= Y1S;
}
else {
rect.boundary[1] = LPoints->y[v];
@@ -723,6 +715,7 @@
if (LPoints->z[v - 1] < LPoints->z[v]) {
rect.boundary[2] = LPoints->z[v - 1];
rect.boundary[5] = LPoints->z[v];
+ sides |= Z1B;
}
else {
rect.boundary[2] = LPoints->z[v];
@@ -736,27 +729,17 @@
if ((segment - 1) == asegments) {
asegments += 1000;
XSegs =
- (XSEG *) G_realloc(XSegs,
- (asegments + 1) * sizeof(XSEG));
+ (char *) G_realloc(XSegs,
+ (asegments + 1) * sizeof(char));
}
- XSegs[segment].x1 = LPoints->x[v - 1];
- XSegs[segment].x2 = LPoints->x[v];
- XSegs[segment].y1 = LPoints->y[v - 1];
- XSegs[segment].y2 = LPoints->y[v];
- if (with_z) {
- XSegs[segment].z1 = LPoints->z[v - 1];
- XSegs[segment].z1 = LPoints->z[v];
- }
- else {
- XSegs[segment].z1 = 0;
- XSegs[segment].z2 = 0;
- }
+ XSegs[segment] = sides;
segment++;
}
}
}
/* go through all vertices of the line to snap */
+ /* find nearest reference vertex */
for (v = 0; v < Points->n_points; v++) {
double dist2, tmpdist2;
double x, y, z;
@@ -776,7 +759,6 @@
rect.boundary[5] = Points->z[v] + thresh;
}
- /* find nearest reference vertex */
Vect_reset_boxlist(List);
RTreeSearch(pnt_tree, &rect, add_item_box, (void *)List);
@@ -812,6 +794,7 @@
}
/* go through all vertices of the line to snap */
+ /* find nearest reference segment */
for (v = 0; v < Points->n_points; v++) {
double dist2, tmpdist2;
double x, y, z;
@@ -831,28 +814,48 @@
rect.boundary[5] = Points->z[v] + thresh;
}
- /* find nearest reference segment */
Vect_reset_boxlist(List);
RTreeSearch(seg_tree, &rect, add_item_box, (void *)List);
for (i = 0; i < List->n_values; i++) {
+ double x1, y1, z1, x2, y2, z2;
double tmpx, tmpy, tmpz;
int segment, status;
segment = List->id[i];
-
+
+ if (XSegs[segment] & X1W) {
+ x1 = List->box[i].W;
+ x2 = List->box[i].E;
+ }
+ else {
+ x1 = List->box[i].E;
+ x2 = List->box[i].W;
+ }
+ if (XSegs[segment] & Y1S) {
+ y1 = List->box[i].S;
+ y2 = List->box[i].N;
+ }
+ else {
+ y1 = List->box[i].N;
+ y2 = List->box[i].S;
+ }
+ if (XSegs[segment] & Z1B) {
+ z1 = List->box[i].B;
+ z2 = List->box[i].T;
+ }
+ else {
+ z1 = List->box[i].T;
+ z2 = List->box[i].B;
+ }
+
/* Check the distance */
tmpdist2 =
dig_distance2_point_to_line(Points->x[v],
Points->y[v],
Points->z[v],
- XSegs[segment].x1,
- XSegs[segment].y1,
- XSegs[segment].z1,
- XSegs[segment].x2,
- XSegs[segment].y2,
- XSegs[segment].z2,
+ x1, y1, z1, x2, y2, z2,
with_z, &tmpx, &tmpy, &tmpz,
NULL, &status);
More information about the grass-commit
mailing list