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

« back to all changes in this revision

Viewing changes to lib/vector/Vlib/build_nat.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
/*!
2
 
   \file build_nat.c
 
2
   \file lib/vector/Vlib/build_nat.c
3
3
 
4
4
   \brief Vector library - Building topology for native format
5
5
 
6
 
   (C) 2001-2008 by the GRASS Development Team
 
6
   (C) 2001-2013 by the GRASS Development Team
7
7
 
8
 
   This program is free software under the 
9
 
   GNU General Public License (>=v2). 
10
 
   Read the file COPYING that comes with GRASS
11
 
   for details.
 
8
   This program is free software under the GNU General Public License
 
9
   (>=v2). Read the file COPYING that comes with GRASS for details.
12
10
 
13
11
   \author Original author CERL, probably Dave Gerdes or Mike Higgins.
14
 
   Update to GRASS 5.7 Radim Blazek and David D. Gray.
15
 
 
16
 
   \date 2001-2008
 
12
   \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
17
13
 */
18
14
 
19
15
#include <string.h>
20
16
#include <stdlib.h>
21
17
#include <stdio.h>
 
18
#include <sys/types.h>
22
19
#include <grass/glocale.h>
23
 
#include <grass/gis.h>
24
 
#include <grass/Vect.h>
25
 
 
26
 
/*!
27
 
   \brief Build area on given side of line (GV_LEFT or GV_RIGHT)
28
 
 
29
 
   \param Map_info vector map
30
 
   \param iline line id
31
 
   \param side side (GV_LEFT or GV_RIGHT)
32
 
 
33
 
   \return > 0 number of  area
34
 
   \return < 0 number of isle
35
 
   \return 0 not created (may also already exist)
36
 
 */
37
 
int Vect_build_line_area(struct Map_info *Map, int iline, int side)
38
 
{
39
 
    int j, area, isle, n_lines, line, type, direction;
40
 
    static int first = 1;
41
 
    long offset;
42
 
    struct Plus_head *plus;
43
 
    P_LINE *BLine;
44
 
    static struct line_pnts *Points, *APoints;
45
 
    plus_t *lines;
46
 
    double area_size;
47
 
 
48
 
    plus = &(Map->plus);
49
 
 
50
 
    G_debug(3, "Vect_build_line_area() line = %d, side = %d", iline, side);
51
 
 
52
 
    if (first) {
53
 
        Points = Vect_new_line_struct();
54
 
        APoints = Vect_new_line_struct();
55
 
        first = 0;
56
 
    }
57
 
 
58
 
    area = dig_line_get_area(plus, iline, side);
59
 
    if (area != 0) {
60
 
        G_debug(3, "  area/isle = %d -> skip", area);
61
 
        return 0;
62
 
    }
63
 
 
64
 
    n_lines = dig_build_area_with_line(plus, iline, side, &lines);
65
 
    G_debug(3, "  n_lines = %d", n_lines);
66
 
    if (n_lines < 1) {
67
 
        return 0;
68
 
    }                           /* area was not built */
69
 
 
70
 
    /* Area or island ? */
71
 
    Vect_reset_line(APoints);
72
 
    for (j = 0; j < n_lines; j++) {
73
 
        line = abs(lines[j]);
74
 
        BLine = plus->Line[line];
75
 
        offset = BLine->offset;
76
 
        G_debug(3, "  line[%d] = %d, offset = %ld", j, line, offset);
77
 
        type = Vect_read_line(Map, Points, NULL, line);
78
 
        if (lines[j] > 0)
79
 
            direction = GV_FORWARD;
80
 
        else
81
 
            direction = GV_BACKWARD;
82
 
        Vect_append_points(APoints, Points, direction);
83
 
    }
84
 
 
85
 
    dig_find_area_poly(APoints, &area_size);
86
 
    G_debug(3, "  area/isle size = %f", area_size);
87
 
 
88
 
    if (area_size > 0) {        /* area */
89
 
        /* add area structure to plus */
90
 
        area = dig_add_area(plus, n_lines, lines);
91
 
        if (area == -1) {       /* error */
92
 
            Vect_close(Map);
93
 
            G_fatal_error(_("Unable to add area (map closed, topo saved)"));
94
 
        }
95
 
        G_debug(3, "  -> area %d", area);
96
 
        return area;
97
 
    }
98
 
    else if (area_size < 0) {   /* island */
99
 
        isle = dig_add_isle(plus, n_lines, lines);
100
 
        if (isle == -1) {       /* error */
101
 
            Vect_close(Map);
102
 
            G_fatal_error(_("Unable to add isle (map closed, topo saved)"));
103
 
        }
104
 
        G_debug(3, "  -> isle %d", isle);
105
 
        return -isle;
106
 
    }
107
 
    else {
108
 
        /* TODO: What to do with such areas? Should be areas/isles of size 0 stored,
109
 
         *        so that may be found and cleaned by some utility
110
 
         *  Note: it would be useful for vertical closed polygons, but such would be added twice
111
 
         *        as area */
112
 
        G_warning(_("Area of size = 0.0 ignored"));
113
 
    }
114
 
    return 0;
115
 
}
116
 
 
117
 
