~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to display/d.vect/label.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
6
6
#include "plot.h"
7
7
 
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 *);
 
11
 
 
12
int display_label(struct Map_info *Map, int type,
 
13
                  struct cat_list *Clist, LATTR *lattr, int chcat)
10
14
{
11
 
    int i, ltype;
12
 
    double xl, yl;
 
15
    int ltype;
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];
16
 
    int cat;
17
 
    char text[100];
 
18
    int ogr_centroids;
18
19
 
 
20
    const struct Format_info *finfo;
 
21
    
19
22
    Points = Vect_new_line_struct();
20
23
    Cats = Vect_new_cats_struct();
21
24
 
22
25
    Vect_rewind(Map);
23
26
 
24
 
    while (1) {
 
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 "
 
34
                        "for OGR layers"));
 
35
        else if (Vect_get_num_primitives(Map, GV_CENTROID) > 0 &&
 
36
                 type & GV_CENTROID)
 
37
            /* label centroids from topo, don't label boundaries */
 
38
            ogr_centroids = TRUE;
 
39
    }
 
40
    
 
41
    while (TRUE) {
25
42
        ltype = Vect_read_next_line(Map, Points, Cats);
26
 
        switch (ltype) {
27
 
        case -1:
28
 
            G_fatal_error(_("Can't read vector map"));
29
 
        case -2:                /* EOF */
30
 
            return 0;
31
 
        }
32
 
 
33
 
        if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
 
43
        if (ltype == -1)
 
44
            G_fatal_error(_("Unable to read vector map"));
 
45
        else if (ltype == -2) /* EOF */
 
46
            break;
 
47
        
 
48
        if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
34
49
            continue;           /* used for both lines and labels */
35
 
 
36
 
        R_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
37
 
        R_text_size(lattr->size, lattr->size);
38
 
        if (lattr->font)
39
 
            R_font(lattr->font);
40
 
 
41
 
        if (chcat) {
42
 
            int found = 0;
43
 
 
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)) {
47
 
                    found = 1;
48
 
                    break;
49
 
                }
50
 
            }
51
 
            if (!found)
52
 
                continue;
53
 
        }
54
 
        else if (Clist->field > 0) {
55
 
            int found = 0;
56
 
 
57
 
            for (i = 0; i < Cats->n_cats; i++) {
58
 
                if (Cats->field[i] == Clist->field) {
59
 
                    found = 1;
60
 
                    break;
61
 
                }
62
 
            }
63
 
            /* lines with no category will be displayed */
64
 
            if (Cats->n_cats > 0 && !found)
65
 
                continue;
66
 
        }
67
 
 
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 */
71
 
            {
72
 
                X = (int)(D_u_to_d_col(Points->x[0]));
73
 
                Y = (int)(D_u_to_d_row(Points->y[0]));
74
 
            }
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));
80
 
            }
81
 
            else {
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]));
85
 
            }
86
 
 
87
 
            X = X + 0.5 * lattr->size;
88
 
            Y = Y + 1.5 * lattr->size;
89
 
 
90
 
            R_move_abs(X, Y);
91
 
            text[0] = '\0';
92
 
            for (i = 0; i < Cats->n_cats; i++) {
93
 
                G_debug(3, "cat lab: field = %d, cat = %d", Cats->field[i],
94
 
                        Cats->cat[i]);
95
 
                if (Cats->field[i] == lattr->field) {   /* all cats of given lfield */
96
 
                    if (*text != '\0')
97
 
                        sprintf(text, "%s/", text);
98
 
 
99
 
                    sprintf(text, "%s%d", text, Cats->cat[i]);
100
 
                }
101
 
            }
102
 
            R_get_text_box(text, &T, &B, &L, &R);
103
 
 
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;
109
 
 
110
 
            Xoffset = 0;
111
 
            Yoffset = 0;
112
 
            if (lattr->xref == LCENTER)
113
 
                Xoffset = -(R - L) / 2;
114
 
            if (lattr->xref == LRIGHT)
115
 
                Xoffset = -(R - L);
116
 
            if (lattr->yref == LCENTER)
117
 
                Yoffset = -(B - T) / 2;
118
 
            if (lattr->yref == LBOTTOM)
119
 
                Yoffset = -(B - T);
120
 
 
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;
126
 
 
127
 
                if (lattr->has_bgcolor) {
128
 
                    R_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
129
 
                                lattr->bgcolor.B);
130
 
                    R_polygon_abs(xarr, yarr, 5);
131
 
                }
132
 
 
133
 
                if (lattr->has_bcolor) {
134
 
                    R_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
135
 
                                lattr->bcolor.B);
136
 
                    R_polyline_abs(xarr, yarr, 5);
137
 
                }
138
 
                R_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
139
 
            }
140
 
 
141
 
            R_move_abs(X + Xoffset, Y + Yoffset);
142
 
            R_text(text);
143
 
        }
 
50
        
 
51
        if (ogr_centroids && ltype == GV_BOUNDARY)
 
52
            /* do not label boundaries */
 
53
            continue;
 
54
 
 
55
        process_line(ltype, Points, Cats, lattr, chcat, Clist);
 
