[GRASS-SVN] r33929 - grass/branches/develbranch_6/vector/v.label.sa

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Oct 19 10:37:15 EDT 2008


Author: wolf
Date: 2008-10-19 10:37:15 -0400 (Sun, 19 Oct 2008)
New Revision: 33929

Modified:
   grass/branches/develbranch_6/vector/v.label.sa/font.c
   grass/branches/develbranch_6/vector/v.label.sa/labels.c
   grass/branches/develbranch_6/vector/v.label.sa/labels.h
   grass/branches/develbranch_6/vector/v.label.sa/main.c
Log:
Added support for the overlap= parameter to hide overlapping labels

Modified: grass/branches/develbranch_6/vector/v.label.sa/font.c
===================================================================
--- grass/branches/develbranch_6/vector/v.label.sa/font.c	2008-10-18 21:24:51 UTC (rev 33928)
+++ grass/branches/develbranch_6/vector/v.label.sa/font.c	2008-10-19 14:37:15 UTC (rev 33929)
@@ -51,7 +51,8 @@
     fp = NULL;
     if ((capfile = getenv("GRASS_FONT_CAP"))) {
 	if ((fp = fopen(capfile, "r")) == NULL)
-	    G_warning(_("%s: Unable to read font definition file; use the default"),
+	    G_warning(_
+		      ("%s: Unable to read font definition file; use the default"),
 		      capfile);
     }
     if (fp == NULL) {

Modified: grass/branches/develbranch_6/vector/v.label.sa/labels.c
===================================================================
--- grass/branches/develbranch_6/vector/v.label.sa/labels.c	2008-10-18 21:24:51 UTC (rev 33928)
+++ grass/branches/develbranch_6/vector/v.label.sa/labels.c	2008-10-19 14:37:15 UTC (rev 33929)
@@ -83,8 +83,9 @@
 	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 		      fi->database, fi->driver);
 
-    sql_len = strlen(p->column->answer) + strlen(fi->table) +
-	strlen(fi->key) + 30;
+    sql_len =
+	strlen(p->column->answer) + strlen(p->overlap->answer) +
+	strlen(fi->table) + strlen(fi->key) + 31;
 
     /* initialize FT 2 library */
     if (FT_Init_FreeType(&library))
@@ -107,7 +108,7 @@
     buffer = atof(p->isize->answer);
 
     /* use 1 point = 1 map unit */
-    if (FT_Set_Char_Size(face, (int)((font_size * 0.95) * 64.0), 0, 100, 100))
+    if (FT_Set_Char_Size(face, (int)((font_size) * 64.0), 0, 100, 100))
 	G_fatal_error(_("Unable to set font size"));
 
     /* start reading the map */
@@ -154,8 +155,15 @@
 
 	sql = G_malloc(sql_len);
 	/* Read label from database */
-	sprintf(sql, "select %s from %s where %s = %d", p->column->answer,
-		fi->table, fi->key, cat);
+	if (p->overlap->answer[0] != '\0') {
+	    sprintf(sql, "select %s,%s from %s where %s = %d",
+		    p->column->answer, p->overlap->answer,
+		    fi->table, fi->key, cat);
+	}
+	else {
+	    sprintf(sql, "select %s from %s where %s = %d", p->column->answer,
+		    fi->table, fi->key, cat);
+	}
 	G_debug(3, "SQL: %s", sql);
 	db_init_string(&query);
 	db_set_string(&query, sql);
@@ -177,11 +185,8 @@
 
 	table = db_get_cursor_table(&cursor);
 	column = db_get_table_column(table, 0);	/* first column */
-
 	db_init_string(&value);
 	db_convert_column_value_to_string(column, &value);
-	db_close_cursor(&cursor);
-
 	G_debug(3, "Label: %s", db_get_string(&value));
 
 	/* ignore empty strings */
@@ -195,6 +200,34 @@
 	G_debug(3, "Label [%d]: %s, cat=%d, type=0x%02x", i, labels[i].text,
 		labels[i].cat, labels[i].type);
 
+	if (p->overlap->answer[0] != '\0') {
+	    int ctype;
+	    double dbl;
+
+	    column = db_get_table_column(table, 1);
+	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
+	    if (ctype == DB_C_TYPE_INT) {
+		dbValue *val;
+
+		val = db_get_column_value(column);
+		dbl = (double)db_get_value_int(val);
+	    }
+	    else if (ctype == DB_C_TYPE_DOUBLE) {
+		dbValue *val;
+
+		val = db_get_column_value(column);
+		dbl = db_get_value_double(val);
+	    }
+	    else {
+		db_close_cursor(&cursor);
+		G_fatal_error(_("Cannot load overlap weights. "
+				"Column %s is not of numeric type in "
+				"table <%s>"), p->overlap->answer, fi->table);
+	    }
+	    labels[i].weight = dbl;
+	}
+	db_close_cursor(&cursor);
+
 	/* make a skyline for the text */
 	label_skyline(face, p->charset->answer, &labels[i]);
 
@@ -344,16 +377,17 @@
 	G_percent(i, n_labels - 1, 1);
 	switch (labels[i].type) {
 	case GV_POINT:
-	    G_debug(3, "Line (%d): %s", i, labels[i].text);
+	    G_debug(3, "Point (%d): %s", i, labels[i].text);
 	    label_point_candidates(&labels[i]);
 	    break;
 	case GV_LINE:
 	    G_debug(3, "Line (%d): %s", i, labels[i].text);
 	    label_line_candidates(&labels[i]);
 	    break;
-	    /*                case GV_AREA:
-	     * label_area_candidates(labels[i]);
-	     * break; */
+	case GV_CENTROID:
+	    G_debug(3, "Area (%d): %s", i, labels[i].text);
+	    label_point_candidates(&labels[i]);
+	    break;
 	default:
 	    /* this should never be reached */
 	    break;

Modified: grass/branches/develbranch_6/vector/v.label.sa/labels.h
===================================================================
--- grass/branches/develbranch_6/vector/v.label.sa/labels.h	2008-10-18 21:24:51 UTC (rev 33928)
+++ grass/branches/develbranch_6/vector/v.label.sa/labels.h	2008-10-19 14:37:15 UTC (rev 33929)
@@ -44,28 +44,32 @@
 struct _label
 {
 
-    struct line_pnts *skyline;	/**< The skyline of the text, as an offest
-				  *  from the label point */
+    struct line_pnts *skyline;	    /**< The skyline of the text, as an offest
+	                                  *  from the label point */
     BOUND_BOX bb;
     double size;
 
-    double current_score;	  /**< The current score of the label. */
+    double current_score;	    /**< The current score of the label. */
 
     label_candidate_t *candidates;  /**< A list of candidate positions */
 
-    int n_candidates;		 /**< The size of the candidates array */
+    int n_candidates;		    /**< The size of the candidates array */
 
-    int current_candidate;	 /**< An index into the candidates array
-				   *  describing the currently selected candidate */
+    int current_candidate;	    /**< An index into the candidates array
+	                                  *  describing the currently selected candidate */
 
-    char *text;			 /**< The label text */
+    char *text;			    /**< The label text */
 
-    int cat;			     /**< the cat of the feature */
+    int cat;			    /**< the cat of the feature */
 
-    int type;			     /**< The feture type (point, line, area) */
+    int type;			    /**< The feature type (point, line, area) */
 
-    struct line_pnts *shape;	     /**< The points for the feature that this
-				       *  label belongs to */
+    struct line_pnts *shape;	    /**< The points for the feature that this
+	                                  *  label belongs to */
+
+    char hide;			    /**< If this is 1, the label will not be created */
+
+    double weight;		    /**< The label weight if user requested to ide overlaps */
 };
 
 /**
@@ -74,19 +78,19 @@
 struct _label_candidate
 {
 
-    label_point_t point;     /**< The point of the label position 
-			       *  (lower left corner)*/
+    label_point_t point;	    /**< The point of the label position
+	                                  *  (lower left corner)*/
 
-    double score; /**< The base score of this position (sans overlap metric) */
+    double score;		    /**< The base score of this position (sans overlap metric) */
     double lineover;
 
-    double rotation;	 /**< The mount the label is rotated in this position */
+    double rotation;		    /**< The mount the label is rotated in this position */
 
-    label_intersection_t *intersections;  /**< A list of all label candidate 
-                                            *  positions which intersect with
-                                            *  this position. */
+    label_intersection_t *intersections;  /**< A list of all label candidate
+	                                        *  positions which intersect with
+	                                        *  this position. */
 
-    int n_intersections; /**< Number of items in the intersections array */
+    int n_intersections;	    /**< Number of items in the intersections array */
     struct line_pnts *baseline;
     struct line_pnts *swathline;
     int above;
@@ -124,6 +128,7 @@
     struct Option *opaque;
     struct Option *bocolor;
     struct Option *bowidth;
+    struct Option *overlap;
 
     /*    struct Option */
     /*      struct Option *where; *//* later */

Modified: grass/branches/develbranch_6/vector/v.label.sa/main.c
===================================================================
--- grass/branches/develbranch_6/vector/v.label.sa/main.c	2008-10-18 21:24:51 UTC (rev 33928)
+++ grass/branches/develbranch_6/vector/v.label.sa/main.c	2008-10-19 14:37:15 UTC (rev 33929)
@@ -24,10 +24,19 @@
  * @param argc Count of command line arguments
  * @param argv The command line arguments.
  * @param p The parameters structure.
+ * @return On error this function will exit.
  */
 static void parse_args(int argc, char *argv[], struct params *p);
 
 /**
+ * This function hides overlapping labels so that only the label with the
+ * largest weight will be shown.
+ * @param labels The labels array
+ * @param n_labels The size of the labels array
+ */
+static void hide_overlapping_lables(label_t * labels, int n_labels);
+
+/**
  * The main function controls the program flow.
  */
 int main(int argc, char *argv[])
@@ -58,57 +67,22 @@
     label_candidate_overlap(labels, n_labels);
     /*   3. position selection */
     simulate_annealing(labels, n_labels, &p);
+    /*   4. If overlap= option is given then go through final positioning
+     *   and remove remove overlaping labels */
+    if (p.overlap->answer[0] != '\0') {
+	hide_overlapping_lables(labels, n_labels);
+    }
     /* write lables to file */
     fprintf(stderr, "Writing labels to file: ...");
     labelf = G_fopen_new("paint/labels", p.labels->answer);
     for (i = 0; i < n_labels; i++) {
-	if (labels[i].n_candidates > 0) {
+	if ((labels[i].n_candidates > 0) && (!labels[i].hide)) {
 	    print_label(labelf, &labels[i], &p);
 	}
 	G_percent(i, (n_labels - 1), 1);
     }
     fclose(labelf);
 
-    /* dumping the skyline of the labels */
-    /*    {
-       int n=1;
-       char *f;
-       FILE *skyf;
-       f = G_tempfile();
-       skyf = fopen(f, "w");
-       printf("Writing label skylines & label points to file %s", f);
-       fprintf(skyf, "VERTI:\n");
-       printf("\n%d labels:\n", n_labels);
-       for (i = 0; i < n_labels; i++) {
-       printf("%s has %d candidates\n", labels[i].text, labels[i].n_candidates);
-       if (labels[i].n_candidates > 0) {
-       int j;
-       label_t *l = &labels[i];
-       j = l->current_candidate;
-       //           for(j=0; j < l->n_candidates; j++) {
-       {
-       int k;
-       label_candidate_t *cc = &l->candidates[j];
-       struct line_pnts *sky = skyline_trans_rot(l->skyline,
-       &cc->point,
-       cc->rotation);
-       fprintf(skyf, "L %d 1\n", sky->n_points);
-       for(k=0;k < sky->n_points; k++) {
-       fprintf(skyf, " %.12f %.12f\n", sky->x[k], sky->y[k]);
-       }
-       fprintf(skyf, " %-5d %-10d\n", 1, 1000+n);
-       // The label point
-       fprintf(skyf, "P 1 1\n");
-       fprintf(skyf, " %.12f %.12f\n", cc->point.x, cc->point.y);
-       fprintf(skyf, " %-5d %-10d\n", 1, 2000+n);
-       n++;
-       }
-       }
-       }
-       free(f);
-       fclose(skyf);
-       } */
-
     return EXIT_SUCCESS;
 }
 
@@ -122,8 +96,7 @@
 
     p->layer = G_define_standard_option(G_OPT_V_FIELD);
 
-    p->column = G_define_option();
-    p->column->key = "column";
+    p->column = G_define_standard_option(G_OPT_COLUMN);
     p->column->type = TYPE_STRING;
     p->column->required = YES;
     p->column->description =
@@ -143,7 +116,7 @@
     p->font->description =
 	_("Name of TrueType font (as listed in the fontcap)");
     p->font->guisection = _("Font");
-    p->font->gisprompt = "font";
+    p->font->gisprompt = _("Font");
 
     p->size = G_define_option();
     p->size->key = "size";
@@ -229,6 +202,13 @@
     p->bowidth->answer = "0";
     p->bowidth->guisection = _("Colors");
 
+    p->overlap = G_define_standard_option(G_OPT_COLUMN);
+    p->overlap->key = "overlap";
+    p->overlap->description = _("Numeric column to give precedence in case of"
+				" overlapping labels. The label with a smaller"
+				" weight is hidden.");
+    p->overlap->answer = "";
+
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 }
@@ -246,7 +226,7 @@
     fprintf(labelf, "north: %lf\n", label->candidates[cc].point.y);
     fprintf(labelf, "xoffset: %lf\n", 0.0);	/*  * (size)); */
     fprintf(labelf, "yoffset: %lf\n", 0.0);	/*  * (size)); */
-    fprintf(labelf, "ref: %s\n", "bottom left");
+    fprintf(labelf, "ref: %s\n", "none none");
 
     fprintf(labelf, "font: %s\n", p->font->answer);
     fprintf(labelf, "color: %s\n", p->color->answer);
@@ -265,3 +245,34 @@
 
     return;
 }
+
+void hide_overlapping_lables(label_t * labels, int n_labels)
+{
+    int i;
+
+    fprintf(stderr, "Culling overlapping labels: ...");
+    for (i = 0; i < n_labels; i++) {
+	int j;
+	int cc = labels[i].current_candidate;
+
+	/* do not bother with already hidden labels */
+	if (labels[i].hide) {
+	    G_percent(i, (n_labels - 1), 1);
+	    continue;
+	}
+	for (j = 0; j < labels[i].candidates[cc].n_intersections; j++) {
+	    label_intersection_t *isect =
+		&labels[i].candidates[cc].intersections[j];
+	    if (isect->candidate == isect->label->current_candidate) {
+		/* hide the one with a lower weight */
+		if (labels[i].weight >= isect->label->weight) {
+		    isect->label->hide = 1;
+		}
+		else {
+		    labels[i].hide = 1;
+		}
+	    }
+	}
+	G_percent(i, (n_labels - 1), 1);
+    }
+}



More information about the grass-commit mailing list