[GRASS-SVN] r68787 - grass/branches/releasebranch_7_0/raster/r.to.vect

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Jun 27 13:53:19 PDT 2016


Author: mmetz
Date: 2016-06-27 13:53:19 -0700 (Mon, 27 Jun 2016)
New Revision: 68787

Modified:
   grass/branches/releasebranch_7_0/raster/r.to.vect/areas.c
   grass/branches/releasebranch_7_0/raster/r.to.vect/areas_io.c
   grass/branches/releasebranch_7_0/raster/r.to.vect/global.h
   grass/branches/releasebranch_7_0/raster/r.to.vect/lines.c
   grass/branches/releasebranch_7_0/raster/r.to.vect/lines_io.c
   grass/branches/releasebranch_7_0/raster/r.to.vect/main.c
   grass/branches/releasebranch_7_0/raster/r.to.vect/util.c
Log:
r.to.vect: sync to trunk, fix #2045

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/areas.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/areas.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/areas.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -107,11 +107,13 @@
 int extract_areas(void)
 {
     double nullVal;
+    int i;
 
     row = col = top = 0;	/* get started for read of first */
     bottom = 1;			/* line from raster map */
     area_num = 0;
     tl_area = 0;
+    n_alloced_ptrs = 0;
 
     Rast_set_d_null_value(&nullVal, 1);
     /* represents the "outside", the external null values */
@@ -121,7 +123,7 @@
 
     scan_length = read_next();
     while (read_next()) {	/* read rest of file, one row at *//*   a time */
-	G_percent(row, n_rows, 2);
+	G_percent(row, n_rows + 1, 2);
 
 	for (col = 0; col < scan_length - 1; col++) {
 	    tl = get_raster_value(buffer[top], col);	/* top left in window */
@@ -136,15 +138,25 @@
 
 	row++;
     }
-    
+    G_percent(1, 1, 1);
+
     write_area(a_list, e_list, area_num, n_equiv);
 
     G_free(a_list);
+    for (i = 0; i < n_equiv; i++) {
+	if (e_list[i].ptr)
+	    G_free(e_list[i].ptr);
+    }
     G_free(e_list);
     G_free(v_list);
     G_free(buffer[0]);
     G_free(buffer[1]);
 
+    if (n_alloced_ptrs) {
+	/* should not happen */
+	G_warning("Memory leak: %d points are still in use", n_alloced_ptrs);
+    }
+
     return 0;
 }				/* extract_areas */
 
@@ -215,7 +227,7 @@
 	v_list[col]->row = row;	/* keep downward-growing point */
 	v_list[col]->fptr = h_ptr->bptr;	/*   and join it to predecessor */
 	h_ptr->bptr->fptr = v_list[col];	/*   of right-growing point */
-	G_free(h_ptr);		/* right-growing point disappears */
+	free_ptr(h_ptr);		/* right-growing point disappears */
 	h_ptr = NULPTR;		/* turn loose of pointers */
 	write_boundary(v_list[col]);	/* try to write line */
 	v_list[col] = NULPTR;	/* turn loose of pointers */
@@ -383,6 +395,8 @@
     ptr->col = col;
     ptr->fptr = ptr->bptr = NULPTR;
     ptr->node = ptr->left = ptr->right = 0;
+    
+    n_alloced_ptrs++;
 
     return (ptr);
 }

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/areas_io.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/areas_io.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/areas_io.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -28,15 +28,13 @@
 static int write_bnd(struct COOR *, struct COOR *, int);
 static int write_smooth_bnd(struct COOR *, struct COOR *, int);
 
-static int *equivs;
 
-
 /* write_line - attempt to write a line to output */
 /* just returns if line is not completed yet */
 int write_boundary(struct COOR *seed)
 {
-    struct COOR *point, *line_begin, *line_end;
-    int dir, line_type, n, n1;
+    struct COOR *point, *line_begin, *line_end, *last;
+    int dir, line_type, n, n1, i;
 
     point = seed;
     if ((dir = at_end(point))) {	/* already have one end of line */
@@ -68,12 +66,60 @@
 	    direction = FORWARD;	/* direction is arbitrary */
 	}
     }
