[GRASS-SVN] r44899 - grass/trunk/vector/v.generalize

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jan 6 13:15:46 EST 2011


Author: mmetz
Date: 2011-01-06 10:15:45 -0800 (Thu, 06 Jan 2011)
New Revision: 44899

Modified:
   grass/trunk/vector/v.generalize/displacement.c
   grass/trunk/vector/v.generalize/main.c
   grass/trunk/vector/v.generalize/misc.c
   grass/trunk/vector/v.generalize/misc.h
   grass/trunk/vector/v.generalize/network.c
   grass/trunk/vector/v.generalize/operators.h
   grass/trunk/vector/v.generalize/v.generalize.html
Log:
do not delete areas, do not mix up area attributes

Modified: grass/trunk/vector/v.generalize/displacement.c
===================================================================
--- grass/trunk/vector/v.generalize/displacement.c	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/displacement.c	2011-01-06 18:15:45 UTC (rev 44899)
@@ -26,7 +26,7 @@
 #include "matrix.h"
 
 /* snakes method modified for displacement.
- * Function returns somthing. This function affects only the
+ * Function returns something. This function affects only the
  * lines specified in varray (or all lines if varray is null).
  Other lines are copied */
 int snakes_displacement(struct Map_info *In, struct Map_info *Out,
@@ -111,7 +111,7 @@
     }
 
     threshold2 = threshold * threshold;
-    /*select only the points which need to be displace */
+    /*select only the points which need to be displaced */
     for (i = 0; i < index; i++) {
 	if (need[point_index[i]])
 	    continue;

Modified: grass/trunk/vector/v.generalize/main.c
===================================================================
--- grass/trunk/vector/v.generalize/main.c	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/main.c	2011-01-06 18:15:45 UTC (rev 44899)
@@ -5,10 +5,11 @@
  *
  * AUTHOR(S):  Daniel Bundala
  *             OGR support by Martin Landa <landa.martin gmail.com> (2009)
+ *             Markus Metz: preserve areas and area attributes
  *
  * PURPOSE:    Module for line simplification and smoothing
  *
- * COPYRIGHT:  (C) 2007-2009 by the GRASS Development Team
+ * COPYRIGHT:  (C) 2007-2010 by the GRASS Development Team
  *
  *             This program is free software under the GNU General
  *             Public License (>=v2).  Read the file COPYING that
@@ -36,14 +37,13 @@
 #define SNAKES 8
 #define DOUGLAS_REDUCTION 9
 #define SLIDING_AVERAGING 10
-#define REMOVE_SMALL 11
 #define NETWORK 100
 #define DISPLACEMENT 101
 
 int main(int argc, char *argv[])
 {
     struct Map_info In, Out;
-    static struct line_pnts *Points;
+    struct line_pnts *Points;
     struct line_cats *Cats;
     int i, type, iter;
     struct GModule *module;	/* GRASS module for parsing arguments */
@@ -54,7 +54,7 @@
     struct Option *angle_thresh_opt, *degree_thresh_opt,
 	*closeness_thresh_opt;
     struct Option *betweeness_thresh_opt;
-    struct Flag *ca_flag, *rs_flag;
+    struct Flag *ca_flag;
     int with_z;
     int total_input, total_output;	/* Number of points in the input/output map respectively */
     double thresh, alpha, beta, reduction, slide, angle_thresh;
@@ -62,13 +62,11 @@
     int method;
     int look_ahead, iterations;
     int chcat;
-    int ret, layer;
-    int n_areas, n_orig_areas, n_lines;
-    double x, y;
+    int layer;
+    int n_lines;
     int simplification, mask_type;
     struct varray *varray;
     char *s;
-    int left, right;
 
     /* initialize GIS environment */
     G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
@@ -89,8 +87,8 @@
     field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
 
     type_opt = G_define_standard_option(G_OPT_V_TYPE);
-    type_opt->options = "line,boundary,area";
-    type_opt->answer = "line,boundary,area";
+    type_opt->options = "line,boundary";
+    type_opt->answer = "line,boundary";
 
     map_out = G_define_standard_option(G_OPT_V_OUTPUT);
 
@@ -101,14 +99,13 @@
     method_opt->required = YES;
     method_opt->multiple = NO;
     method_opt->options =
-	"douglas,douglas_reduction,lang,reduction,reumann,remove_small,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes,network,displacement";
+	"douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes,network,displacement";
     method_opt->answer = "douglas";
     method_opt->descriptions = _("douglas;Douglas-Peucker Algorithm;"
 				 "douglas_reduction;Douglas-Peucker Algorithm with reduction parameter;"
 				 "lang;Lang Simplification Algorithm;"
 				 "reduction;Vertex Reduction Algorithm eliminates points close to each other;"
 				 "reumann;Reumann-Witkam Algorithm;"
-				 "remove_small;Removes lines shorter than threshold and areas of area less than threshold;"
 				 "boyle;Boyle's Forward-Looking Algorithm;"
 				 "sliding_averaging;McMaster's Sliding Averaging Algorithm;"
 				 "distance_weighting;McMaster's Distance-Weighting Algorithm;"
@@ -211,15 +208,10 @@
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     where_opt = G_define_standard_option(G_OPT_DB_WHERE);
 
-
     ca_flag = G_define_flag();
     ca_flag->key = 'c';
     ca_flag->description = _("Copy attributes");
 
-    rs_flag = G_define_flag();
-    rs_flag->key = 'r';
-    rs_flag->description = _("Remove lines and areas smaller than threshold");
-
     /* options and flags parser */
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
@@ -270,11 +262,6 @@
 	/* we can displace only the lines */
 	mask_type = GV_LINE;
     }
-    else if (strcmp(s, "remove_small") == 0) {
-	method = REMOVE_SMALL;
-	/* switch -r flag on */
-	rs_flag->answer = 1;
-    }
     else {
 	G_fatal_error(_("Unknown method"));
 	exit(EXIT_FAILURE);
@@ -288,7 +275,6 @@
     case LANG:
     case VERTEX_REDUCTION:
     case REUMANN:
-    case REMOVE_SMALL:
 	simplification = 1;
 	break;
     default:
@@ -316,212 +302,195 @@
     }
 
 
-    /* parse filter option and select appropriate lines */
-    layer = Vect_get_field_number(&In, field_opt->answer);
-    if (where_opt->answer) {
-	if (layer < 1)
-	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "where");
-	if (cat_opt->answer)
-	    G_warning(_("'where' and 'cats' parameters were supplied, cat will be ignored"));
-	chcat = 1;
-	varray = Vect_new_varray(Vect_get_num_lines(&In));
-	if (Vect_set_varray_from_db
-	    (&In, layer, where_opt->answer, mask_type, 1, varray) == -1) {
-	    G_warning(_("Unable to load data from database"));
-	}
-    }
-    else if (cat_opt->answer) {
-	if (layer < 1)
-	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "cat");
-	varray = Vect_new_varray(Vect_get_num_lines(&In));
-	chcat = 1;
-	if (Vect_set_varray_from_cat_string
-	    (&In, layer, cat_opt->answer, mask_type, 1, varray) == -1) {
-	    G_warning(_("Problem loading category values"));
-	}
-    }
-    else {
-	chcat = 0;
-	varray = NULL;
-    }
-
     Vect_copy_head_data(&In, &Out);
     Vect_hist_copy(&In, &Out);
     Vect_hist_command(&Out);