/*!
118
 
   \brief Find area outside island
119
 
 
120
 
   \param Map_info vector map
121
 
   \param isle isle id
122
 
 
123
 
   \return number of  area(s)
124
 
   \return 0 if not found
125
 
 */
126
 
int Vect_isle_find_area(struct Map_info *Map, int isle)
127
 
{
128
 
    int j, line, node, sel_area, first, area, poly;
129
 
    static int first_call = 1;
130
 
    struct Plus_head *plus;
131
 
    P_LINE *Line;
132
 
    P_NODE *Node;
133
 
    P_ISLE *Isle;
134
 
    P_AREA *Area;
135
 
    double size, cur_size;
136
 
    BOUND_BOX box, abox;
137
 
    static struct ilist *List;
138
 
    static struct line_pnts *APoints;
139
 
 
140
 
    /* Note: We should check all isle points (at least) because if topology is not clean
141
 
     * and two areas overlap, isle which is not completely within area may be attached,
142
 
     * but it would take long time */
143
 
 
144
 
    G_debug(3, "Vect_isle_find_area () island = %d", isle);
145
 
    plus = &(Map->plus);
146
 
 
147
 
    if (plus->Isle[isle] == NULL) {
148
 
        G_warning(_("Request to find area outside nonexistent isle"));
149
 
        return 0;
150
 
    }
151
 
 
152
 
    if (first_call) {
153
 
        List = Vect_new_list();
154
 
        APoints = Vect_new_line_struct();
155
 
        first_call = 0;
156
 
    }
157
 
 
158
 
    Isle = plus->Isle[isle];
159
 
    line = abs(Isle->lines[0]);
160
 
    Line = plus->Line[line];
161
 
    node = Line->N1;
162
 
    Node = plus->Node[node];
163
 
 
164
 
    /* select areas by box */
165
 
    box.E = Node->x;
166
 
    box.W = Node->x;
167
 
    box.N = Node->y;
168
 
    box.S = Node->y;
169
 
    box.T = PORT_DOUBLE_MAX;
170
 
    box.B = -PORT_DOUBLE_MAX;
171
 
    Vect_select_areas_by_box(Map, &box, List);
172
 
    G_debug(3, "%d areas overlap island boundary point", List->n_values);
173
 
 
174
 
    sel_area = 0;
175
 
    cur_size = -1;
176
 
    first = 1;
177
 
    Vect_get_isle_box(Map, isle, &box);
178
 
    for (j = 0; j < List->n_values; j++) {
179
 
        area = List->value[j];
180
 
        G_debug(3, "area = %d", area);
181
 
 
182
 
        Area = plus->Area[area];
183
 
 
184
 
        /* Before other tests, simply exclude those areas inside isolated isles formed by one boundary */
185
 
        if (abs(Isle->lines[0]) == abs(Area->lines[0])) {
186
 
            G_debug(3, "  area inside isolated isle");
187
 
            continue;
188
 
        }
189
 
 
190
 
        /* Check box */
191
 
        /* Note: If build is run on large files of areas imported from nontopo format (shapefile)
192
 
         * attaching of isles takes very  long time because each area is also isle and select by
193
 
         * box all overlapping areas selects all areas with box overlapping first node. 
194
 
         * Then reading coordinates for all those areas would take a long time -> check first 
195
 
         * if isle's box is completely within area box */
196
 
        Vect_get_area_box(Map, area, &abox);
197
 
        if (box.E > abox.E || box.W < abox.W || box.N > abox.N ||
198
 
            box.S < abox.S) {
199
 
            G_debug(3, "  isle not completely inside area box");
200
 
            continue;
201
 
        }
202
 
 
203
 
        poly = Vect_point_in_area_outer_ring(Node->x, Node->y, Map, area);
204
 
        G_debug(3, "  poly = %d", poly);
205
 
 
206
 
        if (poly == 1) {        /* pint in area, but node is not part of area inside isle (would be poly == 2) */
207
 
            /* In rare case island is inside more areas in that case we have to calculate area
208
 
             * of outer ring and take the smaller */
209
 
            if (sel_area == 0) {        /* first */
210
 
                sel_area = area;
211
 
            }
212
 
            else {              /* is not first */
213
 
                if (cur_size < 0) {     /* second area */
214
 
                    /* This is slow, but should not be called often */
215
 
                    Vect_get_area_points(Map, sel_area, APoints);
216
 
                    G_begin_polygon_area_calculations();
217
 
                    cur_size =
218
 
                        G_area_of_polygon(APoints->x, APoints->y,
219
 
                                          APoints->n_points);
220
 
                    G_debug(3, "  first area size = %f (n points = %d)",
221
 
                            cur_size, APoints->n_points);
222
 
 
223
 
                }
224
 
 
225
 
                Vect_get_area_points(Map, area, APoints);
226
 
                size =
227
 
                    G_area_of_polygon(APoints->x, APoints->y,
228
 
                                      APoints->n_points);
229
 
                G_debug(3, "  area size = %f (n points = %d)", cur_size,
230
 
                        APoints->n_points);
231
 
 
232
 
                if (size < cur_size) {
233
 
                    sel_area = area;
234
 
                    cur_size = size;
235
 
                }
236
 
            }
237
 
            G_debug(3, "sel_area = %d cur_size = %f", sel_area, cur_size);
238
 
        }
239
 
    }
240
 
    if (sel_area > 0) {
241
 
        G_debug(3, "Island %d in area %d", isle, sel_area);
242
 
    }
243
 
    else {
244
 
        G_debug(3, "Island %d is not in area", isle);
245
 
    }
246
 
 
247
 
    return sel_area;
248
 
}
249
 
 
250
 
