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

« back to all changes in this revision

Viewing changes to lib/vector/diglib/spindex.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
 
 
2
 
/**
3
 
 * \file spindex.c
4
 
 *
5
 
 * \brief Vector library - spatial index (lower level functions)
6
 
 *
7
 
 * Lower level functions for reading/writing/manipulating vectors.
8
 
 *
9
 
 * (C) 2001 by the GRASS Development Team
10
 
 *
11
 
 * This program is free software under the GNU General Public License
12
 
 * (>=v2). Read the file COPYING that comes with GRASS for details.
13
 
 *
14
 
 * \author CERL (probably Dave Gerdes), Radim Blazek
 
1
/*!
 
2
   \file diglib/spindex.c
 
3
 
 
4
   \brief Vector library - spatial index (lower level functions)
 
5
 
 
6
   Lower level functions for reading/writing/manipulating vectors.
 
7
 
 
8
   (C) 2001-2009 by the GRASS Development Team
 
9
 
 
10
   This program is free software under the GNU General Public License
 
11
   (>=v2). Read the file COPYING that comes with GRASS for details.
 
12
 
 
13
   \author Original author CERL, probably Dave Gerdes
 
14
   \author Update to GRASS 5.7 Radim Blazek
 
15
   \author Update to GRASS 7 Markus Metz
15
16
 */
16
17
 
17
18
#include <stdlib.h>
 
19
#include <sys/types.h>
 
20
#include <sys/stat.h>
 
21
#include <fcntl.h>
 
22
#include <unistd.h>
18
23
#include <string.h>
19
 
#include <grass/gis.h>
20
 
#include <grass/Vect.h>
 
24
#include <grass/vector.h>
21
25
#include <grass/glocale.h>
22
26
 
23
27
/*!
30
34
 */
31
35
int dig_spidx_init(struct Plus_head *Plus)
32
36
{
33
 
 
34
 
    G_debug(1, "dig_spidx_init()");
35
 
 
36
 
    Plus->Node_spidx = RTreeNewIndex();
37
 
    Plus->Line_spidx = RTreeNewIndex();
38
 
    Plus->Area_spidx = RTreeNewIndex();
39
 
    Plus->Isle_spidx = RTreeNewIndex();
 
37
    int ndims;
 
38
 
 
39
    ndims = (Plus->with_z != 0) ? 3 : 2;
 
40
    Plus->spidx_with_z = (Plus->with_z != 0);
 
41
 
 
42
    G_debug(1, "dig_spidx_init(), %d dims", ndims);
 
43
 
 
44
    if (Plus->Spidx_file) {
 
45
        int fd;
 
46
        char *filename;
 
47
        
 
48
        filename = G_tempfile();
 
49
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
50
        Plus->Node_spidx = RTreeCreateTree(fd, 0, ndims);
 
51
        remove(filename);
 
52
 
 
53
        filename = G_tempfile();
 
54
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
55
        Plus->Line_spidx = RTreeCreateTree(fd, 0, ndims);
 
56
        remove(filename);
 
57
 
 
58
        filename = G_tempfile();
 
59
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
60
        Plus->Area_spidx = RTreeCreateTree(fd, 0, ndims);
 
61
        remove(filename);
 
62
 
 
63
        filename = G_tempfile();
 
64
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
65
        Plus->Isle_spidx = RTreeCreateTree(fd, 0, ndims);
 
66
        remove(filename);
 
67
 
 
68
        Plus->Face_spidx = NULL;
 
69
        Plus->Volume_spidx = NULL;
 
70
        Plus->Hole_spidx = NULL;
 
71
        
 
72
        if (!Plus->Spidx_new) {
 
73
            close(Plus->Node_spidx->fd);
 
74
            close(Plus->Line_spidx->fd);
 
75
            close(Plus->Area_spidx->fd);
 
76
            close(Plus->Isle_spidx->fd);
 
77
        }
 
78
    }
 
79
    else {
 
80
        Plus->Node_spidx = RTreeCreateTree(-1, 0, ndims);
 
81
        Plus->Line_spidx = RTreeCreateTree(-1, 0, ndims);
 
82
        Plus->Area_spidx = RTreeCreateTree(-1, 0, ndims);
 
83
        Plus->Isle_spidx = RTreeCreateTree(-1, 0, ndims);
 
84
        Plus->Face_spidx = NULL;
 
85
        Plus->Volume_spidx = NULL;
 
86
        Plus->Hole_spidx = NULL;
 
87
    }
40
88
 
41
89
    Plus->Node_spidx_offset = 0L;
42
 
    Plus->Edge_spidx_offset = 0L;
43
90
    Plus->Line_spidx_offset = 0L;
44
91
    Plus->Area_spidx_offset = 0L;
45
92
    Plus->Isle_spidx_offset = 0L;
 
93
    Plus->Face_spidx_offset = 0L;
46
94
    Plus->Volume_spidx_offset = 0L;
47
95
    Plus->Hole_spidx_offset = 0L;
48
96
 
 
97
    Plus->Spidx_built = FALSE;
 
98
    
49
99
    return 1;
50
100
}
51
101
 