+    dir = direction;
 
     if (smooth_flag == SMOOTH)
 	write_smooth_bnd(line_begin, line_end, n);
     else
 	write_bnd(line_begin, line_end, n);
 
+    /* now free all the pointers */
+    direction = dir;
+    point = line_begin;
+    last = NULPTR;
+    n1 = 0;
+
+    /* skip first and last point */
+    while ((point = move(point)) == line_begin);
+
+    while (point && point != line_end) {
+	last = point;
+	n1++;
+	point = move(point);
+
+	if (point == last) {
+	    /* should not happen */
+	    G_warning("loop during free ptrs, ptr %d of %d", n1, n);
+	    point = move(point);
+	}
+
+	if (last->fptr != NULPTR)
+	    if (last->fptr->fptr == last)
+		last->fptr->fptr = NULPTR;
+	/* it can be NULL after the previous line, even though before it wasn't */
+	if (last->fptr != NULPTR)
+	    if (last->fptr->bptr == last)
+		last->fptr->bptr = NULPTR;
+	if (last->bptr != NULPTR)
+	    if (last->bptr->fptr == last)
+		last->bptr->fptr = NULPTR;
+	if (last->bptr != NULPTR)
+	    if (last->bptr->bptr == last)
+		last->bptr->bptr = NULPTR;
+
+	free_ptr(last);
+    }
+
+    if (point != line_end) {
+	/* should not happen */
+	G_warning("Line end not reached, possible memory leak");
+    }
+
+    /* free first and last point */
+    free_ptr(line_begin);
+    if (line_end != line_begin)
+	free_ptr(line_end);
+
     return (0);
 }
 
@@ -94,20 +140,18 @@
 	points = Vect_new_line_struct();
     Vect_reset_line(points);
 
-    n++;			/* %% 6.4.88 */
-
     p = line_begin;
     y = cell_head.north - (double)p->row * cell_head.ns_res;
     x = cell_head.west + (double)p->col * cell_head.ew_res;
 
     Vect_append_point(points, x, y, 0.0);
 