-
+    
     total_input = total_output = 0;
 
+    chcat = 0;
+    varray = NULL;
+    layer = Vect_get_field_number(&In, field_opt->answer);
+    /* parse filter option and select appropriate lines */
+    if (method == DISPLACEMENT || method == NETWORK)
+	varray = parse_filter_options(&In, layer, mask_type,
+			      where_opt->answer, cat_opt->answer, &chcat);
+
     if (method == DISPLACEMENT) {
+	/* modifies only lines, all other features including boundaries are preserved */
+	G_message(_("Displacement..."));
 	snakes_displacement(&In, &Out, thresh, alpha, beta, 1.0, 10.0,
 			    iterations, varray);
     }
 
     /* TODO: rearrange code below. It's really messy */
     if (method == NETWORK) {
+	/* extracts lines of selected type, all other features are discarded */
+	G_message(_("Network generalization..."));
 	total_output =
-	    graph_generalization(&In, &Out, degree_thresh, closeness_thresh,
-				 betweeness_thresh);
+	    graph_generalization(&In, &Out, mask_type, degree_thresh, 
+	                         closeness_thresh, betweeness_thresh);
     }
-    else {
-	G_message(_("Generalization (%s)..."), method_opt->answer);
-	G_percent_reset();
+
+    /* copy tables here because method == NETWORK is complete and 
+     * tables for Out may be needed for parse_filter_options() below */
+    if (ca_flag->answer) {
+	if (method == NETWORK)
+	    copy_tables_by_cats(&In, &Out);
+	else
+	    Vect_copy_tables(&In, &Out, -1);
     }
-    i = 0;
-    n_lines = Vect_get_num_lines(&In);
-    while (method < NETWORK &&
-	   (type = Vect_read_next_line(&In, Points, Cats)) > 0) {
-	i++;
-	G_percent(i, n_lines, 1);
 
-	if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
-	    continue;
-	
-	if (type == GV_CENTROID && (mask_type & GV_BOUNDARY))
-	    continue;		/* skip old centroids,
-				 * we calculate new if we generalize boundarie */
-	total_input += Points->n_points;
+    /* smoothing/simplification */
+    if (method < NETWORK) {
+	/* modifies only lines of selected type, all other features are preserved */
+	int not_modified_boundaries = 0, n_oversimplified = 0;
+	struct line_pnts *APoints;  /* original Points */
 
-	if ((type & mask_type) && (!chcat || varray->c[i])) {
-	    int after = 0;
+	Vect_copy_map_lines(&In, &Out);
+	Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
+	/* varray needs to be retrieved from Out vector and not from In vector
+	 * because identical lines can have different ids
+	 * if dead lines are still registered in topo of In */
+	varray = parse_filter_options(&Out, layer, mask_type,
+			      where_opt->answer, cat_opt->answer, &chcat);
 
-	    for (iter = 0; iter < iterations; iter++) {
-		switch (method) {
-		case DOUGLAS:
-		    douglas_peucker(Points, thresh, with_z);
-		    break;
-		case DOUGLAS_REDUCTION:
-		    douglas_peucker_reduction(Points, thresh, reduction,
-					      with_z);
-		    break;
-		case LANG:
-		    lang(Points, thresh, look_ahead, with_z);
-		    break;
-		case VERTEX_REDUCTION:
-		    vertex_reduction(Points, thresh, with_z);
-		    break;
-		case REUMANN:
-		    reumann_witkam(Points, thresh, with_z);
-		    break;
-		case BOYLE:
-		    boyle(Points, look_ahead, with_z);
-		    break;
-		case SLIDING_AVERAGING:
-		    sliding_averaging(Points, slide, look_ahead, with_z);
-		    break;
-		case DISTANCE_WEIGHTING:
-		    distance_weighting(Points, slide, look_ahead, with_z);
-		    break;
-		case CHAIKEN:
-		    chaiken(Points, thresh, with_z);
-		    break;
-		case HERMITE:
-		    hermite(Points, thresh, angle_thresh, with_z);
-		    break;
-		case SNAKES:
-		    snakes(Points, alpha, beta, with_z);
-		    break;
-		}
-	    }
+	G_message("-----------------------------------------------------");
+	G_message(_("Generalization (%s)..."), method_opt->answer);
+	G_percent_reset();
 
+	APoints = Vect_new_line_struct();
 
-	    /* remove "oversimplified" lines */
-	    if (rs_flag->answer && simplification && type == GV_LINE &&
-		Vect_line_length(Points) < thresh)
-		continue;
-
-	    after = Points->n_points;
-	    total_output += after;
-	    Vect_write_line(&Out, type, Points, Cats);
-	}
-	else {
-	    total_output += Points->n_points;
-	    Vect_write_line(&Out, type, Points, Cats);
-	}
-    }
-
-    /* remove incorrect boundaries
-     * they may occur only if they were generalized */
-    if (mask_type & GV_BOUNDARY) {
-	int n_del = 0;
-	Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES);
 	n_lines = Vect_get_num_lines(&Out);
 	for (i = 1; i <= n_lines; i++) {
-	    type = Vect_read_line(&Out, Points, Cats, i);
+	    G_percent(i, n_lines, 1);
+
+	    type = Vect_read_line(&Out, APoints, Cats, i);
+
+	    if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
+		continue;
 	    
-	    if (layer > 0 && !Vect_cat_get(Cats, layer, NULL))
+	    if (!(type & GV_LINES) || !(mask_type & type))
 		continue;
+		
+	    Vect_line_prune(APoints);
 	    
-	    if (type != GV_BOUNDARY)
+	    if (APoints->n_points < 2)
+		/* Line of length zero */
 		continue;
-	    Vect_get_line_areas(&Out, i, &left, &right);
-	    if (left == 0 || right == 0) {
-		Vect_delete_line(&Out, i);
-		total_output -= Points->n_points;
-		n_del++;
-	    }
-	}
-	if (n_del)
-	    G_warning(_("%d boundaries were deleted, input areas are not preserved"), n_del);
 
-	/* make sure that clean topo is built at the end */
-	Vect_build_partial(&Out, GV_BUILD_NONE);
-    }
+	    total_input += APoints->n_points;
 
+	    if ((type & mask_type) && (!chcat || varray->c[i])) {
+		int after = 0;
 
-    /* calculate new centroids 
-     * We need to calculate them only if the boundaries
-     * were generalized
-     */
-    if ((mask_type & GV_BOUNDARY) && method != DISPLACEMENT) {
-	Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES);
-	n_areas = Vect_get_num_areas(&Out);
-	for (i = 1; i <= n_areas; i++) {
-	    /* skip dead area */
-	    if (!Vect_area_alive(&Out, i))
-		continue;
+		/* copy points */
+		Vect_reset_line(Points);
+		Vect_append_points(Points, APoints, GV_FORWARD);
+		    
+		for (iter = 0; iter < iterations; iter++) {
+		    switch (method) {
+		    case DOUGLAS:
+			douglas_peucker(Points, thresh, with_z);
+			break;
+		    case DOUGLAS_REDUCTION:
+			douglas_peucker_reduction(Points, thresh, reduction,
+						  with_z);
+			break;
+		    case LANG:
+			lang(Points, thresh, look_ahead, with_z);
+			break;
+		    case VERTEX_REDUCTION:
+			vertex_reduction(Points, thresh, with_z);
+			break;
+		    case REUMANN:
+			reumann_witkam(Points, thresh, with_z);
+			break;
+		    case BOYLE:
+			boyle(Points, look_ahead, with_z);
+			break;
+		    case SLIDING_AVERAGING:
+			sliding_averaging(Points, slide, look_ahead, with_z);
+			break;
+		    case DISTANCE_WEIGHTING:
+			distance_weighting(Points, slide, look_ahead, with_z);
+			break;
+		    case CHAIKEN:
+			chaiken(Points, thresh, with_z);
+			break;
+		    case HERMITE:
+			hermite(Points, thresh, angle_thresh, with_z);
+			break;
+		    case SNAKES:
+			snakes(Points, alpha, beta, with_z);
+			break;
+		    }
+		}
+		
+		/* safety check, BUG in method if not passed */
+		if (APoints->x[0] != Points->x[0] || 
+		    APoints->y[0] != Points->y[0] ||
+		    APoints->z[0] != Points->z[0])
+		    G_fatal_error(_("Method '%s' did not preserve first point"), method_opt->answer);
+		    
+		if (APoints->x[APoints->n_points - 1] != Points->x[Points->n_points - 1] || 
+		    APoints->y[APoints->n_points - 1] != Points->y[Points->n_points - 1] ||
+		    APoints->z[APoints->n_points - 1] != Points->z[Points->n_points - 1])
+		    G_fatal_error(_("Method '%s' did not preserve last point"), method_opt->answer);
 
-	    /* area i in Out is not necessarily equal to area i in In! */
-	    Vect_get_area_cats(&In, i, Cats);
-	    ret = Vect_get_point_in_area(&Out, i, &x, &y);
-	    if (ret < 0) {
-		G_warning(_("Unable to calculate centroid for area %d"), i);
-		continue;
+		Vect_line_prune(Points);
+		
+		/* oversimplified line */
+		if (Points->n_points < 2) {
+		    after = APoints->n_points;
+		    n_oversimplified++;
+		}
+		/* check for topology corruption */
+		else if (type == GV_BOUNDARY) {
+		    if (!check_topo(&Out, i, APoints, Points, Cats)) {
+			after = APoints->n_points;
+			not_modified_boundaries++;
+		    }
+		    else
+			after = Points->n_points;
+		}
+		else {
+		    /* type == GV_LINE */
+		    Vect_rewrite_line(&Out, i, type, Points, Cats);
+		    after = Points->n_points;
+		}
+
+		total_output += after;
 	    }
-	    Vect_reset_line(Points);
-	    Vect_append_point(Points, x, y, 0.0);
-	    Vect_write_line(&Out, GV_CENTROID, Points, Cats);
+	    else {
+		total_output += APoints->n_points;
+	    }
 	}
-	G_warning(_("New centroids were calculated, attribute attachment may be changed"));
-    }
+	if (not_modified_boundaries > 0)
+	    G_message(_("%d boundaries were not modified because modification would damage topology"),
+		      not_modified_boundaries);
+	if (n_oversimplified > 0)
+	    G_message(_("%d lines/boundaries were not modified due to over-simplification"),
+		      n_oversimplified);
+	G_message("-----------------------------------------------------");
 
-    /* remove small areas */
-    if (rs_flag->answer && simplification && (mask_type & GV_AREA)) {
-	Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
-	Vect_remove_small_areas(&Out, thresh, NULL, &slide);
-
 	/* make sure that clean topo is built at the end */
 	Vect_build_partial(&Out, GV_BUILD_NONE);
     }
 
     Vect_build(&Out);
 
-    /* finally copy tables */
-    if (ca_flag->answer)
-	copy_tables_by_cats(&In, &Out);
+    Vect_close(&In);
+    Vect_close(&Out);
 
-    /* warning about area corruption */
-    if (mask_type & GV_BOUNDARY && (n_orig_areas = Vect_get_num_areas(&In)) > 0) {
-	G_warning(_("Areas may have disappeared and/or area attribute attachment may have changed"));
-	G_warning(_("Try v.clean tool=prune thresh=%f"), thresh);
-    }
-
-    if (total_input != 0)
-	G_done_msg(_("Number of vertices reduced from %d to %d (%d%%)."),
+    G_message("-----------------------------------------------------");
+    if (total_input != 0 && total_input != total_output)
+	G_done_msg(_("Number of vertices %s from %d to %d (%d%%)."),
+		  simplification ? _("reduced") : _("changed"), 
 		  total_input, total_output,
 		  (total_output * 100) / total_input);
+    else
+	G_done_msg(" ");
 
-    Vect_close(&In);
-    Vect_close(&Out);
-
     exit(EXIT_SUCCESS);
 }

Modified: grass/trunk/vector/v.generalize/misc.c
===================================================================
--- grass/trunk/vector/v.generalize/misc.c	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/misc.c	2011-01-06 18:15:45 UTC (rev 44899)
@@ -3,7 +3,7 @@
  *
  * MODULE:     v.generalize
  *
- * AUTHOR(S):  Daniel Bundala
+ * AUTHOR(S):  Daniel Bundala, Markus Metz
  *
  * PURPOSE:    miscellaneous functions of v.generalize
  *          
@@ -74,7 +74,7 @@
 }
 
 /* TODO: The collection of categories is horrible in current version! 
- * Rverything repeats many times. We need some data structure
+ * Everything repeats many times. We need some data structure
  * implementing set! */
 int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out)
 {
@@ -186,3 +186,139 @@
     G_free(fields);
     return 1;
 }