/*!
251
 
   \brief (Re)Attach isle to area
252
 
 
253
 
   \param Map_info vector map
254
 
   \param isle isle id
255
 
 
256
 
   \return 0
257
 
 */
258
 
int Vect_attach_isle(struct Map_info *Map, int isle)
259
 
{
260
 
    int sel_area;
261
 
    P_ISLE *Isle;
262
 
    struct Plus_head *plus;
263
 
 
264
 
    /* Note!: If topology is not clean and areas overlap, one island may fall to more areas
265
 
     *  (partially or fully). Before isle is attached to area it must be check if it is not attached yet */
266
 
    G_debug(3, "Vect_attach_isle (): isle = %d", isle);
267
 
 
268
 
    plus = &(Map->plus);
269
 
 
270
 
    sel_area = Vect_isle_find_area(Map, isle);
271
 
    G_debug(3, "      isle = %d -> area outside = %d", isle, sel_area);
272
 
    if (sel_area > 0) {
273
 
        Isle = plus->Isle[isle];
274
 
        if (Isle->area > 0) {
275
 
            G_debug(3,
276
 
                    "Attempt to attach isle %d to more areas (=>topology is not clean)",
277
 
                    isle);
278
 
        }
279
 
        else {
280
 
            Isle->area = sel_area;
281
 
            dig_area_add_isle(plus, sel_area, isle);
282
 
        }
283
 
    }
284
 
    return 0;
285
 
}
286
 
 
287
 
/*!
288
 
   \brief (Re)Attach isles to areas in given box
289
 
 
290
 
   \param Map_info vector map
291
 
   \param box bounding box
292
 
 
293
 
   \return 0
294
 
 */
295
 
int Vect_attach_isles(struct Map_info *Map, BOUND_BOX * box)
296
 
{
297
 
    int i, isle;
298
 
    static int first = 1;
299
 
    static struct ilist *List;
300
 
    struct Plus_head *plus;
301
 
 
302
 
    G_debug(3, "Vect_attach_isles ()");
303
 
 
304
 
    plus = &(Map->plus);
305
 
 
306
 
    if (first) {
307
 
        List = Vect_new_list();
308
 
        first = 0;
309
 
    }
310
 
 
311
 
    Vect_select_isles_by_box(Map, box, List);
312
 
    G_debug(3, "  number of isles to attach = %d", List->n_values);
313
 
 
314
 
    for (i = 0; i < List->n_values; i++) {
315
 
        isle = List->value[i];
316
 
        Vect_attach_isle(Map, isle);
317
 
    }
318
 
    return 0;
319
 
}
320
 
 
321
 
