label.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <grass/gis.h>
  2. #include <grass/vector.h>
  3. #include <grass/display.h>
  4. #include <grass/glocale.h>
  5. #include "local_proto.h"
  6. #include "plot.h"
  7. int display_label(struct Map_info *Map, int type,
  8. struct cat_list *Clist, LATTR *lattr, int chcat)
  9. {
  10. int i, ltype;
  11. struct line_pnts *Points;
  12. struct line_cats *Cats;
  13. int cat;
  14. char text[100];
  15. Points = Vect_new_line_struct();
  16. Cats = Vect_new_cats_struct();
  17. Vect_rewind(Map);
  18. while (1) {
  19. ltype = Vect_read_next_line(Map, Points, Cats);
  20. switch (ltype) {
  21. case -1:
  22. G_fatal_error(_("Unable to read vector map"));
  23. case -2: /* EOF */
  24. return 0;
  25. }
  26. if (!(type & ltype))
  27. continue; /* used for both lines and labels */
  28. D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
  29. D_text_size(lattr->size, lattr->size);
  30. if (lattr->font)
  31. D_font(lattr->font);
  32. if (lattr->enc)
  33. D_encoding(lattr->enc);
  34. if (chcat) {
  35. int found = 0;
  36. for (i = 0; i < Cats->n_cats; i++) {
  37. if (Cats->field[i] == Clist->field &&
  38. Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
  39. found = 1;
  40. break;
  41. }
  42. }
  43. if (!found)
  44. continue;
  45. }
  46. else if (Clist->field > 0) {
  47. int found = 0;
  48. for (i = 0; i < Cats->n_cats; i++) {
  49. if (Cats->field[i] == Clist->field) {
  50. found = 1;
  51. break;
  52. }
  53. }
  54. /* lines with no category will be displayed */
  55. if (Cats->n_cats > 0 && !found)
  56. continue;
  57. }
  58. if (Vect_cat_get(Cats, lattr->field, &cat)) {
  59. text[0] = '\0';
  60. for (i = 0; i < Cats->n_cats; i++) {
  61. G_debug(3, "cat lab: field = %d, cat = %d", Cats->field[i],
  62. Cats->cat[i]);
  63. if (Cats->field[i] == lattr->field) { /* all cats of given lfield */
  64. if (*text != '\0')
  65. sprintf(text, "%s/", text);
  66. sprintf(text, "%s%d", text, Cats->cat[i]);
  67. }
  68. }
  69. show_label_line(Points, ltype, lattr, text);
  70. }
  71. }
  72. Vect_destroy_line_struct(Points);
  73. Vect_destroy_cats_struct(Cats);
  74. return 0;
  75. }
  76. void show_label(double *px, double *py, LATTR *lattr, const char *text)
  77. {
  78. double X = *px, Y = *py;
  79. int Xoffset, Yoffset;
  80. double xarr[5], yarr[5];
  81. double T, B, L, R;
  82. X = X + D_get_d_to_u_xconv() * 0.5 * lattr->size;
  83. Y = Y + D_get_d_to_u_yconv() * 1.5 * lattr->size;
  84. D_pos_abs(X, Y);
  85. D_get_text_box(text, &T, &B, &L, &R);
  86. /* Expand border 1/2 of text size */
  87. T = T - D_get_d_to_u_yconv() * lattr->size / 2;
  88. B = B + D_get_d_to_u_yconv() * lattr->size / 2;
  89. L = L - D_get_d_to_u_xconv() * lattr->size / 2;
  90. R = R + D_get_d_to_u_xconv() * lattr->size / 2;
  91. Xoffset = 0;
  92. Yoffset = 0;
  93. if (lattr->xref == LCENTER)
  94. Xoffset = -(R - L) / 2;
  95. if (lattr->xref == LRIGHT)
  96. Xoffset = -(R - L);
  97. if (lattr->yref == LCENTER)
  98. Yoffset = -(B - T) / 2;
  99. if (lattr->yref == LBOTTOM)
  100. Yoffset = -(B - T);
  101. if (lattr->has_bgcolor || lattr->has_bcolor) {
  102. xarr[0] = xarr[1] = xarr[4] = L + Xoffset;
  103. xarr[2] = xarr[3] = R + Xoffset;
  104. yarr[0] = yarr[3] = yarr[4] = B + Yoffset;
  105. yarr[1] = yarr[2] = T + Yoffset;
  106. if (lattr->has_bgcolor) {
  107. D_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
  108. lattr->bgcolor.B);
  109. D_polygon_abs(xarr, yarr, 5);
  110. }
  111. if (lattr->has_bcolor) {
  112. D_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
  113. lattr->bcolor.B);
  114. D_polyline_abs(xarr, yarr, 5);
  115. }
  116. D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
  117. }
  118. D_pos_abs(X + Xoffset, Y + Yoffset);
  119. D_text(text);
  120. }
  121. void show_label_line(const struct line_pnts *Points, int ltype, LATTR *lattr, const char *text)
  122. {
  123. double X, Y;
  124. if ((ltype & GV_POINTS) || Points->n_points == 1)
  125. /* point/centroid or line/boundary with one coor */
  126. {
  127. X = Points->x[0];
  128. Y = Points->y[0];
  129. }
  130. else if (Points->n_points == 2) { /* line with two coors */
  131. X = (Points->x[0] + Points->x[1]) / 2;
  132. Y = (Points->y[0] + Points->y[1]) / 2;
  133. }
  134. else {
  135. int i = Points->n_points / 2;
  136. X = Points->x[i];
  137. Y = Points->y[i];
  138. }
  139. show_label(&X, &Y, lattr, text);
  140. }