+
+/* parse filter option and select appropriate lines */
+/* return array with selected lines or NULL */
+struct varray *parse_filter_options(struct Map_info *Map, int layer,
+                      int mask_type, char *where, char *cats, int *chcat)
+{
+    struct varray *varray;
+
+    if (where) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "where");
+	if (cats)
+	    G_warning(_("'where' and 'cats' parameters were supplied, cat will be ignored"));
+	*chcat = 1;
+	varray = Vect_new_varray(Vect_get_num_lines(Map));
+	if (Vect_set_varray_from_db
+	    (Map, layer, where, mask_type, 1, varray) == -1) {
+	    G_warning(_("Unable to load data from database"));
+	}
+    }
+    else if (cats) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "cat");
+	varray = Vect_new_varray(Vect_get_num_lines(Map));
+	*chcat = 1;
+	if (Vect_set_varray_from_cat_string
+	    (Map, layer, cats, mask_type, 1, varray) == -1) {
+	    G_warning(_("Problem loading category values"));
+	}
+    }
+    else
+	return NULL;
+	
+    return varray;
+}
+
+/* check topology corruption by boundary modification
+ * return 0 on corruption, 1 if modification is ok */
+int check_topo(struct Map_info *Out, int line, struct line_pnts *APoints,
+               struct line_pnts *Points, struct line_cats *Cats)
+{
+    int i, intersect, newline, left_old, right_old,
+	left_new, right_new;
+    struct bound_box box;
+    static struct line_pnts *BPoints = NULL;
+    static struct ilist *List = NULL;
+
+    if (!BPoints)
+	BPoints = Vect_new_line_struct();
+    if (!List)
+	List = Vect_new_list();
+
+    /* Check intersection of the modified boundary with other boundaries */
+    Vect_line_box(Points, &box);
+    Vect_select_lines_by_box(Out, &box, GV_BOUNDARY, List);
+
+    intersect = 0;
+    for (i = 0; i < List->n_values; i++) {
+	int j, bline;
+	struct line_pnts **AXLines, **BXLines;
+	int naxlines, nbxlines;
+
+	bline = List->value[i];
+	if (bline == line)
+	    continue;
+
+	Vect_read_line(Out, BPoints, NULL, bline);
+
+	/* Vect_line_intersection is quite slow, hopefully not so bad because only few 
+	 * intersections should be found if any */
+
+	Vect_line_intersection(Points, BPoints, &AXLines, &BXLines,
+			       &naxlines, &nbxlines, 0);
+
+	G_debug(4,
+		"bline = %d intersect = %d naxlines = %d nbxlines = %d",
+		bline, intersect, naxlines, nbxlines);
+
+	/* Free */
+	if (naxlines > 0) {
+	    for (j = 0; j < naxlines; j++) {
+		Vect_destroy_line_struct(AXLines[j]);
+	    }
+	    G_free(AXLines);
+	}
+	if (nbxlines > 0) {
+	    for (j = 0; j < nbxlines; j++) {
+		Vect_destroy_line_struct(BXLines[j]);
+	    }
+	    G_free(BXLines);
+	}
+
+	if (naxlines > 1 || nbxlines > 1) {
+	    intersect = 1;
+	    break;
+	}
+    }
+    
+    /* modified boundary intersects another boundary */
+    if (intersect)
+	return 0;
+
+    /* Get centroids on the left and right side */
+    Vect_get_line_areas(Out, line, &left_old, &right_old);
+    if (left_old < 0)
+	left_old = Vect_get_isle_area(Out, abs(left_old));
+    if (left_old > 0)
+	left_old = Vect_get_area_centroid(Out, left_old);
+    if (right_old < 0)
+	right_old = Vect_get_isle_area(Out, abs(right_old));
+    if (right_old > 0)
+	right_old = Vect_get_area_centroid(Out, right_old);
+
+    /* OK, rewrite modified boundary */
+    newline = Vect_rewrite_line(Out, line, GV_BOUNDARY, Points, Cats);
+
+    /* Check position of centroids */
+    Vect_get_line_areas(Out, newline, &left_new, &right_new);
+    if (left_new < 0)
+	left_new = Vect_get_isle_area(Out, abs(left_new));
+    if (left_new > 0)
+	left_new = Vect_get_area_centroid(Out, left_new);
+    if (right_new < 0)
+	right_new = Vect_get_isle_area(Out, abs(right_new));
+    if (right_new > 0)
+	right_new = Vect_get_area_centroid(Out, right_new);
+
+    if (left_new != left_old || right_new != right_old) {
+	G_debug(3,
+		"The modified boundary changes attachement of centroid -> not modified");
+	Vect_rewrite_line(Out, newline, GV_BOUNDARY, APoints, Cats);
+	return 0;
+    }
+    
+    return 1;
+}