-    for (i = 1; i < n; i++) {
+    for (i = 0; i < n; i++) {
 	last = p;
 
 	/* this should NEVER happen */
 	if ((p = move(p)) == NULPTR)
-	    G_fatal_error(_("Line terminated unexpectedly\n"
+	    G_fatal_error(_("write_bnd:  line terminated unexpectedly\n"
 			    "previous (%d) point %p (%d,%d,%d) %p %p"),
 			  direction, last, last->row, last->col, last->node,
 			  last->fptr, last->bptr);
@@ -118,35 +162,6 @@
 	Vect_append_point(points, x, y, 0.0);
     }
 
-    /* now free all the pointers */
-    p = line_begin;
-
-    for (i = 1; i < n; i++) {
-	last = p;
-	if ((p = move(p)) == NULPTR)
-	    break;
-	if (last == p)
-	    break;
-	if (last->fptr != NULPTR)
-	    if (last->fptr->fptr == last)
-		last->fptr->fptr = NULPTR;
-	/* it can be NULL after the previous line, even though before it wasn't */
-	if (last->fptr != NULPTR)
-	    if (last->fptr->bptr == last)
-		last->fptr->bptr = NULPTR;
-	if (last->bptr != NULPTR)
-	    if (last->bptr->fptr == last)
-		last->bptr->fptr = NULPTR;
-	if (last->bptr != NULPTR)
-	    if (last->bptr->bptr == last)
-		last->bptr->bptr = NULPTR;
-
-	G_free(last);
-    }				/* end of for i */
-
-    if (p != NULPTR)
-	G_free(p);
-
     Vect_write_line(&Map, GV_BOUNDARY, points, Cats);
 
     return 0;
@@ -172,8 +187,6 @@
 	points = Vect_new_line_struct();
     Vect_reset_line(points);
 
-    n++;			/* %% 6.4.88 */
-
     p = line_begin;
     /* allocate the arrays and get the first point */
 
@@ -183,13 +196,13 @@
 
     /* generate the list of smoothed points, may be duplicate points */
     total = 1;
-    for (i = 1; i < n; i++) {
+    for (i = 0; i < n; i++) {
 	if (i < 10)
 	    G_debug(3, " row: %d col: %d\n", p->row, p->col);
 
 	last = p;
 	if ((p = move(p)) == NULPTR) {	/* this should NEVER happen */
-	    G_debug(3, "write_line:  line terminated unexpectedly\n");
+	    G_debug(3, "write_smooth_bnd:  line terminated unexpectedly\n");
 	    G_debug(3, "  previous (%d) point %p (%d,%d,%d) %p %p\n",
 		    direction, last, last->row, last->col, last->node,
 		    last->fptr, last->bptr);
@@ -219,44 +232,11 @@
 
     /* strip out the duplicate points from the list */
     Vect_line_prune(points);
-    G_debug(3, "removed duplicates: %d", total - points->n_points);
+    if (total != points->n_points)
+	G_debug(3, "removed duplicates: %d", total - points->n_points);
 
-    /* write files */
     Vect_write_line(&Map, GV_BOUNDARY, points, Cats);
 
-    /* now free all the pointers */
-    p = line_begin;
-
-    for (i = 1; i < n; i++) {
-	if (i < 10)
-	    G_debug(3, " row: %d col: %d\n", p->row, p->col);
-
-	last = p;
-	if ((p = move(p)) == NULPTR)
-	    break;
-	if (last == p)
-	    break;
-	if (last->fptr != NULPTR)
-	    if (last->fptr->fptr == last)
-		last->fptr->fptr = NULPTR;
-
-	/* now it can already ne NULL */
-	if (last->fptr != NULPTR)
-	    if (last->fptr->bptr == last)
-		last->fptr->bptr = NULPTR;
-	if (last->bptr != NULPTR)
-	    if (last->bptr->fptr == last)
-		last->bptr->fptr = NULPTR;
-	if (last->bptr != NULPTR)
-	    if (last->bptr->bptr == last)
-		last->bptr->bptr = NULPTR;
-
-	G_free(last);
-    }				/* end of for i */
-
-    if (p != NULPTR)
-	G_free(p);
-
     return 0;
 }
 
@@ -270,10 +250,12 @@
     int n, i;
     struct area_table *p;
     char *temp_buf;
+    int *equivs;
     int cat;
     int catNum;
     double x, y;
 
+    equivs = NULL;
     total_areas = 0;
     if (n_equiv < n_areas) {
 	equivs = (int *)G_malloc(n_areas * sizeof(int));
@@ -380,6 +362,9 @@
 	}
     }
     G_percent(1, 1, 1);
+
+    if (equivs)
+	G_free(equivs);
     
     return 0;
 }

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/global.h
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/global.h	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/global.h	2016-06-27 20:53:19 UTC (rev 68787)
@@ -44,6 +44,7 @@
 extern int input_fd;
 extern int row_length, row_count, n_rows;
 extern int total_areas;
+extern int n_alloced_ptrs;
 
 extern int smooth_flag;		/* this is 0 for no smoothing, 1 for smoothing of lines */
 extern int value_flag;		/* use raster values as categories */
@@ -123,3 +124,4 @@
 int at_end(struct COOR *);
 int read_row(void *);
 void insert_value(int, int, double);
+int free_ptr(struct COOR *ptr);

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/lines.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/lines.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/lines.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -63,6 +63,7 @@
 
 int extract_lines(void)
 {
+    n_alloced_ptrs = 0;
     row = -3;
     read_next();
     read_next();
@@ -181,6 +182,11 @@
     G_free(bottom);
     G_free(v_list);
 
+    if (n_alloced_ptrs) {
+	/* should not happen */
+	G_warning("Memory leak: %d points are still in use", n_alloced_ptrs);
+    }
+
     return 0;
 }
 
@@ -588,7 +594,7 @@
     else
 	q->bptr->bptr = p;
 
-    G_free(q);
+    free_ptr(q);
     write_line(p);
 
     return 0;
@@ -705,6 +711,8 @@
 
     p->bptr = p->fptr = NULL;
 
+    n_alloced_ptrs++;
+
     return (p);
 }
 

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/lines_io.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/lines_io.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/lines_io.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -48,7 +48,7 @@
 
 int write_line(struct COOR *seed)
 {
-    struct COOR *point, *begin, *end;
+    struct COOR *point, *begin, *end, *last;
     int dir, line_type, n, n1;
 
     point = seed;
@@ -87,9 +87,55 @@
 	}
     }
 
+    dir = direction;
+
     /* if (n > 2) */
     write_ln(begin, end, n);
 
+    /* now free all the pointers */
+    direction = dir;
+    point = begin;
+
+    /* skip first and last point */
+    while ((point = move(point)) == begin);
+
+    while (point && point != end) {
+	last = point;
+
+	point = move(point);
+	if (point == last) {
+	    /* should not happen */
+	    G_warning("loop during free ptrs, ptr %d of %d", n1, n);
+	    point = move(point);
+	}
+
+	if (last->fptr != NULL)
+	    if (last->fptr->fptr == last)
+		last->fptr->fptr = NULL;
+
+	/* now it can already ne NULL */
+	if (last->fptr != NULL)
+	    if (last->fptr->bptr == last)
+		last->fptr->bptr = NULL;
+	if (last->bptr != NULL)
+	    if (last->bptr->fptr == last)
+		last->bptr->fptr = NULL;
+	if (last->bptr != NULL)
+	    if (last->bptr->bptr == last)
+		last->bptr->bptr = NULL;
+	free_ptr(last);
+    }				/* end of for i */
+
+    if (point != end) {
+	/* should not happen */
+	G_warning("Line end not reached, possible memory leak");
+    }
+
+    /* free first and last point */
+    free_ptr(begin);
+    if (end != begin)
+	free_ptr(end);
+
     return (0);
 }
 