52
 
/*!
 
102
/*! 
53
103
   \brief Free spatial index for nodes
54
104
 
55
105
   \param Plus pointer to Plus_head structure
56
106
 */
57
107
void dig_spidx_free_nodes(struct Plus_head *Plus)
58
108
{
59
 
    RTreeDestroyNode(Plus->Node_spidx);
60
 
    Plus->Node_spidx = RTreeNewIndex();
 
109
    int ndims;
 
110
 
 
111
    ndims = Plus->with_z ? 3 : 2;
 
112
 
 
113
    /* Node spidx */
 
114
    if (Plus->Node_spidx->fd > -1) {
 
115
        int fd;
 
116
        char *filename;
 
117
        
 
118
        if (Plus->Spidx_new)
 
119
            close(Plus->Node_spidx->fd);
 
120
        RTreeDestroyTree(Plus->Node_spidx);
 
121
        filename = G_tempfile();
 
122
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
123
        Plus->Node_spidx = RTreeCreateTree(fd, 0, ndims);
 
124
        remove(filename);
 
125
        if (!Plus->Spidx_new)
 
126
            close(Plus->Node_spidx->fd);
 
127
    }
 
128
    else {
 
129
        RTreeDestroyTree(Plus->Node_spidx);
 
130
        Plus->Node_spidx = RTreeCreateTree(-1, 0, ndims);
 
131
    }
61
132
}
62
133
 
63
 
/*!
 
134
/*! 
64
135
   \brief Free spatial index for lines
65
136
 
66
137
   \param Plus pointer to Plus_head structure
67
138
 */
68
139
void dig_spidx_free_lines(struct Plus_head *Plus)
69
140
{
70
 
    RTreeDestroyNode(Plus->Line_spidx);
71
 
    Plus->Line_spidx = RTreeNewIndex();
 
141
    int ndims;
 
142
 
 
143
    ndims = Plus->with_z ? 3 : 2;
 
144
 
 
145
    /* Line spidx */
 
146
    if (Plus->Line_spidx->fd > -1) {
 
147
        int fd;
 
148
        char *filename;
 
149
        
 
150
        if (Plus->Spidx_new)
 
151
            close(Plus->Line_spidx->fd);
 
152
        RTreeDestroyTree(Plus->Line_spidx);
 
153
        filename = G_tempfile();
 
154
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
155
        Plus->Line_spidx = RTreeCreateTree(fd, 0, ndims);
 
156
        remove(filename);
 
157
        if (!Plus->Spidx_new)
 
158
            close(Plus->Line_spidx->fd);
 
159
    }
 
160
    else {
 
161
        RTreeDestroyTree(Plus->Line_spidx);
 
162
        Plus->Line_spidx = RTreeCreateTree(-1, 0, ndims);
 
163
    }
72
164
}
73
165
 
74
 
/*!
75
 
   \brief Free spatial index for areas
 
166
/*! 
 
167
   \brief Reset spatial index for areas
76
168
 
77
169
   \param Plus pointer to Plus_head structure
78
170
 */
79
171
void dig_spidx_free_areas(struct Plus_head *Plus)
80
172
{
81
 
    RTreeDestroyNode(Plus->Area_spidx);
82
 
    Plus->Area_spidx = RTreeNewIndex();
 
173
    int ndims;
 
174
 
 
175
    ndims = Plus->with_z ? 3 : 2;
 
176
 
 
177
    /* Area spidx */
 
178
    if (Plus->Area_spidx->fd > -1) {
 
179
        int fd;
 
180
        char *filename;
 
181
        
 
182
        if (Plus->Spidx_new)
 
183
            close(Plus->Area_spidx->fd);
 
184
        RTreeDestroyTree(Plus->Area_spidx);
 
185
        filename = G_tempfile();
 
186
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
187
        Plus->Area_spidx = RTreeCreateTree(fd, 0, ndims);
 
188
        remove(filename);
 
189
        if (!Plus->Spidx_new)
 
190
            close(Plus->Area_spidx->fd);
 
191
    }
 
192
    else {
 
193
        RTreeDestroyTree(Plus->Area_spidx);
 
194
        Plus->Area_spidx = RTreeCreateTree(-1, 0, ndims);
 
195
    }
83
196
}
84
197
 
85
 
/*!
86
 
   \brief Free spatial index for isles
 
198
/*! 
 
199
   \brief Reset spatial index for isles
87
200
 
88
201
   \param Plus pointer to Plus_head structure
89
202
 */