56
    }
 
57
 
 
58
    if (ogr_centroids) {
 
59
        /* show label for centroids stored in topo (for OGR layers
 
60
           only) */
 
61
        int line, nlines;
 
62
        struct bound_box box;
 
63
        struct boxlist *list;
 
64
        
 
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);
 
69
        
 
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);
 
73
        }
 
74
        Vect_destroy_boxlist(list);
144
75
    }
145
76
 
146
77
    Vect_destroy_line_struct(Points);
148
79
 
149
80
    return 0;
150
81
}
 
82
 
 
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)
 
86
{
 
87
    int i, cat, len;
 
88
    char *text = NULL, buf[100];
 
89
    
 
90
    D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
 
91
    D_text_size(lattr->size, lattr->size);
 
92
    if (lattr->font)
 
93
        D_font(lattr->font);
 
94
    if (lattr->enc)
 
95
        D_encoding(lattr->enc);
 
96
    
 
97
    if (chcat) {
 
98
        int found = 0;
 
99
        
 
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)) {
 
103
                found = 1;
 
104
                break;
 
105
            }
 
106
        }
 
107
        if (!found)
 
108
            return 0;
 
109
    }
 
110
    else if (Clist->field > 0) {
 
111
        int found = 0;
 
112
        
 
113
        for (i = 0; i < Cats->n_cats; i++) {
 
114
            if (Cats->field[i] == Clist->field) {
 
115
                found = 1;
 
116
                break;
 
117
            }
 
118
        }
 
119
        /* lines with no category will be displayed */
 
120
        if (Cats->n_cats > 0 && !found)
 
121
            return 0;
 
122
    }
 
123
    
 
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],
 
127
                    Cats->cat[i]);
 
128
            if (Cats->field[i] == lattr->field) {       /* all cats of given lfield */
 
129
                if (!text) {
 
130
                    sprintf(buf, "%d", Cats->cat[i]);
 
131
                    text = G_calloc(strlen(buf), sizeof(char));
 
132
                    text[0] = '\0';
 
133
                    strcpy(text, buf);
 
134
                }
 
135
                else {
 
136
                    sprintf(buf, "/%d", Cats->cat[i]);
 
137
                    len = strlen(text) + strlen(buf) + 1;
 
138
                    text = G_realloc(text, len * sizeof(char));
 
139
                    strcat(text, buf);
 
140
                }
 
141
            }
 
142
        }
 
143
        show_label_line(Points, ltype, lattr, text);
 
144
    }
 
145
    
 
146
    if (text)
 
147
        G_free(text);
 
148
 
 
149
    return 1;
 
150
}
 
151
 
 
152
void show_label(double *px, double *py, LATTR *lattr, const char *text)
 
153
{
 
154
    double X = *px, Y = *py;
 
155
    int Xoffset, Yoffset;
 
156
    double xarr[5], yarr[5];
 
157
    double T, B, L, R;
 
158
 
 
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;
 
161
 
 
162
    D_pos_abs(X, Y);
 
163
    D_get_text_box(text, &T, &B, &L, &R);
 
164
 
 
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;
 
170
 
 
171
    Xoffset = 0;
 
172
    Yoffset = 0;
 
173
    if (lattr->xref == LCENTER)
 
174
        Xoffset = -(R - L) / 2;
 
175
    if (lattr->xref == LRIGHT)
 
176
        Xoffset = -(R - L);
 
177
    if (lattr->yref == LCENTER)
 
178
        Yoffset = -(B - T) / 2;
 
179
    if (lattr->yref == LBOTTOM)
 
180
        Yoffset = -(B - T);
 
181
 
 
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;
 
187
 
 
188
        if (lattr->has_bgcolor) {
 
189
            D_RGB_color(lattr->bgcolor.R, lattr->bgcolor.G,
 
190
                        lattr->bgcolor.B);
 
191
            D_polygon_abs(xarr, yarr, 5);
 
192
        }
 
193
 
 
194
        if (lattr->has_bcolor) {
 
195
            D_RGB_color(lattr->bcolor.R, lattr->bcolor.G,
 
196
                        lattr->bcolor.B);
 
197
            D_polyline_abs(xarr, yarr, 5);
 
198
        }
 
199
        D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
 
200
    }
 
201
 
 
202
    D_pos_abs(X + Xoffset, Y + Yoffset);
 
203
    D_text(text);
 
204
}
 
205
 
 
206
void show_label_line(const struct line_pnts *Points, int ltype, LATTR *lattr,
 
207
                     const char *text)
 
208
{
 
209
    double X, Y;
 
210
 
 
211
    if ((ltype & GV_POINTS) || Points->n_points == 1)
 
212
        /* point/centroid or line/boundary with one coor */
 
213
    {
 
214
        X = Points->x[0];
 
215
        Y = Points->y[0];
 
216
    }
 
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;
 
220
    }
 
221
    else {
 
222
        int i = Points->n_points / 2;
 
223
        X = Points->x[i];
 
224
        Y = Points->y[i];
 
225
    }
 
226
 
 
227
    show_label(&X, &Y, lattr, text);
 
228
}