Modified: grass/trunk/vector/v.generalize/misc.h
===================================================================
--- grass/trunk/vector/v.generalize/misc.h	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/misc.h	2011-01-06 18:15:45 UTC (rev 44899)
@@ -19,4 +19,14 @@
 /* returns 1 on success, 0 on failure */
 extern int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out);
 
+/* parse filter option and select appropriate lines */
+/* return array with selected lines or NULL */
+struct varray *parse_filter_options(struct Map_info *Map, int layer, 
+                      int mask_type, char *where, char *cats, int *chcat);
+
+/* check topology corruption by boundary modification
+ * return 0 on corruption, 1 if modification is ok */
+int check_topo(struct Map_info *, int, struct line_pnts *, 
+               struct line_pnts *, struct line_cats *);
+
 #endif

Modified: grass/trunk/vector/v.generalize/network.c
===================================================================
--- grass/trunk/vector/v.generalize/network.c	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/network.c	2011-01-06 18:15:45 UTC (rev 44899)
@@ -65,12 +65,12 @@
 /* writes the most important part of the In network to Out network
  * according to the thresholds, output is bigger for smaller
  * thresholds. Function returns the number of points written 
- TODO: rewrite ilist by somthing more space and time efficient
+ TODO: rewrite ilist by something more space and time efficient
  or at least, implement append which does not check whether
  the value is already in the list*/
 int graph_generalization(struct Map_info *In, struct Map_info *Out,
-			 double degree_thresh, double closeness_thresh,
-			 double betweeness_thresh)
+			 int mask_type, double degree_thresh, 
+			 double closeness_thresh, double betweeness_thresh)
 {
 
     int i;
@@ -85,7 +85,7 @@
     double *betw, *betweeness;
     struct ilist **prev;
 
-    Vect_net_build_graph(In, GV_LINE | GV_BOUNDARY, 0, 0, NULL, NULL, NULL, 0,
+    Vect_net_build_graph(In, mask_type, 0, 0, NULL, NULL, NULL, 0,
 			 0);
     gr = &(In->graph);
     /* build own graph by edge<->vertex */
@@ -207,7 +207,7 @@
 		}
 	    }
 	}