90
203
void dig_spidx_free_isles(struct Plus_head *Plus)
91
204
{
92
 
    RTreeDestroyNode(Plus->Isle_spidx);
93
 
    Plus->Isle_spidx = RTreeNewIndex();
 
205
    int ndims;
 
206
 
 
207
    ndims = Plus->with_z ? 3 : 2;
 
208
 
 
209
    /* Isle spidx */
 
210
    if (Plus->Isle_spidx->fd > -1) {
 
211
        int fd;
 
212
        char *filename;
 
213
        
 
214
        if (Plus->Spidx_new)
 
215
            close(Plus->Isle_spidx->fd);
 
216
        RTreeDestroyTree(Plus->Isle_spidx);
 
217
        filename = G_tempfile();
 
218
        fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
 
219
        Plus->Isle_spidx = RTreeCreateTree(fd, 0, ndims);
 
220
        remove(filename);
 
221
        if (!Plus->Spidx_new)
 
222
            close(Plus->Isle_spidx->fd);
 
223
    }
 
224
    else {
 
225
        RTreeDestroyTree(Plus->Isle_spidx);
 
226
        Plus->Isle_spidx = RTreeCreateTree(-1, 0, ndims);
 
227
    }
94
228
}
95
229
 
96
230
/*! 
100
234
 */
101
235
void dig_spidx_free(struct Plus_head *Plus)
102
236
{
103
 
    dig_spidx_free_nodes(Plus);
104
 
    dig_spidx_free_lines(Plus);
105
 
    dig_spidx_free_areas(Plus);
106
 
    dig_spidx_free_isles(Plus);
 
237
    /* close tmp files */
 
238
    if (Plus->Spidx_new) {
 
239
        /* Node spidx */
 
240
        if (Plus->Node_spidx->fd > -1)
 
241
            close(Plus->Node_spidx->fd);
 
242
        /* Line spidx */
 
243
        if (Plus->Spidx_new && Plus->Line_spidx->fd > -1)
 
244
            close(Plus->Line_spidx->fd);
 
245
        /* Area spidx */
 
246
        if (Plus->Area_spidx->fd > -1)
 
247
            close(Plus->Area_spidx->fd);
 
248
        /* Isle spidx */
 
249
        if (Plus->Isle_spidx->fd > -1)
 
250
            close(Plus->Isle_spidx->fd);
 
251
    }
 
252
    
 
253
    /* destroy tree structures */
 
254
    /* Node spidx */
 
255
    if (Plus->Node_spidx)
 
256
        RTreeDestroyTree(Plus->Node_spidx);
 
257
    /* Line spidx */
 
258
    if (Plus->Line_spidx)
 
259
        RTreeDestroyTree(Plus->Line_spidx);
 
260
    /* Area spidx */
 
261
    if (Plus->Area_spidx)
 
262
        RTreeDestroyTree(Plus->Area_spidx);
 
263
    /* Isle spidx */
 
264
    if (Plus->Isle_spidx)
 
265
        RTreeDestroyTree(Plus->Isle_spidx);
 
266
 
 
267
    /* 3D future : */
 
268
    /* Face spidx */
 
269
    /* Volume spidx */
 
270
    /* Hole spidx */
107
271
}
108
272
 
109
273
/*!
120
284
dig_spidx_add_node(struct Plus_head *Plus, int node,
121
285
                   double x, double y, double z)
122
286
{
123
 
    struct Rect rect;
 
287
    static struct RTree_Rect rect;
 
288
    static int rect_init = 0;
 
289
 
 
290
    if (!rect_init) {
 
291
        /* always 6 sides for 3D */
 
292
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
293
        rect_init = 6;
 
294
    }
124
295
 
125
296
    G_debug(3, "dig_spidx_add_node(): node = %d, x,y,z = %f, %f, %f", node, x,
126
297
            y, z);
131
302
    rect.boundary[3] = x;
132
303
    rect.boundary[4] = y;
133
304
    rect.boundary[5] = z;
134
 
    RTreeInsertRect(&rect, node, &(Plus->Node_spidx), 0);
 
305
    RTreeInsertRect(&rect, node, Plus->Node_spidx);
135
306
 
136
307
    return 1;
137
308
}
145
316
 
146
317
   \return 0
147
318
 */
148
 
int dig_spidx_add_line(struct Plus_head *Plus, int line, BOUND_BOX * box)
 
319
int dig_spidx_add_line(struct Plus_head *Plus, int line,
 
320
                       const struct bound_box *box)
149
321
{
150
 
    struct Rect rect;
 
322
    static struct RTree_Rect rect;
 
323
    static int rect_init = 0;
 
324
 
 
325
    if (!rect_init) {
 
326
        /* always 6 sides for 3D */
 
327
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
328
        rect_init = 6;
 
329
    }
151
330
 
152
331
    G_debug(3, "dig_spidx_add_line(): line = %d", line);
153
332
 
157
336
    rect.boundary[3] = box->E;
158
337
    rect.boundary[4] = box->N;
159
338
    rect.boundary[5] = box->T;
160
 
    RTreeInsertRect(&rect, line, &(Plus->Line_spidx), 0);
 
339
    RTreeInsertRect(&rect, line, Plus->Line_spidx);
161
340
 
162
341
    return 0;
163
342
}
171
350
 
172
351
   \return 0
173
352
 */
174
 
int dig_spidx_add_area(struct Plus_head *Plus, int area, BOUND_BOX * box)
 