/*!
322
 
   \brief (Re)Attach centroids to areas in given box
323
 
 
324
 
   \param Map_info vector map
325
 
   \param box bounding box
326
 
 
327
 
   \return 0
328
 
 */
329
 
int Vect_attach_centroids(struct Map_info *Map, BOUND_BOX * box)
330
 
{
331
 
    int i, sel_area, centr;
332
 
    static int first = 1;
333
 
    static struct ilist *List;
334
 
    P_AREA *Area;
335
 
    P_LINE *Line;
336
 
    struct Plus_head *plus;
337
 
 
338
 
    G_debug(3, "Vect_attach_centroids ()");
339
 
 
340
 
    plus = &(Map->plus);
341
 
 
342
 
    if (first) {
343
 
        List = Vect_new_list();
344
 
        first = 0;
345
 
    }
346
 
 
347
 
    /* Warning: If map is updated on level2, it may happen that previously correct island 
348
 
     * becomes incorrect. In that case, centroid of area forming the island is reattached 
349
 
     * to outer area, because island polygon is not excluded. 
350
 
     *
351
 
     * +-----------+     +-----------+
352
 
     * |   1       |     |   1       |
353
 
     * | +---+---+ |     | +---+---+ |     
354
 
     * | | 2 | 3 | |     | | 2 |     |   
355
 
     * | | x |   | |  -> | | x |     |  
356
 
     * | |   |   | |     | |   |     | 
357
 
     * | +---+---+ |     | +---+---+ |
358
 
     * |           |     |           |
359
 
     * +-----------+     +-----------+
360
 
     * centroid is       centroid is
361
 
     * attached to 2     reattached to 1
362
 
     *
363
 
     * Because of this, when the centroid is reattached to another area, it is always necessary
364
 
     * to check if original area exist, unregister centroid from previous area.
365
 
     * To simplify code, this is implemented so that centroid is always firs unregistered 
366
 
     * and if new area is found, it is registered again.
367
 
     *
368
 
     * This problem can be avoided altogether if properly attached centroids
369
 
     * are skipped
370
 
     * MM 2009
371
 
     */
372
 
 
373
 
    Vect_select_lines_by_box(Map, box, GV_CENTROID, List);
374
 
    G_debug(3, "  number of centroids to reattach = %d", List->n_values);
375
 
    for (i = 0; i < List->n_values; i++) {
376
 
        int orig_area;
377
 
 
378
 
        centr = List->value[i];
379
 
        Line = plus->Line[centr];
380
 
 
381
 
        /* only attach unregistered and duplicate centroids because 
382
 
         * 1) all properly attached centroids are properly attached, really! Don't touch.
383
 
         * 2) Vect_find_area() below does not always return the correct area
384
 
         * 3) it's faster
385
 
         */
386
 
        if (Line->left > 0)
387
 
            continue; 
388
 
 
389
 
        orig_area = Line->left;
390
 
 
391
 
        sel_area = Vect_find_area(Map, Line->E, Line->N);
392
 
        G_debug(3, "  centroid %d is in area %d", centr, sel_area);
393
 
        if (sel_area > 0) {
394
 
            Area = plus->Area[sel_area];
395
 
            if (Area->centroid == 0) {  /* first centroid */
396
 
                G_debug(3, "  first centroid -> attach to area");
397
 
                Area->centroid = centr;
398
 
                Line->left = sel_area;
399
 
                
400
 
                if (sel_area != orig_area && plus->do_uplist)
401
 
                    dig_line_add_updated(plus, centr);
402
 
            }
403
 
            else if (Area->centroid != centr) { /* duplicate centroid */
404
 
                /* Note: it cannot happen that Area->centroid == centr, because the centroid
405
 
                 * was not registered or a duplicate */
406
 
                G_debug(3, "  duplicate centroid -> do not attach to area");
407
 
                Line->left = -sel_area;
408
 
 
409
 
                if (-sel_area != orig_area && plus->do_uplist)
410
 
                    dig_line_add_updated(plus, centr);
411
 
            }
412
 
        }
413
 
 
414
 
        if (sel_area != orig_area && plus->do_uplist)
415
 
            dig_line_add_updated(plus, centr);
416
 
    }
417
 
 
418
 
    return 0;
419
 
}
 