-	/*finally run another BFS from the leaves in the BFS DAG
+	/* finally run another BFS from the leaves in the BFS DAG
 	 * and calculate betweeness centrality measure */
 	front = 0;
 	back = 0;
@@ -245,8 +245,10 @@
 	     (comp[i] - 1.0) / closeness[i] >= closeness_thresh &&
 	     betweeness[i] >= betweeness_thresh)) {
 	    type = Vect_read_line(In, Points, Cats, i);
-	    output += Points->n_points;
-	    Vect_write_line(Out, type, Points, Cats);
+	    if (type & mask_type) {
+		output += Points->n_points;
+		Vect_write_line(Out, type, Points, Cats);
+	    }
 	}
     }
 

Modified: grass/trunk/vector/v.generalize/operators.h
===================================================================
--- grass/trunk/vector/v.generalize/operators.h	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/operators.h	2011-01-06 18:15:45 UTC (rev 44899)
@@ -21,9 +21,9 @@
 int snakes(struct line_pnts *Points, double alpha, double beta, int with_z);
 
 /* network.c */
-int graph_generalization(struct Map_info *In, struct Map_info *Out,
-			 double degree_thresh, double closeness_thresh,
-			 double betweeness_thresh);
+int graph_generalization(struct Map_info *In, struct Map_info *Out, 
+                         int type, double degree_thresh, 
+			 double closeness_thresh, double betweeness_thresh);
 
 /* displacement.c */
 int snakes_displacement(struct Map_info *In, struct Map_info *Out,

Modified: grass/trunk/vector/v.generalize/v.generalize.html
===================================================================
--- grass/trunk/vector/v.generalize/v.generalize.html	2011-01-06 11:04:57 UTC (rev 44898)
+++ grass/trunk/vector/v.generalize/v.generalize.html	2011-01-06 18:15:45 UTC (rev 44899)
@@ -1,6 +1,6 @@
 <h2>DESCRIPTION</h2>
 
-<em>v.generalise</em>
+<em>v.generalize</em>
 is a module for the generalization of GRASS vector maps. This module
 consists of algorithms for line simplification, line smoothing,
 network generalization and displacement (new methods may be added later).
@@ -8,177 +8,207 @@
 <em><a href="http://users.ox.ac.uk/~orie1848/tutorial.html">tutorial</a><br></em> 
 
 <h2>NOTES</h2>
-(Line) simplification is a process of reducing the complexity of vector features.
-The module transforms a line into another line consisting of fewer vertices, that
-still approximate the original line. Most of the algorithms described below
-select a subset of points on the original line.
+(Line) simplification is a process of reducing the complexity of vector 
+features. The module transforms a line into another line consisting of 
+fewer vertices, that still approximate the original line. Most of the 
+algorithms described below select a subset of points on the original line.
 
 <p>
 (Line) smoothing is a "reverse" process which takes as input a line and 
-produces a smoother approximate of the original.
-In some cases, this is achieved by inserting new vertices into the original line, and can 
-total up to 4000% of the number of vertices in the original. In such an instance, 
+produces a smoother approximate of the original. In some cases, this is 
+achieved by inserting new vertices into the original line, and can total 
+up to 4000% of the number of vertices in the original. In such an instance, 
 it is always a good idea to simplify the line after smoothing.
 
 <p>
-Smoothing and simplification algorithms implemented in this module work line by 
-line, i.e. simplification/smoothing of one line does not affect the other lines; 
-they are treated separately.  Also, the first and the last point of each line is
-never translated and/or deleted. 
+Smoothing and simplification algorithms implemented in this module work 
+line by line, i.e. simplification/smoothing of one line does not affect 
+the other lines; they are treated separately.  Also, the first and the 
+last point of each line is never translated and/or deleted. 
 
 <h3>SIMPLIFICATION</h3>
 
-<em>v.generalise</em> contains following line simplification algorithms:
+<em>v.generalize</em> contains following line simplification algorithms:
 <ul>
 <li>Douglas-Peucker Algorithm</li>
-<li>"Douglas-Peucker Reduction Algorithm"</li>
+<li>Douglas-Peucker Reduction Algorithm</li>
 <li>Lang Algorithm</li>
 <li>Vertex Reduction</li>
 <li>Reumann-Witkam Algorithm</li>
 <li>Remove Small Lines/Areas</li>
 </ul>
 
-Different algorithms require different parameters, but all the algorithms have
-one parameter in common: the <b>threshold</b> parameter. In general, the degree
-of simplification increases with the increasing value of <b>threshold</b>.<br>
+Different algorithms require different parameters, but all the algorithms 
+have one parameter in common: the <b>threshold</b> parameter. In general, 
+the degree of simplification increases with the increasing value of 
+<b>threshold</b>.<br>
 
-If the <b>-r</b> flag is passed, simplified lines that become shorter becomes shorter than the 
-<b>threshold</b> value are removed. Additionally, if the <b>type</b> parameter contains <b>area</b> 
-and a simplification algorithm is selected, then areas less than <b>threshold</b> are also removed.
-
 <h4>ALGORITHM DESCRIPTIONS</h4>
 
 <ul>
-<li> <i>Douglas-Peucker</i> - "Quicksort" of line simplification, the most widely used
-     algorithm. Input parameters: <b>input</b>, <b>threshold</b>. For more
-     information, please see: <A href="http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm">http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm</a>.</li>
-<li> <i>Douglas-Peucker Reduction Algorithm</i> is essentially the same algorithm as the
-     algorithm above, the difference being that it takes additional <b>reduction</b> parameter
-     which denotes the percentage of the number of points on the new line with respect 
-     to the number of points on the original line. Input parameters: <b>input</b>, 
+<li> <i>Douglas-Peucker</i> - "Quicksort" of line simplification, the 
+     most widely used algorithm. Input parameters: <b>input</b>, 
+     <b>threshold</b>. For more information, see: <br>
+     <A href="http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm">http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm</a>.</li>
+<li> <i>Douglas-Peucker Reduction Algorithm</i> is essentially the same 
+     algorithm as the algorithm above, the difference being that it takes 
+     an additional <b>reduction</b> parameter which denotes the percentage 
+     of the number of points on the new line with respect to the number 
+     of points on the original line. Input parameters: <b>input</b>, 
      <b>threshold</b>, <b>reduction</b>.</li>     
-<li> <i>Lang</i> - Another standard algorithm. Input parameters: <b>input</b>, <b>threshold</b>, <b>look_ahead</b>. 
-     For an excellent description, see: <A href="http://www.sli.unimelb.edu.au/gisweb/LGmodule/LGLangVisualisation.htm">http://www.sli.unimelb.edu.au/gisweb/LGmodule/LGLangVisualisation.htm</a>.</li>
-<li> <i>Vertex Reduction</i> - Simplest among the algorithms. Input parameters: <b>input</b>, <b>threshold</b>.
-     Given a line, this algorithm removes the points of this line which are closer to each other than <b>threshold</b>.
-     More precisely, if p1 and p2 are two consecutive points, and the distance between p2 and p1 is less
-     than <b>threshold</b>, it removes p2 and repeats the same process on the remaining points.</li>
-<li> <i>Reuman-Witkam</i> - Input parameters: <b>input</b>, <b>threshold</b>. This algorithm quite
-     reasonably preserves the global characteristics of the lines. For more information
-     see <A href="http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/GIS1/Lernmodule/Lg/LG_de_6.html">http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/GIS1/Lernmodule/Lg/LG_de_6.html</a>(german)</li>
-<li> <i>Remove Small Lines/Areas</i> - removes the lines (strictly) shorter than threshold and areas (strictly) less than threshold.
-     Other lines/areas/boundaries are left unchanged. Input parameters: <b>input</b>, <b>threshold</b>             
+<li> <i>Lang</i> - Another standard algorithm. Input parameters: 
+     <b>input</b>, <b>threshold</b>, <b>look_ahead</b>. 
+     For an excellent description, see:  <br>
+     <A href="http://www.sli.unimelb.edu.au/gisweb/LGmodule/LGLangVisualisation.htm">http://www.sli.unimelb.edu.au/gisweb/LGmodule/LGLangVisualisation.htm</a>.</li>
+<li> <i>Vertex Reduction</i> - Simplest among the algorithms. Input 
+     parameters: <b>input</b>, <b>threshold</b>.
+     Given a line, this algorithm removes the points of this line which 
+     are closer to each other than <b>threshold</b>. More precisely, if 
+     p1 and p2 are two consecutive points, and the distance between p2 
+     and p1 is less than <b>threshold</b>, it removes p2 and repeats the 
+     same process on the remaining points.</li>
+<li> <i>Reuman-Witkam</i> - Input parameters: <b>input</b>, 
+     <b>threshold</b>. 
+     This algorithm quite reasonably preserves the global characteristics 
+     of the lines. For more information, see:  <br> 
+     <A href="http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/GIS1/Lernmodule/Lg/LG_de_6.html">http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/GIS1/Lernmodule/Lg/LG_de_6.html</a> (german).</li>
 </ul>
 
-<i>Douglas-Peucker</i> and <i>Douglas-Peucker Reduction Algorithm</i> use the same method
-to simplify the lines. Note that 
+<i>Douglas-Peucker</i> and <i>Douglas-Peucker Reduction Algorithm</i> 
+use the same method to simplify the lines. Note that 
 <div class="code"><pre>
-v.generalise input=in output=out method=douglas threshold=eps
+v.generalize input=in output=out method=douglas threshold=eps
 </pre></div>
 is equivalent to
 <div class="code"><pre>
-v.generalise input=in output=out method=douglas_reduction threshold=eps reduction=100
+v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=100
 </pre></div>
 However, in this case, the first method is faster. Also observe that
-<i>douglas_reduction</i> never outputs more vertices than <i>douglas</i>. And that,
-in general, <i>douglas</i> is more efficient than <i>douglas_reduction</i>.
-More importantly, the effect of
+<i>douglas_reduction</i> never outputs more vertices than <i>douglas</i>,
+and that, in general, <i>douglas</i> is more efficient than 
+<i>douglas_reduction</i>. More importantly, the effect of
 <div class="code"><pre>
-v.generalise input=in output=out method=douglas_reduction threshold=0 reduction=X
+v.generalize input=in output=out method=douglas_reduction threshold=0 reduction=X
 </pre></div>
-
 is that 'out' contains approximately only X% of points of 'in'.
 
 <h3>SMOOTHING</h3>
 
-The following smoothing algorithms are implemented in <em>v.generalise</em>
+The following smoothing algorithms are implemented in <em>v.generalize</em>
 
 <ul>
-<li><i>Boyle's Forward-Looking Algorithm</i> - The position of each point depends on the
-    position of the previous points and the point <b>look_ahead</b> ahead. 
-    <b>look_ahead</b> consecutive points. Input parameters: <b>input</b>, <b>look_ahead</b>.</li>
-<li><i>McMaster's Sliding Averaging Algorithm</i> - Input Parameters: <b>input</b>, <b>slide</b>, <b>look_ahead</b>.
-    The new position of each point is the average of the <b>look_ahead</b> points around. Parameter <b>slide</b>
-    is used for linear interpolation between old and new position (see below).</li>     
-<li><i>McMaster's Distance-Weighting Algorithm</i> - Works by taking the weighted average of <b>look_ahead</b> consecutive points
-    where the weight is the reciprocal of the distance from the point to the currently smoothed point. And parameter <b>slide</b> is used
-    for linear interpolation between the original position of the point and newly computed position where value 0 means the original position.
+<li><i>Boyle's Forward-Looking Algorithm</i> - The position of each point 
+    depends on the position of the previous points and the point 
+    <b>look_ahead</b> ahead. <b>look_ahead</b> consecutive points. Input 
+    parameters: <b>input</b>, <b>look_ahead</b>.</li>
+<li><i>McMaster's Sliding Averaging Algorithm</i> - Input Parameters: 
+    <b>input</b>, <b>slide</b>, <b>look_ahead</b>.
+    The new position of each point is the average of the <b>look_ahead</b> 
+    points around. Parameter <b>slide</b> is used for linear interpolation 
+    between old and new position (see below).</li>     
+<li><i>McMaster's Distance-Weighting Algorithm</i> - Takes the weighted 
+    average of <b>look_ahead</b> consecutive points where the weight is 
+    the reciprocal of the distance from the point to the currently 
+    smoothed point. The parameter <b>slide</b> is used for linear 
+    interpolation between the original position of the point and newly 
+    computed position where value 0 means the original position.
     Input parameters: <b>input</b>, <b>slide</b>, <b>look_ahead</b>.
     </li>
-<li><i>Chaiken's Algorithm</i> - "Inscribes" a line touching the original line such that the points on this new line
-    are at least <i>threshold</i> apart. Input parameters: <b>input</b>, <b>threshold</b>. This algorithm
-    approximates the given line very well.</li>
-<li> <i>Hermite Interpolation</i> - This algorithm takes the points of the given line as the control
-     points of hermite cubic spline and approximates this spline by the points approximately <b>threshold</b> apart.
-     This method has excellent results for the small values of <b>threshold</b>, but in this case it produces
-     a huge number of new points and some simplification is usually needed. Input parameters: <b>input</b>, <b>threshold</b>, <b>angle_thresh</b>.
-     <b>Angle_thresh</b> is used for reducing the number of the outputed points. It denotes the minimal
-     angle (in degrees) between two consecutive segments of line.</li>     
-<li> <i>Snakes</i> is the method of minimisation of the "energy" of the line. This method preserves the
-     general characteristics of the lines but smooths the "sharp corners" of the line. Input parameters <b>input</b>, <b>alpha</b>, <b>beta</b>.
-     This algorithm works very well for small values of <b>alpha</b> and <b>beta</b> (between 0 and 5). These
-     parameters affects the "sharpness" and the curvature of the computed line.</li>                          
+<li><i>Chaiken's Algorithm</i> - "Inscribes" a line touching the original 
+    line such that the points on this new line are at least 
+    <i>threshold</i> apart. Input parameters: <b>input</b>, 
+    <b>threshold</b>. This algorithm approximates the given line very 
+    well.</li>
+<li> <i>Hermite Interpolation</i> - This algorithm takes the points of 
+     the given line as the control points of hermite cubic spline and 
+     approximates this spline by the points approximately 
+     <b>threshold</b> apart. This method has excellent results for small 
+     values of <b>threshold</b>, but in this case it produces a huge 
+     number of new points and some simplification is usually needed. 
+     Input parameters: <b>input</b>, <b>threshold</b>, <b>angle_thresh</b>.
+     <b>Angle_thresh</b> is used for reducing the number of the points. 
+     It denotes the minimal angle (in degrees) between two consecutive 
+     segments of a line.</li>     
+<li> <i>Snakes</i> is the method of minimisation of the "energy" of a 
+     line. This method preserves the general characteristics of the lines 
+     but smooths the "sharp corners" of a line. Input parameters 
+     <b>input</b>, <b>alpha</b>, <b>beta</b>.
+     This algorithm works very well for small values of <b>alpha</b> and 
+     <b>beta</b> (between 0 and 5). These parameters affect the 
+     "sharpness" and the curvature of the computed line.</li>                          
 </ul>
 
-One of the key advantages of <i>Hermite Interpolation</i> is the fact that the computed line
-always passes through the points of the original line, whereas the lines produced by the 
-remaining algorithms never pass through these points. In some sense, this algorithm outputs
-a line which "circumscribes" the input line.
+One of the key advantages of <i>Hermite Interpolation</i> is the fact 
+that the computed line always passes through the points of the original 
+line, whereas the lines produced by the remaining algorithms never pass 
+through these points. In some sense, this algorithm outputs a line which 
+"circumscribes" the input line.
 
 <p>
-On the other hand, <i>Chaiken's Algorithm</i> outputs a line which "inscribes" a given line. 
-The output line always touches/intersects the centre of the input line segment between two 
-consecutive points. For more iterations, the property above does not hold, but the computed 
-lines are very similar to the Bezier Splines. The disadvantage of the two algorithms given above is that 
-they increase the number of points. However, <i>Hermite Interpolation</i> can be used as another 
-simplification algorithm. To achieve this, it is necessary to set <i>angle_thresh</i> to higher values (15 or so). 
+On the other hand, <i>Chaiken's Algorithm</i> outputs a line which 
+"inscribes" a given line. The output line always touches/intersects the 
+centre of the input line segment between two consecutive points. For 
+more iterations, the property above does not hold, but the computed 
+lines are very similar to the Bezier Splines. The disadvantage of the 
+two algorithms given above is that they increase the number of points. 
+However, <i>Hermite Interpolation</i> can be used as another 
+simplification algorithm. To achieve this, it is necessary to set 
+<i>angle_thresh</i> to higher values (15 or so). 
 
 <p>
-One restriction on both McMasters' Algorithms is that <i>look_ahead</i> parameter must be odd. Also
-note that these algorithms have no effect if <i>look_ahead = 1</i>. 
+One restriction on both McMasters' Algorithms is that <i>look_ahead</i> 
+parameter must be odd. Also note that these algorithms have no effect if 
+<i>look_ahead = 1</i>. 
 
 <p>
-Note that <i>Boyle's</i>, <i>McMasters'</i> and <i>Snakes</i> algorithm are sometimes used in the signal processing to smooth the signals.
-More importantly, these algorithms never change the number of points on the lines; they only
-translate the points, and do not insert any new points. 
+Note that <i>Boyle's</i>, <i>McMasters'</i> and <i>Snakes</i> algorithm 
+are sometimes used in the signal processing to smooth the signals.
+More importantly, these algorithms never change the number of points on 
+the lines; they only translate the points, and do not insert any new points. 
 
 <p>
-<i>Snakes</i> Algorithm is (asymptotically) the slowest among the algorithms presented above. Also,
-it requires quite a lot of memory. This means that it is not very efficient for maps with the lines
+<i>Snakes</i> Algorithm is (asymptotically) the slowest among the 
+algorithms presented above. Also, it requires quite a lot of memory. 
+This means that it is not very efficient for maps with the lines
 consisting of many segments.
 
 <h3>DISPLACEMENT</h3>
 
-The displacement is used when the lines overlap and/or are close to each other at the current
-level of detail. In general, displacement methods moves the conflicting features apart so 
-that they do not interact and can be distinguished.   
+The displacement is used when the lines overlap and/or are close to each 
+other at the current level of detail. In general, displacement methods 
+move the conflicting features apart so that they do not interact and can 
+be distinguished.   
 
 <p>
-This module implements algorithm for displacement of linear features based on
-the <i>Snakes</i> approach. This method generally yields very good results; however, it
-requires a lot of memory and is not very efficient.
+This module implements an algorithm for displacement of linear features 
+based on the <i>Snakes</i> approach. This method generally yields very 
+good results; however, it requires a lot of memory and is not very efficient.
 
 <p>
-Displacement is selected by <b>method=displacement</b>. It uses following parameters:
+Displacement is selected by <b>method=displacement</b>. It uses the 
+following parameters:
 
 <ul>
 <li>
-<b>threshold</b> - specifies critical distance. Two features interact if they are
-closer than <b>threshold</b> apart.
+<b>threshold</b> - specifies critical distance. Two features interact if 
+they are closer than <b>threshold</b> apart.
 </li>
 
 <li>
-<b>alpha</b>, <b>beta</b> - These parameters define the rigidity of lines. For greater
-values of <b>alpha</b>, <b>beta</b> (&gt;=1), the algorithm does a better job at retaining the original
-shape of the lines, possibly at the expense of displacement distance. If the values of <b>alpha</b>,
-<b>beta</b> are too small (&lt;=0.001), then the lines are moved sufficiently, but the geometry and topology of lines can
-be destroyed. Most likely the best way to find the good values of <b>alpha</b>, <b>beta</b>
+<b>alpha</b>, <b>beta</b> - These parameters define the rigidity of lines. 
+For larger values of <b>alpha</b>, <b>beta</b> (&gt;=1), the algorithm 
+does a better job at retaining the original shape of the lines, possibly 
+at the expense of displacement distance. If the values of <b>alpha</b>,
+<b>beta</b> are too small (&lt;=0.001), then the lines are moved 
+sufficiently, but the geometry and topology of lines can be destroyed. 
+Most likely the best way to find the good values of <b>alpha</b>, <b>beta</b>
 is by trial and error.
 </li>
 
 <li>
-<b>iterations</b> - denotes the number of iterations the interactions between
-the lines are resolved. Good starting points for values of <b>iterations</b> are between 10 and 100.
+<b>iterations</b> - denotes the number of iterations the interactions 
+between the lines are resolved. Good starting points for values of 
+<b>iterations</b> are between 10 and 100.
 </li>
 
 </ul>
@@ -202,28 +232,30 @@
 with at least <b>degree_thresh</b> different lines.
 </li>
 <li>
-<b>closeness_thresh</b> - is always in the range (0, 1]. Only the lines with
-the closeness centrality value at least <b>closeness_thresh</b> apart are selected. 
-The lines in the centre of a network have greater values of this measure than
-the lines near the border of a network. This means that this parameter can be used 
-for selecting the centre(s) of a network. Note that if closeness_thresh=0 then everything is selected.
+<b>closeness_thresh</b> - is always in the range (0, 1]. Only the lines 
+with the closeness centrality value at least <b>closeness_thresh</b> apart 
+are selected. The lines in the centre of a network have greater values of 
+this measure than the lines near the border of a network. This means that 
+this parameter can be used for selecting the centre(s) of a network. Note 
+that if closeness_thresh=0 then everything is selected.
 </li>
 <li>
-<b>betweeness_thresh</b> - Again, only the lines with a betweeness centrality
-measure at least <b>betweeness_thresh</b> are selected. This value is always
-positive and is larger for large networks. It denotes to what extent a line
-is in between the other lines in the network. This value is great for the lines
-which lie between other lines and lie on the paths between two parts of a network.
-In the terminology of the road networks, these are highways, bypasses, main roads/streets, etc.
+<b>betweeness_thresh</b> - Again, only the lines with a betweeness 
+centrality measure at least <b>betweeness_thresh</b> are selected. This 
+value is always positive and is larger for large networks. It denotes to 
+what extent a line is in between the other lines in the network. This 
+value is large for the lines which lie between other lines and lie on 
+the paths between two parts of a network. In the terminology of road 
+networks, these are highways, bypasses, main roads/streets, etc.
 </li>
 </ul>
 
-All three parameters above can be presented at the same time. In that case,
-the algorithm selects only the lines which meet each criterion. 
+All three parameters above can be presented at the same time. In that 
+case, the algorithm selects only the lines which meet each criterion. 
 
 <p>
-Also, the outputed network may not be connected if the value of <b>betweeness_thresh</b>
-is too large.
+Also, the outputed network may not be connected if the value of 
+<b>betweeness_thresh</b> is too large.
 
 <!-- TODO: example(s) -->
 



More information about the grass-commit mailing list