353
int dig_spidx_add_area(struct Plus_head *Plus, int area,
 
354
                       const struct bound_box *box)
175
355
{
176
 
    struct Rect rect;
 
356
    static struct RTree_Rect rect;
 
357
    static int rect_init = 0;
 
358
 
 
359
    if (!rect_init) {
 
360
        /* always 6 sides for 3D */
 
361
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
362
        rect_init = 6;
 
363
    }
177
364
 
178
365
    G_debug(3, "dig_spidx_add_area(): area = %d", area);
179
366
 
183
370
    rect.boundary[3] = box->E;
184
371
    rect.boundary[4] = box->N;
185
372
    rect.boundary[5] = box->T;
186
 
    RTreeInsertRect(&rect, area, &(Plus->Area_spidx), 0);
 
373
    RTreeInsertRect(&rect, area, Plus->Area_spidx);
187
374
 
188
375
    return 0;
189
376
}
198
385
   \return 0
199
386
 */
200
387
 
201
 
int dig_spidx_add_isle(struct Plus_head *Plus, int isle, BOUND_BOX * box)
 
388
int dig_spidx_add_isle(struct Plus_head *Plus, int isle,
 
389
                       const struct bound_box *box)
202
390
{
203
 
    struct Rect rect;
 
391
    static struct RTree_Rect rect;
 
392
    static int rect_init = 0;
 
393
 
 
394
    if (!rect_init) {
 
395
        /* always 6 sides for 3D */
 
396
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
397
        rect_init = 6;
 
398
    }
204
399
 
205
400
    G_debug(3, "dig_spidx_add_isle(): isle = %d", isle);
206
401
 
210
405
    rect.boundary[3] = box->E;
211
406
    rect.boundary[4] = box->N;
212
407
    rect.boundary[5] = box->T;
213
 
    RTreeInsertRect(&rect, isle, &(Plus->Isle_spidx), 0);
 
408
    RTreeInsertRect(&rect, isle, Plus->Isle_spidx);
214
409
 
215
410
    return 0;
216
411
}
228
423
int dig_spidx_del_node(struct Plus_head *Plus, int node)
229
424
{
230
425
    int ret;
231
 
    P_NODE *Node;
232
 
    struct Rect rect;
 
426
    struct P_node *Node;
 
427
    static struct RTree_Rect rect;
 
428
    static int rect_init = 0;
 
429
 
 
430
    if (!rect_init) {
 
431
        /* always 6 sides for 3D */
 
432
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
433
        rect_init = 6;
 
434
    }
233
435
 
234
436
    G_debug(3, "dig_spidx_del_node(): node = %d", node);
235
437
 
242
444
    rect.boundary[4] = Node->y;
243
445
    rect.boundary[5] = Node->z;
244
446
 
245
 
    ret = RTreeDeleteRect(&rect, node, &(Plus->Node_spidx));
 
447
    ret = RTreeDeleteRect(&rect, node, Plus->Node_spidx);
246
448
 
247
449
    if (ret)
248
450
        G_fatal_error(_("Unable to delete node %d from spatial index"), node);
257
459
 
258
460
   \param Plus pointer to Plus_head structure
259
461
   \param line line id
 
462
   \param x,y,z coordinates
260
463
 
261
464
   \return 0
262
465
 */
263
 
int dig_spidx_del_line(struct Plus_head *Plus, int line)
 
466
int dig_spidx_del_line(struct Plus_head *Plus, int line,
 
467
                       double x, double y, double z)
264
468
{
265
 
    P_LINE *Line;
266
 
    struct Rect rect;
267
469
    int ret;
 
470
    static struct RTree_Rect rect;
 
471
    static int rect_init = 0;
 
472
 
 
473
    if (!rect_init) {
 
474
        /* always 6 sides for 3D */
 
475
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
476
        rect_init = 6;
 
477
    }
268
478
 
269
479
    G_debug(3, "dig_spidx_del_line(): line = %d", line);
270
480
 
271
 
    Line = Plus->Line[line];
272
 
 
273
 
    G_debug(3, "  box(x1,y1,z1,x2,y2,z2): %f %f %f %f %f %f", Line->W,
274
 
            Line->S, Line->B, Line->E, Line->N, Line->T);
275
 
 
276
 
    rect.boundary[0] = Line->W;
277
 
    rect.boundary[1] = Line->S;
278
 
    rect.boundary[2] = Line->B;
279
 
    rect.boundary[3] = Line->E;
280
 
    rect.boundary[4] = Line->N;
281
 
    rect.boundary[5] = Line->T;
282
 
 
283
 
    ret = RTreeDeleteRect(&rect, line, &(Plus->Line_spidx));
 
481
    rect.boundary[0] = x;
 
482
    rect.boundary[1] = y;
 
483
    rect.boundary[2] = z;
 
484
    rect.boundary[3] = x;
 
485
    rect.boundary[4] = y;
 
486
    rect.boundary[5] = z;
 
487
 
 
488
    ret = RTreeDeleteRect(&rect, line, Plus->Line_spidx);
284
489
 
285
490
    G_debug(3, "  ret = %d", ret);
286
491
 
303
508
int dig_spidx_del_area(struct Plus_head *Plus, int area)
304
509
{
305
510
    int ret;
306
 
    P_AREA *Area;
307
 
    struct Rect rect;
 
511
    struct P_area *Area;
 
512
    struct P_line *Line;
 
513
    struct P_node *Node;
 
514
    struct P_topo_b *topo;
 
515
    static struct RTree_Rect rect;
 
516
    static int rect_init = 0;
 
517
 
 
518
    if (!rect_init) {
 
519
        /* always 6 sides for 3D */
 
520
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
521
        rect_init = 6;
 
522
    }
308
523
 
309
524
    G_debug(3, "dig_spidx_del_area(): area = %d", area);
310
525
 
314
529
        G_fatal_error(_("Attempt to delete sidx for dead area"));
315
530
    }
316
531
 
317
 
    rect.boundary[0] = Area->W;
318
 
    rect.boundary[1] = Area->S;
319
 
    rect.boundary[2] = Area->B;
320
 
    rect.boundary[3] = Area->E;
321
 
    rect.boundary[4] = Area->N;
322
 
    rect.boundary[5] = Area->T;
323
 
 
324
 
    ret = RTreeDeleteRect(&rect, area, &(Plus->Area_spidx));
 
532
    Line = Plus->Line[abs(Area->lines[0])];
 
533
    topo = (struct P_topo_b *)Line->topo;
 
534
    Node = Plus->Node[topo->N1];
 
535
 
 
536
    rect.boundary[0] = Node->x;
 
537
    rect.boundary[1] = Node->y;
 
538
    rect.boundary[2] = Node->z;
 
539
    rect.boundary[3] = Node->x;
 
540
    rect.boundary[4] = Node->y;
 
541
    rect.boundary[5] = Node->z;
 
542
 
 
543
    ret = RTreeDeleteRect(&rect, area, Plus->Area_spidx);
325
544
 
326
545
    if (ret)
327
546
        G_fatal_error(_("Unable to delete area %d from spatial index"), area);
342
561
int dig_spidx_del_isle(struct Plus_head *Plus, int isle)
343
562
{
344
563
    int ret;
345
 
    P_ISLE *Isle;
346
 
    struct Rect rect;
 
564
    struct P_isle *Isle;
 
565
    struct P_line *Line;
 
566
    struct P_node *Node;
 
567
    struct P_topo_b *topo;
 
568
    static struct RTree_Rect rect;
 
569
    static int rect_init = 0;
 
570
 
 
571
    if (!rect_init) {
 
572
        /* always 6 sides for 3D */
 
573
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
574
        rect_init = 6;
 
575
    }
347
576
 
348
577
    G_debug(3, "dig_spidx_del_isle(): isle = %d", isle);
349
578
 
350
579
    Isle = Plus->Isle[isle];
351
580
 
352
 
    rect.boundary[0] = Isle->W;
353
 
    rect.boundary[1] = Isle->S;
354
 
    rect.boundary[2] = Isle->B;
355
 
    rect.boundary[3] = Isle->E;
356
 
    rect.boundary[4] = Isle->N;
357
 
    rect.boundary[5] = Isle->T;
358
 
 
359
 
    ret = RTreeDeleteRect(&rect, isle, &(Plus->Isle_spidx));
 
581
    Line = Plus->Line[abs(Isle->lines[0])];
 
582
    topo = (struct P_topo_b *)Line->topo;
 
583
    Node = Plus->Node[topo->N1];
 
584
 
 
585
    rect.boundary[0] = Node->x;
 
586
    rect.boundary[1] = Node->y;
 
587
    rect.boundary[2] = Node->z;
 
588
    rect.boundary[3] = Node->x;
 
589
    rect.boundary[4] = Node->y;
 
590
    rect.boundary[5] = Node->z;
 
591
 
 
592
    ret = RTreeDeleteRect(&rect, isle, Plus->Isle_spidx);
360
593
 
361
594
    if (ret)
362
595
        G_fatal_error(_("Unable to delete isle %d from spatial index"), isle);
364
597
    return 0;
365
598
}
366
599
 
367
 
/* This function is called by  RTreeSearch() to add selected node/line/area/isle to thelist */
368
 
static int _add_item(int id, struct ilist *list)
369
 
{
370
 
    dig_list_add(list, id);
 
600
/* This function is called by RTreeSearch() to add selected node/line/area/isle to the list */
 
601
static int _add_item(int id, const struct RTree_Rect *rect,
 
602
                     struct ilist *list)
 
603
{
 
604
    G_ilist_add(list, id);
 
605
    return 1;
 
606
}
 
607
 
 
608
/* This function is called by RTreeSearch() to add 
 
609
 * selected node/line/area/isle to the box list */
 
610
static int _add_item_with_box(int id, const struct RTree_Rect *rect,
 
611
                              struct boxlist *list)
 
612
{
 
613
    struct bound_box box;
 
614
    
 
615
    box.W = rect->boundary[0];
 
616
    box.S = rect->boundary[1];
 
617
    box.B = rect->boundary[2];
 
618
    box.E = rect->boundary[3];
 
619
    box.N = rect->boundary[4];
 
620
    box.T = rect->boundary[5];
 
621
 
 
622
    dig_boxlist_add(list, id, &box);
 
623
    return 1;
 
624
}
 
625
 
 
626
struct boxid
 
627
{
 
628
    int id;
 
629
    struct bound_box *box;
 
630
};
 
631
 
 
632
/* This function is called by RTreeSearch() to add 
 
633
 * selected node/line/area/isle to the box list */
 
634
static int _set_item_box(int id, const struct RTree_Rect *rect,
 
635
                         struct boxid *box_id)
 
636
{
 
637
    if (id == box_id->id) {
 
638
        
 
639
        box_id->box->W = rect->boundary[0];
 
640
        box_id->box->S = rect->boundary[1];
 
641
        box_id->box->B = rect->boundary[2];
 
642
        box_id->box->E = rect->boundary[3];
 
643
        box_id->box->N = rect->boundary[4];
 
644
        box_id->box->T = rect->boundary[5];
 
645
        
 
646
        return 0;
 
647
    }
 
648
 
371
649
    return 1;
372
650
}
373
651
 
382
660
   \return -1 on error
383
661
 */
384
662
int
385
 
dig_select_nodes(struct Plus_head *Plus, BOUND_BOX * box, struct ilist *list)
 
663
dig_select_nodes(struct Plus_head *Plus, const struct bound_box * box,
 
664
                 struct ilist *list)
386
665
{
387
 
    struct Rect rect;
 
666
    static struct RTree_Rect rect;
 
667
    static int rect_init = 0;
 
668
 
 
669
    if (!rect_init) {
 
670
        /* always 6 sides for 3D */
 
671
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
672
        rect_init = 6;
 
673
    }
388
674
 
389
675
    G_debug(3, "dig_select_nodes()");
390
676
 
396
682
    rect.boundary[3] = box->E;
397
683
    rect.boundary[4] = box->N;
398
684
    rect.boundary[5] = box->T;
399
 
    RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_item, list);
 
685
 
 
686
    if (Plus->Spidx_new)
 
687
        RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_item, list);
 
688
    else
 
689
        rtree_search(Plus->Node_spidx, &rect, (void *)_add_item, list, Plus);
400
690
 
401
691
    return (list->n_values);
402
692
}
403
693
 
404
 
/* This function is called by  RTreeSearch() for nodes to add selected node to list */
405
 
static int _add_node(int id, int *node)
 
694
/* This function is called by RTreeSearch() for nodes to find the node id */
 
695
static int _add_node(int id, const struct RTree_Rect *rect, int *node)
406
696
{
407
697
    *node = id;
408
698
    return 0;
419
709
 */
420
710
int dig_find_node(struct Plus_head *Plus, double x, double y, double z)
421
711
{
422
 
    struct Rect rect;
423
 
    struct ilist list;
424
712
    int node;
 
713
    static struct RTree_Rect rect;
 
714
    static int rect_init = 0;
 
715
 
 
716
    if (!rect_init) {
 
717
        /* always 6 sides for 3D */
 
718
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
719
        rect_init = 6;
 
720
    }
425
721
 
426
722
    G_debug(3, "dig_find_node()");
427
723
 
428
 
    dig_init_list(&list);
429
 
 
430
724
    rect.boundary[0] = x;
431
725
    rect.boundary[1] = y;
432
726
    rect.boundary[2] = z;
435
729
    rect.boundary[5] = z;
436
730
 
437
731
    node = 0;
438
 
    RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_node, &node);
 
732
    if (Plus->Spidx_new)
 
733
        RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_node, &node);
 
734
    else
 
735
        rtree_search(Plus->Node_spidx, &rect, (void *)_add_node, &node, Plus);
439
736
 
440
737
    return node;
441
738
}
442
739
 
