[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