20
#include <grass/vector.h>
 
21
 
 
22
static struct line_pnts *Points;
420
23
 
421
24
/*!
422
25
   \brief Build topology 
423
26
 
424
 
   \param Map_info vector map
 
27
   \param Map vector map
425
28
   \param build build level
426
29
 
427
30
   \return 1 on success
430
33
int Vect_build_nat(struct Map_info *Map, int build)
431
34
{
432
35
    struct Plus_head *plus;
433
 
    int i, s, type, lineid;
434
 
    long offset;
435
 
    int side, line, area;
436
 
    struct line_pnts *Points, *APoints;
 
36
    int i, s, type, line;
 
37
    off_t offset;
 
38
    int side, area;
437
39
    struct line_cats *Cats;
438
 
    P_LINE *Line;
439
 
    P_NODE *Node;
440
 
    P_AREA *Area;
441
 
    BOUND_BOX box;
442
 
    struct ilist *List;
443
 
 
 
40
    struct P_line *Line;
 
41
    struct P_area *Area;
 
42
    struct bound_box box;
 
43
    
444
44
    G_debug(3, "Vect_build_nat() build = %d", build);
445
45
 
446
46
    plus = &(Map->plus);
449
49
        return 1;               /* Do nothing */
450
50
 
451
51
    /* Check if upgrade or downgrade */