443
740
/*!
444
 
   \brief Select lines by box 
 
741
   \brief Select lines with boxes by box
445
742
 
446
743
   \param Plus pointer to Plus_head structure
447
744
   \param box bounding box
448
 
   \param list list of selected lines
 
745
   \param list boxlist of selected lines
449
746
 
450
747
   \return number of selected lines
 
748
   \return 0 not found
451
749
 */
452
 
int
453
 
dig_select_lines(struct Plus_head *Plus, BOUND_BOX * box, struct ilist *list)
 
750
int dig_select_lines(struct Plus_head *Plus, const struct bound_box *box, 
 
751
                     struct boxlist *list)
454
752
{
455
 
    struct Rect rect;
456
 
 
457
 
    G_debug(3, "dig_select_lines()");
 
753
    static struct RTree_Rect rect;
 
754
    static int rect_init = 0;
 
755
 
 
756
    if (!rect_init) {
 
757
        /* always 6 sides for 3D */
 
758
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
759
        rect_init = 6;
 
760
    }
 
761
 
 
762
    G_debug(3, "dig_select_lines_with_box()");
458
763
 
459
764
    list->n_values = 0;
460
765
 
464
769
    rect.boundary[3] = box->E;
465
770
    rect.boundary[4] = box->N;
466
771
    rect.boundary[5] = box->T;
467
 
    RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item, list);
 