@@ -110,7 +156,6 @@
     Vect_reset_line(points);
 
     field = 1;
-    ++n;
 
     Vect_reset_cats(Cats);
 
@@ -124,7 +169,7 @@
     Vect_cat_set(Cats, field, cat);
     Vect_append_point(points, x, y, 0.0);
 
-    for (i = 1; i < n; i++) {
+    for (i = 0; i < n; i++) {
 	last = p;
 
 	/* this should NEVER happen */
@@ -162,35 +207,5 @@
 
     count++;
 
-    /* now free all the pointers */
-    p = begin;
-
-    for (i = 1; i < n; i++) {
-	last = p;
-
-	if ((p = move(p)) == NULL)
-	    break;
-	if (last == p)
-	    break;
-	if (last->fptr != NULL)
-	    if (last->fptr->fptr == last)
-		last->fptr->fptr = NULL;
-
-	/* now it can already ne NULL */
-	if (last->fptr != NULL)
-	    if (last->fptr->bptr == last)
-		last->fptr->bptr = NULL;
-	if (last->bptr != NULL)
-	    if (last->bptr->fptr == last)
-		last->bptr->fptr = NULL;
-	if (last->bptr != NULL)
-	    if (last->bptr->bptr == last)
-		last->bptr->bptr = NULL;
-	G_free(last);
-    }				/* end of for i */
-
-    if (p != NULL)
-	G_free(p);
-
     return 0;
 }

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/main.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/main.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/main.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -47,6 +47,7 @@
 int input_fd;
 int row_length, row_count, n_rows;
 int total_areas;
+int n_alloced_ptrs;
 
 int smooth_flag;		/* this is 0 for no smoothing, 1 for smoothing of lines */
 int value_flag;			/* use raster values as categories */
@@ -56,6 +57,11 @@
 dbDriver *driver;
 dbString sql, label;
 
+static int cmp_int(const void *a, const void *b)
+{
+    return (*(int *)a - *(int *)b);
+}
+
 int main(int argc, char *argv[])
 {
     struct GModule *module;
@@ -261,27 +267,53 @@
 
     Rast_close(input_fd);
 
-    if (!no_topol->answer)
-	Vect_build(&Map);
-
-
     /* insert cats and optionally labels if raster cats were used */
     if (driver && value_flag) {
 	char buf[1000];
-	int c, i, cat, fidx, ncats, lastcat, tp, id;
+	int c, i, j, cat;
+	struct ilist *clist;
+	int type;
 
-	fidx = Vect_cidx_get_field_index(&Map, 1);
-	if (fidx >= 0) {
-	    ncats = Vect_cidx_get_num_cats_by_index(&Map, fidx);
-	    lastcat = -1;
-            
+	clist = G_new_ilist();
+
+	/* create category list */
+	Vect_rewind(&Map);
+
+	while (1) {
+	    /* register line */
+	    type = Vect_read_next_line(&Map, NULL, Cats);
+
+	    /* Note: check for dead lines is not needed, because they are skipped by V1_read_next_line_nat() */
+	    if (type == -1) {
+		G_warning(_("Unable to read vector map"));
+		break;
+	    }
+	    else if (type == -2) {
+		break;
+	    }
+	    
+	    for (i = 0; i < Cats->n_cats; i++)
+		G_ilist_add(clist, Cats->cat[i]);
+	}
+	
+	if (clist->n_values > 0) {
+
+	    qsort(clist->value, clist->n_values, sizeof(int), cmp_int);
+	    j = 1;
+	    for (i = 1; i < clist->n_values; i++) {
+		if (clist->value[i] != clist->value[j - 1]) {
+		    clist->value[j] = clist->value[i];
+		    j++;
+		}
+	    }
+	    clist->n_values = j;
+
             G_important_message(_("Updating attributes..."));
-	    for (c = 0; c < ncats; c++) {
-		Vect_cidx_get_cat_by_index(&Map, fidx, c, &cat, &tp, &id);
+	    for (c = 0; c < clist->n_values; c++) {
+		G_percent(c, clist->n_values, 4);
+		
+		cat = clist->value[c];
 
-		if (lastcat == cat)
-		    continue;
-
 		/* find label, slow -> TODO faster */
 		db_set_string(&label, "");
 		for (i = 0; i < RastCats.ncats; i++) {
@@ -301,10 +333,10 @@
 		if (db_execute_immediate(driver, &sql) != DB_OK)
 		    G_fatal_error(_("Unable to insert into table: %s"),
 				  db_get_string(&sql));
-
-		lastcat = cat;
 	    }
+	    G_percent(1, 1, 1);
 	}
+	G_free_ilist(clist);
     }
 
     if (has_cats)
@@ -315,6 +347,9 @@
 	db_close_database_shutdown_driver(driver);
     }
 
+    if (!no_topol->answer)
+	Vect_build(&Map);
+
     Vect_close(&Map);
     G_done_msg(" ");
 

Modified: grass/branches/releasebranch_7_0/raster/r.to.vect/util.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.to.vect/util.c	2016-06-27 20:52:56 UTC (rev 68786)
+++ grass/branches/releasebranch_7_0/raster/r.to.vect/util.c	2016-06-27 20:53:19 UTC (rev 68787)
@@ -157,3 +157,10 @@
 	G_fatal_error(_("Cannot insert new row: %s"), db_get_string(&sql));
 
 }
+
+int free_ptr(struct COOR *ptr)
+{
+    G_free(ptr);
+    
+    return (--n_alloced_ptrs);
+}



More information about the grass-commit mailing list