452
 
    if (build < plus->built) {  /* lower level request */
453
 
 
454
 
        /* release old sources (this also initializes structures and numbers of elements) */
455
 
        if (plus->built >= GV_BUILD_CENTROIDS && build < GV_BUILD_CENTROIDS) {
456
 
            /* reset info about areas stored for centroids */
457
 
            int nlines = Vect_get_num_lines(Map);
458
 
 
459
 
            for (line = 1; line <= nlines; line++) {
460
 
                Line = plus->Line[line];
461
 
                if (Line && Line->type == GV_CENTROID)
462
 
                    Line->left = 0;
463
 
            }
464
 
            dig_free_plus_areas(plus);
465
 
            dig_spidx_free_areas(plus);
466
 
            dig_free_plus_isles(plus);
467
 
            dig_spidx_free_isles(plus);
468
 
        }
469
 
 
470
 
 
471
 
        if (plus->built >= GV_BUILD_AREAS && build < GV_BUILD_AREAS) {
472
 
            /* reset info about areas stored for lines */
473
 
            int nlines = Vect_get_num_lines(Map);
474
 
 
475
 
            for (line = 1; line <= nlines; line++) {
476
 
                Line = plus->Line[line];
477
 
                if (Line && Line->type == GV_BOUNDARY) {
478
 
                    Line->left = 0;
479
 
                    Line->right = 0;
480
 
                }
481
 
            }
482
 
            dig_free_plus_areas(plus);
483
 
            dig_spidx_free_areas(plus);
484
 
            dig_free_plus_isles(plus);
485
 
            dig_spidx_free_isles(plus);
486
 
        }
487
 
        if (plus->built >= GV_BUILD_BASE && build < GV_BUILD_BASE) {
488
 
            dig_free_plus_nodes(plus);
489
 
            dig_spidx_free_nodes(plus);
490
 
            dig_free_plus_lines(plus);
491
 
            dig_spidx_free_lines(plus);
492
 
        }
493
 
 
494
 
        plus->built = build;
495
 
        return 1;
 
52
    if (build < plus->built) {
 
53
        /* -> downgrade */
 
54
        Vect__build_downgrade(Map, build);
 
55
        return 1;
496
56
    }
497
57
 
498
 
    Points = Vect_new_line_struct();
499
 
    APoints = Vect_new_line_struct();
 
58
    /* -> upgrade */
 
59
    if (!Points)
 
60
        Points = Vect_new_line_struct();
500
61
    Cats = Vect_new_cats_struct();
501
 
    List = Vect_new_list();
502
 
 
 
62
    
503
63
    if (plus->built < GV_BUILD_BASE) {
504
 
        int npoints, format;
505
 
 
506
 
        format = G_info_format();
507
 
 
 
64
        int npoints, c;
 
65
        
508
66
        /* 
509
 
         *  We shall go through all primitives in coor file and 
510
 
         *  add new node for each end point to nodes structure
511
 
         *  if the node with the same coordinates doesn't exist yet.
 
67
         *  We shall go through all primitives in coor file and add
 
68
         *  new node for each end point to nodes structure if the node
 
69
         *  with the same coordinates doesn't exist yet.
512
70
         */
513
71
 
514
72
        /* register lines, create nodes */
515
73
        Vect_rewind(Map);
516
74
        G_message(_("Registering primitives..."));
517
 
        i = 1;
 
75
        i = 0;
518
76
        npoints = 0;
519
 
        while (1) {
 
77
        while (TRUE) {
520
78
            /* register line */
521
79
            type = Vect_read_next_line(Map, Points, Cats);
522
80
 
523
 
            /* Note: check for dead lines is not needed, because they are skipped by V1_read_next_line_nat() */
 
81
            /* Note: check for dead lines is not needed, because they
 
82
               are skipped by V1_read_next_line() */
524
83
            if (type == -1) {
525
84
                G_warning(_("Unable to read vector map"));
526
85
                return 0;
529
88
                break;
530
89
            }
531
90
 
 
91
            G_progress(++i, 1e4);
 
92
            
532
93
            npoints += Points->n_points;
533
94
 
534
95
            offset = Map->head.last_offset;
535
96
 
536
 
            G_debug(3, "Register line: offset = %ld", offset);
537
 
            lineid = dig_add_line(plus, type, Points, offset);
 
97
            G_debug(3, "Register line: offset = %lu", (unsigned long)offset);
538
98
            dig_line_box(Points, &box);
539
 
            if (lineid == 1)
 
99
            line = dig_add_line(plus, type, Points, &box, offset);
 
100
            if (line == 1)
540
101
                Vect_box_copy(&(plus->box), &box);
541
102
            else
542
103
                Vect_box_extend(&(plus->box), &box);
543
104
 
544
105
            /* Add all categories to category index */
545
106
            if (build == GV_BUILD_ALL) {
546
 
                int c;
547
 
 
548
107
                for (c = 0; c < Cats->n_cats; c++) {
549
108
                    dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c],
550
 
                                     lineid, type);
 
109
                                     line, type);
551
110
                }
552
111
                if (Cats->n_cats == 0)  /* add field 0, cat 0 */
553
 
                    dig_cidx_add_cat(plus, 0, 0, lineid, type);
554
 
            }
555
 
 
556
 
            if (G_verbose() > G_verbose_min() && i % 1000 == 0) {
557
 
                if (format == G_INFO_FORMAT_PLAIN)
558
 
                    fprintf(stderr, "%d..", i);
559
 
                else
560
 
                    fprintf(stderr, "%9d\b\b\b\b\b\b\b\b\b", i);
561
 
            }
562
 
            
563
 
            i++;
 
112
                    dig_cidx_add_cat(plus, 0, 0, line, type);
 
113
            }
564
114
        }
565
 
        
566
 
        if ( (G_verbose() > G_verbose_min() ) && format != G_INFO_FORMAT_PLAIN )
567
 
            fprintf(stderr, "\r");
 
115
        G_progress(1, 1);
568
116
 
569
 
        G_message(_("%d primitives registered"), plus->n_lines);
570
 
        G_message(_("%d vertices registered"), npoints);
 
117
        G_message(_n("One primitive registered", "%d primitives registered", plus->n_lines), plus->n_lines);
 
118
        G_message(_n("One vertex registered", "%d vertices registered", npoints), npoints);
571
119
 
572
120
        plus->built = GV_BUILD_BASE;
573
121
    }
579
127
        /* Build areas */
580
128
        /* Go through all bundaries and try to build area for both sides */
581
129
        G_important_message(_("Building areas..."));