772
 
 
773
    if (Plus->Spidx_new)
 
774
        RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list);
 
775
    else
 
776
        rtree_search(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list, Plus);
468
777
 
469
778
    return (list->n_values);
470
779
}
471
780
 
 
781
/*!
 
782
   \brief Find box for line
 
783
 
 
784
   \param Plus pointer to Plus_head structure
 
785
   \param line line id
 
786
   \param[out] box bounding box
 
787
 
 
788
   \return > 0 bounding box for line found
 
789
   \return 0 not found
 
790
 */
 
791
int dig_find_line_box(struct Plus_head *Plus, int line,
 
792
                      struct bound_box *box)
 
793
{
 
794
    int ret, type;
 
795
    struct P_line *Line;
 
796
    struct boxid box_id;
 
797
    static struct RTree_Rect rect;
 
798
    static int rect_init = 0;
 
799
 
 
800
    G_debug(3, "dig_find_line_box()");
 
801
 
 
802
    if (!rect_init) {
 
803
        /* always 6 sides for 3D */
 
804
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
805
        rect_init = 6;
 
806
    }
 
807
 
 
808
    Line = Plus->Line[line];
 
809
    type = Line->type;
 
810
 
 
811
    /* GV_LINES: retrieve box from spatial index */
 
812
    if (type & GV_LINES) {
 
813
        struct P_node *Node = NULL;
 
814
 
 
815
        if (type == GV_LINE) {
 
816
            struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
 
817
 
 
818
            Node = Plus->Node[topo->N1];
 
819
        }
 
820
        else if (type == GV_BOUNDARY) {
 
821
            struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
 
822
 
 
823
            Node = Plus->Node[topo->N1];
 
824
        }
 
825
 
 
826
        rect.boundary[0] = Node->x;
 
827
        rect.boundary[1] = Node->y;
 
828
        rect.boundary[2] = Node->z;
 
829
        rect.boundary[3] = Node->x;
 
830
        rect.boundary[4] = Node->y;
 
831
        rect.boundary[5] = Node->z;
 
832
        
 
833
        box_id.id = line;
 
834
        box_id.box = box;
 
835
 
 
836
        if (Plus->Spidx_new)
 
837
            ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, &box_id);
 
838
        else
 
839
            ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
 
840
 
 
841
        return ret;
 
842
    }
 
