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

« back to all changes in this revision

Viewing changes to imagery/i.class/outline.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
 
#define OUTLINE
2
 
 
3
 
#include <stdlib.h>
4
 
#include <grass/gis.h>
5
 
#include <grass/glocale.h>
6
 
#include "globals.h"
7
 
#include "local_proto.h"
8
 
 
9
 
 
10
 
#define V     Region.vertex     /* converted vertex list */
11
 
#define VN    Region.vertex_npoints
12
 
 
13
 
#define P     Region.perimeter  /* perimeter point list */
14
 
#define PN    Region.perimeter_npoints
15
 
 
16
 
#define A     Region.point
17
 
#define AN    Region.npoints
18
 
 
19
 
#define extrema(x,y,z) (((x<y)&&(z<y))||((x>y)&&(z>y)))
20
 
#define non_extrema(x,y,z) (((x<y)&&(y<z))||((x>y)&&(y>z)))
21
 
 
22
 
int outline(void)
23
 
{
24
 
    int first;
25
 
    int skip;                   /* boolean */
26
 
    int np;                     /* perimeter estimate */
27
 
    POINT tmp[MAX_VERTEX];      /* temp vertex list   */
28
 
    int cur;
29
 
    int prev;
30
 
    int next;
31
 
    double tmp_n, tmp_e;
32
 
    POINT temp;
33
 
 
34
 
 
35
 
    /* convert alarm area points to data row/col verticies */
36
 
    Menu_msg("Preparing outline...");
37
 
 
38
 
    for (cur = 0; cur < AN; cur++) {
39
 
        temp.y = view_to_row(Region.view, A[cur].y);
40
 
        temp.x = view_to_col(Region.view, A[cur].x);
41
 
        tmp_n = row_to_northing(&(Region.view->cell.head), temp.y, 0.5);
42
 
        tmp_e = col_to_easting(&(Region.view->cell.head), temp.x, 0.5);
43
 
        tmp[cur].y = G_northing_to_row(tmp_n, &Band_cellhd);
44
 
        tmp[cur].x = G_easting_to_col(tmp_e, &Band_cellhd);
45
 
    }
46
 
 
47
 
    /* find first edge which is not horizontal */
48
 
 
49
 
    first = -1;
50
 
    prev = AN - 1;
51
 
    for (cur = 0; cur < AN; prev = cur++)
52
 
        if (tmp[cur].y != tmp[prev].y) {
53
 
            first = cur;
54
 
            break;
55
 
        }
56
 
    if (first < 0) {
57
 
        G_warning(_("Absurd polygon."));
58
 
        return (0);
59
 
    }
60
 
 
61
 
    /* copy tmp to vertex list collapsing adjacent horizontal edges */
62
 
 
63
 
    skip = 0;
64
 
    VN = 0;
65
 
    cur = first;                /* stmt not necssary */
66
 
 
67
 
    do {
68
 
        if (signalflag.interrupt)
69
 
            return (0);
70
 
        if (!skip) {
71
 
            V[VN].x = tmp[cur].x;
72
 
            V[VN].y = tmp[cur].y;
73
 
            VN++;
74
 
        }
75
 
 
76
 
        prev = cur++;
77
 
        if (cur >= AN)
78
 
            cur = 0;
79
 
        if ((next = cur + 1) >= AN)
80
 
            next = 0;
81
 
 
82
 
        skip = ((tmp[prev].y == tmp[cur].y) && (tmp[next].y == tmp[cur].y));
83
 
    }
84
 
    while (cur != first);
85
 
 
86
 
 
87
 
    /* count points on the perimeter */
88
 
 
89
 
    np = 0;
90
 
    prev = VN - 1;
91
 
    for (cur = 0; cur < VN; prev = cur++)
92
 
        np += abs(V[prev].y - V[cur].y);
93
 
 
94
 
 
95
 
    /* allocate perimeter list */
96
 
 
97
 
    P = (POINT *) G_malloc(np * sizeof(POINT));
98
 
    if (!P) {
99
 
        G_warning(_("Outlined area is too large."));
100
 
        return (0);
101
 
    }
102
 
 
103
 
    /* store the perimeter points */
104
 
 
105
 
    PN = 0;
106
 
    prev = VN - 1;
107
 
    for (cur = 0; cur < VN; prev = cur++) {
108
 
        if (signalflag.interrupt)
109
 
            return (0);
110
 
        edge(V[prev].x, V[prev].y, V[cur].x, V[cur].y);
111
 
    }
112
 
 
113
 
    /*
114
 
     * now decide which verticies should be included
115
 
     *    local extrema are excluded
116
 
     *    local non-extrema are included
117
 
     *    verticies of horizontal edges which are pseudo-extrema
118
 
     *      are excluded.
119
 
     *    one vertex of horizontal edges which are pseudo-non-extrema
120
 
     *      are included.
121
 
     */
122
 
 
123
 
 
124
 
    prev = VN - 1;
125
 
    cur = 0;
126
 
    do {
127
 
        if (signalflag.interrupt)
128
 
            return (0);
129
 
        next = cur + 1;
130
 
        if (next >= VN)
131
 
            next = 0;
132
 
 
133
 
        if (extrema(V[prev].y, V[cur].y, V[next].y))
134
 
            skip = 1;
135
 
        else if (non_extrema(V[prev].y, V[cur].y, V[next].y))
136
 
            skip = 0;
137
 
        else {
138
 
            skip = 0;
139
 
            if (++next >= VN)
140
 
                next = 0;
141
 
            if (extrema(V[prev].y, V[cur].y, V[next].y))
142
 
                skip = 1;
143
 
        }
144
 
 
145
 
        if (!skip)
146
 
            edge_point(V[cur].x, V[cur].y);
147
 
 
148
 
        cur = next;
149
 
        prev = cur - 1;
150
 
    }
151
 
    while (cur != 0);
152
 
 
153
 
 
154
 
    /* sort the edge points by row and then by col */
155
 
 
156
 
    Menu_msg("Sorting...");
157
 
    qsort(P, (size_t) PN, sizeof(POINT), edge_order);
158
 
 
159
 
    Menu_msg("");
160
 
    return (1);
161
 
}