1
1
#include <grass/gis.h>
2
#include <grass/Vect.h>
2
#include <grass/vector.h>
3
3
#include <grass/display.h>
4
#include <grass/raster.h>
5
4
#include <grass/glocale.h>
5
#include "local_proto.h"
8
int label(struct Map_info *Map, int type,
9
struct cat_list *Clist, LATTR * lattr, int chcat)
8
static int process_line(int, const struct line_pnts *,
9
const struct line_cats *, LATTR *,
10
int, const struct cat_list *);
12
int display_label(struct Map_info *Map, int type,
13
struct cat_list *Clist, LATTR *lattr, int chcat)
13
16
struct line_pnts *Points;
14
17
struct line_cats *Cats;
15
int X, Y, T, B, L, R, Xoffset, Yoffset, xarr[5], yarr[5];
20
const struct Format_info *finfo;
19
22
Points = Vect_new_line_struct();
20
23
Cats = Vect_new_cats_struct();
27
ogr_centroids = FALSE;
28
finfo = Vect_get_finfo(Map);
29
if (Vect_maptype(Map) == GV_FORMAT_OGR ||
30
(Vect_maptype(Map) == GV_FORMAT_POSTGIS &&
31
finfo->pg.toposchema_name == NULL)) {
32
if (Vect_level(Map) < 2)
33
G_warning(_("Topology level required for drawing centroids "
35
else if (Vect_get_num_primitives(Map, GV_CENTROID) > 0 &&
37
/* label centroids from topo, don't label boundaries */
25
42
ltype = Vect_read_next_line(Map, Points, Cats);
28
G_fatal_error(_("Can't read vector map"));
33
if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
44
G_fatal_error(_("Unable to read vector map"));
45
else if (ltype == -2) /* EOF */
48
if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
34
49
continue; /* used for both lines and labels */
36
R_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
37
R_text_size(lattr->size, lattr->size);
44
for (i = 0; i < Cats->n_cats; i++) {
45
if (Cats->field[i] == Clist->field &&
46
Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
54
else if (Clist->field > 0) {
57
for (i = 0; i < Cats->n_cats; i++) {
58
if (Cats->field[i] == Clist->field) {
63
/* lines with no category will be displayed */
64
if (Cats->n_cats > 0 && !found)
68
if (Vect_cat_get(Cats, lattr->field, &cat)) {
69
if ((ltype & GV_POINTS) || Points->n_points == 1)
70
/* point/centroid or line/boundary with one coor */
72
X = (int)(D_u_to_d_col(Points->x[0]));
73
Y = (int)(D_u_to_d_row(Points->y[0]));
75
else if (Points->n_points == 2) { /* line with two coors */
76
xl = (Points->x[0] + Points->x[1]) / 2;
77
yl = (Points->y[0] + Points->y[1]) / 2;
78
X = (int)(D_u_to_d_col(xl));
79
Y = (int)(D_u_to_d_row(yl));
82
i = Points->n_points / 2;
83
X = (int)(D_u_to_d_col(Points->x[i]));
84
Y = (int)(D_u_to_d_row(Points->y[i]));
87
X = X + 0.5 * lattr->size;
88
Y = Y + 1.5 * lattr->size;
92
for (i = 0; i < Cats->n_cats; i++) {
93
G_debug(3, "cat lab: field = %d, cat = %d", Cats->field[i],
95
if (Cats->field[i] == lattr->field) { /* all cats of given lfield */
97
sprintf(text, "%s/", text);
99
sprintf(text, "%s%d", text, Cats->cat[i]);
102
R_get_text_box(text, &T, &B, &L, &R);
104
/* Expand border 1/2 of text size */
105
T = T - lattr->size / 2;
106
B = B + lattr->size / 2;
107
L = L - lattr->size / 2;
108
R = R + lattr->size / 2;
112
if (lattr->xref == LCENTER)
113
Xoffset = -(R - L) / 2;
114
if (lattr->xref == LRIGHT)
116
if (lattr->yref == LCENTER)
117
Yoffset = -(B - T) / 2;
118
if (lattr->yref == LBOTTOM)
121
if (lattr->has_bgcolor || lattr->has_bcolor) {
122
xarr[0] = xarr[1] = xarr[4] = L + Xoffset;
123
xarr[2] = xarr[3] = R + Xoffset;
124
yarr[0] = yarr[3] = yarr[4] = B + Yoffset;
125
yarr[1] = yarr[2] = T + Yoffset;
127
if (lattr->has_bgcolor) {
128
R_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
130
R_polygon_abs(xarr, yarr, 5);
133
if (lattr->has_bcolor) {
134
R_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
136
R_polyline_abs(xarr, yarr, 5);
138
R_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
141
R_move_abs(X + Xoffset, Y + Yoffset);
51
if (ogr_centroids && ltype == GV_BOUNDARY)
52
/* do not label boundaries */
55
process_line(ltype, Points, Cats, lattr, chcat, Clist);
59
/* show label for centroids stored in topo (for OGR layers
65
list = Vect_new_boxlist(FALSE); /* bboxes not needed */
66
Vect_get_constraint_box(Map, &box);
67
nlines = Vect_select_lines_by_box(Map, &box, GV_CENTROID, list);
68
G_debug(3, "ncentroids (ogr) = %d", nlines);
70
for (line = 0; line < nlines; line++) {
71
ltype = Vect_read_line(Map, Points, Cats, list->id[line]);
72
process_line(ltype, Points, Cats, lattr, chcat, Clist);
74
Vect_destroy_boxlist(list);
146
77
Vect_destroy_line_struct(Points);
83
int process_line(int ltype, const struct line_pnts *Points,
84
const struct line_cats *Cats, LATTR *lattr,
85
int chcat, const struct cat_list *Clist)
88
char *text = NULL, buf[100];
90
D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
91
D_text_size(lattr->size, lattr->size);
95
D_encoding(lattr->enc);
100
for (i = 0; i < Cats->n_cats; i++) {
101
if (Cats->field[i] == Clist->field &&
102
Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
110
else if (Clist->field > 0) {
113
for (i = 0; i < Cats->n_cats; i++) {
114
if (Cats->field[i] == Clist->field) {
119
/* lines with no category will be displayed */
120
if (Cats->n_cats > 0 && !found)
124
if (Vect_cat_get(Cats, lattr->field, &cat)) {
125
for (i = 0; i < Cats->n_cats; i++) {
126
G_debug(3, "cat lab: field = %d, cat = %d", Cats->field[i],
128
if (Cats->field[i] == lattr->field) { /* all cats of given lfield */
130
sprintf(buf, "%d", Cats->cat[i]);
131
text = G_calloc(strlen(buf), sizeof(char));
136
sprintf(buf, "/%d", Cats->cat[i]);
137
len = strlen(text) + strlen(buf) + 1;
138
text = G_realloc(text, len * sizeof(char));
143
show_label_line(Points, ltype, lattr, text);
152
void show_label(double *px, double *py, LATTR *lattr, const char *text)
154
double X = *px, Y = *py;
155
int Xoffset, Yoffset;
156
double xarr[5], yarr[5];
159
X = X + D_get_d_to_u_xconv() * 0.5 * lattr->size;
160
Y = Y + D_get_d_to_u_yconv() * 1.5 * lattr->size;
163
D_get_text_box(text, &T, &B, &L, &R);
165
/* Expand border 1/2 of text size */
166
T = T - D_get_d_to_u_yconv() * lattr->size / 2;
167
B = B + D_get_d_to_u_yconv() * lattr->size / 2;
168
L = L - D_get_d_to_u_xconv() * lattr->size / 2;
169
R = R + D_get_d_to_u_xconv() * lattr->size / 2;
173
if (lattr->xref == LCENTER)
174
Xoffset = -(R - L) / 2;
175
if (lattr->xref == LRIGHT)
177
if (lattr->yref == LCENTER)
178
Yoffset = -(B - T) / 2;
179
if (lattr->yref == LBOTTOM)
182
if (lattr->has_bgcolor || lattr->has_bcolor) {
183
xarr[0] = xarr[1] = xarr[4] = L + Xoffset;
184
xarr[2] = xarr[3] = R + Xoffset;
185
yarr[0] = yarr[3] = yarr[4] = B + Yoffset;
186
yarr[1] = yarr[2] = T + Yoffset;
188
if (lattr->has_bgcolor) {
189
D_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
191
D_polygon_abs(xarr, yarr, 5);
194
if (lattr->has_bcolor) {
195
D_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
197
D_polyline_abs(xarr, yarr, 5);
199
D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
202
D_pos_abs(X + Xoffset, Y + Yoffset);
206
void show_label_line(const struct line_pnts *Points, int ltype, LATTR *lattr,
211
if ((ltype & GV_POINTS) || Points->n_points == 1)
212
/* point/centroid or line/boundary with one coor */
217
else if (Points->n_points == 2) { /* line with two coors */
218
X = (Points->x[0] + Points->x[1]) / 2;
219
Y = (Points->y[0] + Points->y[1]) / 2;
222
int i = Points->n_points / 2;
227
show_label(&X, &Y, lattr, text);