843
 
 
844
    /* do not translate this error because 
 
845
     * 1. this error is not supposed to happen
 
846
     * 2. the maintainer at which this message is directed prefers english */
 
847
    G_fatal_error("Bug in vector lib: dig_find_line_box() may only be used for lines and boundaries.");
 
848
 
 
849
    return 0;
 
850
}
 
851
 
472
852
/*! 
473
 
   \brief Select areas by box 
 
853
   \brief Select areas with boxes by box 
474
854
 
475
855
   \param Plus pointer to Plus_head structure
476
856
   \param box bounding box
477
 
   \param list list of selected lines
 
857
   \param list boxlist of selected areas
478
858
 
479
859
   \return number of selected areas
480
860
 */
481
861
int
482
 
dig_select_areas(struct Plus_head *Plus, BOUND_BOX * box, struct ilist *list)
 
862
dig_select_areas(struct Plus_head *Plus, const struct bound_box *box,
 
863
                 struct boxlist *list)
483
864
{
484
 
    struct Rect rect;
485
 
 
486
 
    G_debug(3, "dig_select_areas()");
 
865
    static struct RTree_Rect rect;
 
866
    static int rect_init = 0;
 
867
 
 
868
    if (!rect_init) {
 
869
        /* always 6 sides for 3D */
 
870
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
871
        rect_init = 6;
 
872
    }
 
873
 
 
874
    G_debug(3, "dig_select_areas_with_box()");
487
875
 
488
876
    list->n_values = 0;
489
877
 
493
881
    rect.boundary[3] = box->E;
494
882
    rect.boundary[4] = box->N;
495
883
    rect.boundary[5] = box->T;
496
 
    RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item, list);
 
884
 
 
885
    if (Plus->Spidx_new)
 
886
        RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list);
 
887
    else
 
888
        rtree_search(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list, Plus);
497
889
 
498
890
    return (list->n_values);
499
891
}
500
892
 
501
893
/*!
502
 
   \brief Select isles by box 
 
894
   \brief Find bounding box for given area
 
895
 
 
896
   \param Plus pointer to Plus_head structure
 
897
   \param area area id
 
898
   \param[out] box bounding box
 
899
 
 
900
   \return > 0 bounding box for area found
 
901
   \return 0 not found
 
902
 */
 