582
 
        for (i = 1; i <= plus->n_lines; i++) {
583
 
            G_percent(i, plus->n_lines, 1);
 
130
        G_percent(0, plus->n_lines, 1);
 
131
        for (line = 1; line <= plus->n_lines; line++) {
 
132
            G_percent(line, plus->n_lines, 1);
584
133
 
585
134
            /* build */
586
 
            if (plus->Line[i] == NULL) {
 
135
            if (plus->Line[line] == NULL) {
587
136
                continue;
588
137
            }                   /* dead line */
589
 
            Line = plus->Line[i];
 
138
            Line = plus->Line[line];
590
139
            if (Line->type != GV_BOUNDARY) {
591
140
                continue;
592
141
            }
597
146
                else
598
147
                    side = GV_RIGHT;
599
148
 
600
 
                G_debug(3, "Build area for line = %d, side = %d", i, side);
601
 
                Vect_build_line_area(Map, i, side);
 
149
                G_debug(3, "Build area for line = %d, side = %d", line, side);
 
150
                Vect_build_line_area(Map, line, side);
602
151
            }
603
152
        }
604
 
        G_message(_("%d areas built"), plus->n_areas);
605
 
        G_message(_("%d isles built"), plus->n_isles);
 
153
        G_message(_n("One area built", "%d areas built", plus->n_areas), plus->n_areas);
 
154
        G_message(_n("One isle built", "%d isles built", plus->n_isles), plus->n_isles);
606
155
        plus->built = GV_BUILD_AREAS;
607
156
    }
608
157
 
614
163
        G_important_message(_("Attaching islands..."));
615
164
        for (i = 1; i <= plus->n_isles; i++) {
616
165
            G_percent(i, plus->n_isles, 1);
617
 
            Vect_attach_isle(Map, i);
 
166
            Vect_get_isle_box(Map, i, &box);
 
167
            Vect_attach_isle(Map, i, &box);
618
168
        }
619
169
        plus->built = GV_BUILD_ATTACH_ISLES;
620
170
    }
625
175
    /* Attach centroids to areas */
626
176
    if (plus->built < GV_BUILD_CENTROIDS) {
627
177
        int nlines;
 
178
        struct P_topo_c *topo;
628
179
 
629
180
        G_important_message(_("Attaching centroids..."));
630
181
 
639
190
            if (Line->type != GV_CENTROID)
640
191
                continue;
641
192
 
642
 
            Node = plus->Node[Line->N1];
643
 
 
644
 
            area = Vect_find_area(Map, Node->x, Node->y);
 
193
            Vect_read_line(Map, Points, NULL, line);
 
194
            area = Vect_find_area(Map, Points->x[0], Points->y[0]);
645
195
 
646
196
            if (area > 0) {
647
197
                G_debug(3, "Centroid (line=%d) in area %d", line, area);
648
198
 
649
199
                Area = plus->Area[area];
 
200
                topo = (struct P_topo_c *)Line->topo;
650
201
 
651
202
                if (Area->centroid == 0) {      /* first */
652
203
                    Area->centroid = line;
653
 
                    Line->left = area;
 
204
                    topo->area = area;
654
205
                }
655
206
                else {          /* duplicate */
656
 
                    Line->left = -area;
 
207
                    topo->area = -area;
657
208
                }
658
209
            }
659
210
        }
661
212
    }
662
213
 
663
214
    /* Add areas to category index */
664
 
    for (area = 1; area <= plus->n_areas; area++) {
 
215
    for (i = 1; i <= plus->n_areas; i++) {
665
216
        int c;
666
217
 
667
 
        if (plus->Area[area] == NULL)
 
218
        if (plus->Area[i] == NULL)
668
219
            continue;
669
220
 
670
 
        if (plus->Area[area]->centroid > 0) {
671
 
            Vect_read_line(Map, NULL, Cats, plus->Area[area]->centroid);
 
221
        if (plus->Area[i]->centroid > 0) {
 
222
            Vect_read_line(Map, NULL, Cats, plus->Area[i]->centroid);
672
223
 
673
224
            for (c = 0; c < Cats->n_cats; c++) {
674
 
                dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c], area,
 
225
                dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c], i,
675
226
                                 GV_AREA);
676
227
            }
677
228
        }
678
229
 
679
 
        if (plus->Area[area]->centroid == 0 || Cats->n_cats == 0)       /* no centroid or no cats */
680
 
            dig_cidx_add_cat(plus, 0, 0, area, GV_AREA);
 
230
        if (plus->Area[i]->centroid == 0 || Cats->n_cats == 0)  /* no centroid or no cats */
 
231
            dig_cidx_add_cat(plus, 0, 0, i, GV_AREA);
681
232
    }
682
233
 
 
234
    Vect_destroy_cats_struct(Cats);
 
235
    
683
236
    return 1;
684
237
}