903
int dig_find_area_box(struct Plus_head *Plus, int area,
 
904
                      struct bound_box *box)
 
905
{
 
906
    int ret;
 
907
    struct boxid box_id;
 
908
    struct P_area *Area;
 
909
    struct P_line *Line;
 
910
    struct P_node *Node;
 
911
    struct P_topo_b *topo;
 
912
    static struct RTree_Rect rect;
 
913
    static int rect_init = 0;
 
914
 
 
915
    G_debug(3, "dig_find_area_box()");
 
916
 
 
917
    if (!rect_init) {
 
918
        /* always 6 sides for 3D */
 
919
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
920
        rect_init = 6;
 
921
    }
 
922
 
 
923
    Area = Plus->Area[area];
 
924
    Line = Plus->Line[abs(Area->lines[0])];
 
925
    topo = (struct P_topo_b *)Line->topo;
 
926
    Node = Plus->Node[topo->N1];
 
927
 
 
928
    rect.boundary[0] = Node->x;
 
929
    rect.boundary[1] = Node->y;
 
930
    rect.boundary[2] = Node->z;
 
931
    rect.boundary[3] = Node->x;
 
932
    rect.boundary[4] = Node->y;
 
933
    rect.boundary[5] = Node->z;
 
934
    
 
935
    box_id.id = area;
 
936
    box_id.box = box;
 
937
 
 
938
    if (Plus->Spidx_new)
 
939
        ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id);
 
940
    else
 
941
        ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
 
942
 
 
943
    return ret;
 
944
}
 
945
 
 
946
/*! 
 
947
   \brief Select isles with boxes by box 
503
948
 
504
949
   \param Plus pointer to Plus_head structure
505
950
   \param box bounding box
506
 
   \param list list of selected lines
 
951
   \param list boxlist of selected isles
507
952
 
508
953
   \return number of selected isles
509
954
 */
510
955
int
511
 
dig_select_isles(struct Plus_head *Plus, BOUND_BOX * box, struct ilist *list)
 
956
dig_select_isles(struct Plus_head *Plus, const struct bound_box * box,
 
957
                 struct boxlist *list)
512
958
{
513
 
    struct Rect rect;
514
 
 
515
 
    G_debug(3, "dig_select_isles()");
 
959
    static struct RTree_Rect rect;
 
960
    static int rect_init = 0;
 
961
 
 
962
    if (!rect_init) {
 
963
        /* always 6 sides for 3D */
 
964
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
965
        rect_init = 6;
 
966
    }
 
967
 
 
968
    G_debug(3, "dig_select_areas_with_box()");
516
969
 
517
970
    list->n_values = 0;
518
971
 
522
975
    rect.boundary[3] = box->E;
523
976
    rect.boundary[4] = box->N;
524
977
    rect.boundary[5] = box->T;
525
 
    RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item, list);
 
978
 
 
979
    if (Plus->Spidx_new)
 
980
        RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list);
 
981
    else
 
982
        rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list, Plus);
526
983
 
527
984
    return (list->n_values);
528
985
}
 
986
 
 
987
/*!
 
988
   \brief Find box for isle
 
989
 
 
990
   \param Plus pointer to Plus_head structure
 
991
   \param isle isle id
 
992
   \param[out] box bounding box
 
993
 
 
994
   \return > 0 bounding box for isle found
 
995
   \return 0 not found
 
996
 */
 
997
int dig_find_isle_box(struct Plus_head *Plus, int isle,
 
998
                      struct bound_box *box)
 
999
{
 
1000
    int ret;
 
1001
    struct boxid box_id;
 
1002
    struct P_isle *Isle;
 
1003
    struct P_line *Line;
 
1004
    struct P_node *Node;
 
1005
    struct P_topo_b *topo;
 
1006
    static struct RTree_Rect rect;
 
1007
    static int rect_init = 0;
 
1008
 
 
1009
    G_debug(3, "dig_find_isle_box()");
 
1010
 
 
1011
    if (!rect_init) {
 
1012
        /* always 6 sides for 3D */
 
1013
        rect.boundary = G_malloc(6 * sizeof(RectReal));
 
1014
        rect_init = 6;
 
1015
    }
 
1016
 
 
1017
    Isle = Plus->Isle[isle];
 
1018
    Line = Plus->Line[abs(Isle->lines[0])];
 
1019
    topo = (struct P_topo_b *)Line->topo;
 
1020
    Node = Plus->Node[topo->N1];
 
1021
 
 
1022
    rect.boundary[0] = Node->x;
 
1023
    rect.boundary[1] = Node->y;
 
1024
    rect.boundary[2] = Node->z;
 
1025
    rect.boundary[3] = Node->x;
 
1026
    rect.boundary[4] = Node->y;
 
1027
    rect.boundary[5] = Node->z;
 
1028
    
 
1029
    box_id.id = isle;
 
1030
    box_id.box = box;
 
1031
 
 
1032
    if (Plus->Spidx_new)
 
1033
        ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id);
 
1034
    else
 
1035
        ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
 
1036
 
 
1037
    return ret;
 
1038
}