84
81
else if (parm.operator->answer[0] == 'r')
85
82
operator = OP_RELATE;
87
G_fatal_error(_("Unknown operator"));
84
G_fatal_error(_("Unknown operator '%s'"), parm.operator->answer);
89
87
if (operator == OP_RELATE && !parm.relate->answer) {
90
88
G_fatal_error(_("Required parameter <%s> not set"),
92
if (operator != OP_OVERLAP) {
93
G_warning(_("Operator can only be 'overlap'"));
94
operator = OP_OVERLAP;
94
97
for (iopt = 0; iopt < 2; iopt++) {
95
98
itype[iopt] = Vect_option_to_types(parm.type[iopt]);
96
ifield[iopt] = atoi(parm.field[iopt]->answer);
98
100
Vect_check_input_output_name(parm.input[iopt]->answer, parm.output->answer,
102
G_find_vector2(parm.input[iopt]->answer, NULL)) == NULL) {
103
G_fatal_error(_("Vector map <%s> not found"),
104
parm.input[iopt]->answer);
107
103
Vect_set_open_level(2);
108
Vect_open_old(&(In[iopt]), parm.input[iopt]->answer, mapset[iopt]);
105
if (Vect_open_old2(&(In[iopt]), parm.input[iopt]->answer, "",
106
parm.field[iopt]->answer) < 0)
107
G_fatal_error(_("Unable to open vector map <%s>"),
108
parm.input[iopt]->answer);
110
ifield[iopt] = Vect_get_field_number(&(In[iopt]), parm.field[iopt]->answer);
113
/* Alloc space for input lines array */
114
ALines = (int *)G_calloc(Vect_get_num_lines(&(In[0])) + 1, sizeof(int));
111
116
/* Read field info */
112
117
IFi = Vect_get_field(&(In[0]), ifield[0]);
114
APoints = Vect_new_line_struct();
115
BPoints = Vect_new_line_struct();
116
ACats = Vect_new_cats_struct();
117
BCats = Vect_new_cats_struct();
118
List = Vect_new_list();
119
TmpList = Vect_new_list();
120
BoundList = Vect_new_list();
122
119
/* Open output */
123
Vect_open_new(&Out, parm.output->answer, Vect_is_3d(&(In[0])));
120
if (Vect_open_new(&Out, parm.output->answer, Vect_is_3d(&(In[0]))) < 0)
121
G_fatal_error(_("Unable to create vector map <%s>"),
122
parm.output->answer);
124
124
Vect_set_map_name(&Out, _("Output from v.select"));
125
125
Vect_set_person(&Out, G_whoami());
126
126
Vect_copy_head_data(&(In[0]), &Out);
127
127
Vect_hist_copy(&(In[0]), &Out);
128
128
Vect_hist_command(&Out);
131
nalines = Vect_get_num_lines(&(In[0]));
130
/* Select features */
134
initGEOS(G_message, G_fatal_error);
135
GEOSGeometry *AGeom = NULL;
132
select_lines(&(In[0]), itype[0], ifield[0],
133
&(In[1]), itype[1], ifield[1],
134
flag.cat->answer ? 1 : 0, operator,
140
/* Alloc space for input lines array */
141
ALines = (int *)G_calloc(nalines + 1, sizeof(int));
143
G_message(_("Building spatial index..."));
144
Vect_build_spatial_index(&In[0]);
145
Vect_build_spatial_index(&In[1]);
147
/* Lines in A. Go through all lines and mark those that meets condition */
148
if (itype[0] & (GV_POINTS | GV_LINES)) {
149
G_message(_("Processing features..."));
151
for (aline = 1; aline <= nalines; aline++) {
154
G_debug(3, "aline = %d", aline);
155
G_percent(aline, nalines, 2); /* must be before any continue */
158
if (!flag.cat->answer && Vect_get_line_cat(&(In[0]), aline, ifield[0]) < 0) {
163
/* Read line and check type */
164
if (operator != OP_OVERLAP) {
166
AGeom = Vect_read_line_geos(&(In[0]), aline, <ype);
168
if (!(ltype & (GV_POINT | GV_LINE)))
172
G_fatal_error(_("Unable to read line id %d from vector map <%s>"),
173
aline, Vect_get_full_name(&(In[0])));
176
ltype = Vect_read_line(&(In[0]), APoints, NULL, aline);
179
if (!(ltype & itype[0]))
182
Vect_get_line_box(&(In[0]), aline, &abox);
183
abox.T = PORT_DOUBLE_MAX;
184
abox.B = -PORT_DOUBLE_MAX;
186
/* Check if this line overlaps any feature in B */
188
if (itype[1] & (GV_POINTS | GV_LINES)) {
193
Vect_select_lines_by_box(&(In[1]), &abox, itype[1], List);
194
for (i = 0; i < List->n_values; i++) {
197
bline = List->value[i];
198
G_debug(3, " bline = %d", bline);
201
if (!flag.cat->answer && Vect_get_line_cat(&(In[1]), bline, ifield[1]) < 0) {
206
if (operator != OP_OVERLAP) {
208
if(line_relate_geos(&(In[1]), AGeom,
209
bline, operator, parm.relate->answer)) {
217
Vect_read_line(&(In[1]), BPoints, NULL, bline);
219
if (Vect_line_check_intersection(APoints, BPoints, 0)) {
228
continue; /* Go to next A line */
233
if (itype[1] & GV_AREA) {
236
Vect_select_areas_by_box(&(In[1]), &abox, List);
237
for (i = 0; i < List->n_values; i++) {
240
barea = List->value[i];
241
G_debug(3, " barea = %d", barea);
243
if (Vect_get_area_cat(&(In[1]), barea, ifield[1]) < 0) {
248
if (operator != OP_OVERLAP) {
250
if(area_relate_geos(&(In[1]), AGeom,
251
barea, operator, parm.relate->answer)) {
258
if (line_overlap_area(&(In[0]), aline, &(In[1]), barea)) {
265
if (operator != OP_OVERLAP) {
267
GEOSGeom_destroy(AGeom);
275
if (itype[0] & GV_AREA) {
278
G_message(_("Processing areas..."));
280
naareas = Vect_get_num_areas(&(In[0]));
282
for (aarea = 1; aarea <= naareas; aarea++) {
285
G_percent(aarea, naareas, 2); /* must be before any continue */
287
if (Vect_get_area_cat(&(In[0]), aarea, ifield[0]) < 0) {
292
Vect_get_area_box(&(In[0]), aarea, &abox);
293
abox.T = PORT_DOUBLE_MAX;
294
abox.B = -PORT_DOUBLE_MAX;
296
if (operator != OP_OVERLAP) {
298
AGeom = Vect_read_area_geos(&(In[0]), aarea);
301
G_fatal_error(_("Unable to read area id %d from vector map <%s>"),
302
aline, Vect_get_full_name(&(In[0])));
306
if (itype[1] & (GV_POINTS | GV_LINES)) {
307
Vect_select_lines_by_box(&(In[1]), &abox, itype[1], List);
309
for (i = 0; i < List->n_values; i++) {
312
bline = List->value[i];
314
if (!flag.cat->answer && Vect_get_line_cat(&(In[1]), bline, ifield[1]) < 0) {
319
if (operator != OP_OVERLAP) {
321
if(line_relate_geos(&(In[1]), AGeom,
322
bline, operator, parm.relate->answer)) {
323
add_aarea(&(In[0]), aarea, ALines);
329
if (line_overlap_area(&(In[1]), bline, &(In[0]), aarea)) {
330
add_aarea(&(In[0]), aarea, ALines);
338
if (itype[1] & GV_AREA) {
342
/* List of areas B */
344
/* Make a list of features forming area A */
345
Vect_reset_list(List);
347
Vect_get_area_boundaries(&(In[0]), aarea, BoundList);
348
for (i = 0; i < BoundList->n_values; i++) {
349
Vect_list_append(List, abs(BoundList->value[i]));
352
naisles = Vect_get_area_num_isles(&(In[0]), aarea);
354
for (i = 0; i < naisles; i++) {
357
aisle = Vect_get_area_isle(&(In[0]), aarea, i);
359
Vect_get_isle_boundaries(&(In[0]), aisle, BoundList);
360
for (j = 0; j < BoundList->n_values; j++) {
361
Vect_list_append(List, BoundList->value[j]);
365
Vect_select_areas_by_box(&(In[1]), &abox, TmpList);
367
for (i = 0; i < List->n_values; i++) {
370
aline = abs(List->value[i]);
372
for (j = 0; j < TmpList->n_values; j++) {
373
int barea, bcentroid;
375
barea = TmpList->value[j];
376
G_debug(3, " barea = %d", barea);
378
if (Vect_get_area_cat(&(In[1]), barea, ifield[1]) < 0) {
383
/* Check if any centroid of area B is in area A.
384
* This test is important in if area B is completely within area A */
385
bcentroid = Vect_get_area_centroid(&(In[1]), barea);
386
Vect_read_line(&(In[1]), BPoints, NULL, bcentroid);
388
if (operator != OP_OVERLAP) {
390
if(area_relate_geos(&(In[1]), AGeom,
391
barea, operator, parm.relate->answer)) {
398
if (Vect_point_in_area(&(In[0]), aarea,
399
BPoints->x[0], BPoints->y[0])) {
404
/* Check intersectin of lines from List with area B */
405
if (line_overlap_area(&(In[0]), aline,
413
add_aarea(&(In[0]), aarea, ALines);
418
if (operator != OP_OVERLAP) {
420
GEOSGeom_destroy(AGeom);
427
Vect_close(&(In[1]));
138
select_lines(&(In[0]), itype[0], ifield[0],
139
&(In[1]), itype[1], ifield[1],
140
flag.cat->answer ? 1 : 0, operator,
149
native = Vect_maptype(&Out) == GV_FORMAT_NATIVE;
434
151
nfields = Vect_cidx_get_num_fields(&(In[0]));
435
152
cats = (int **)G_malloc(nfields * sizeof(int *));
436
153
ncats = (int *)G_malloc(nfields * sizeof(int));
437
154
fields = (int *)G_malloc(nfields * sizeof(int));
438
for (i = 0; i < nfields; i++) {
441
(int *)G_malloc(Vect_cidx_get_num_cats_by_index(&(In[0]), i) *
443
fields[i] = Vect_cidx_get_field_number(&(In[0]), i);
446
G_message(_("Writing selected features..."));
447
for (aline = 1; aline <= nalines; aline++) {
450
G_debug(4, "aline = %d ALines[aline] = %d", aline, ALines[aline]);
451
G_percent(aline, nalines, 2);
453
if ((!flag.reverse->answer && !(ALines[aline])) ||
454
(flag.reverse->answer && ALines[aline]))
457
atype = Vect_read_line(&(In[0]), APoints, ACats, aline);
458
Vect_write_line(&Out, atype, APoints, ACats);
460
if (!(flag.table->answer) && (IFi != NULL)) {
461
for (i = 0; i < ACats->n_cats; i++) {
464
for (j = 0; j < nfields; j++) { /* find field */
465
if (fields[j] == ACats->field[i]) {
470
cats[f][ncats[f]] = ACats->cat[i];
157
if (!flag.table->answer && !native) {
158
/* Copy attributes for OGR output */
159
Vect_copy_map_dblinks(&(In[0]), &Out, TRUE);
162
write_lines(&(In[0]), IFi, ALines,
163
&Out, flag.table->answer ? 1 : 0, flag.reverse->answer ? 1 : 0,
164
nfields, fields, ncats, cats);
476
166
/* Copy tables */
477
if (!(flag.table->answer)) {
478
int ttype, ntabs = 0;
480
G_message(_("Writing attributes..."));
482
/* Number of output tabs */
483
for (i = 0; i < Vect_get_num_dblinks(&(In[0])); i++) {
486
IFi = Vect_get_dblink(&(In[0]), i);
488
for (j = 0; j < nfields; j++) { /* find field */
489
if (fields[j] == IFi->number) {
503
for (i = 0; i < nfields; i++) {
509
/* Make a list of categories */
510
IFi = Vect_get_field(&(In[0]), fields[i]);
511
if (!IFi) { /* no table */
512
G_warning(_("Layer %d - no table"), fields[i]);
517
Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);
520
db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
522
Vect_subst_var(OFi->database, &Out),
523
OFi->table, IFi->key, cats[i],
526
if (ret == DB_FAILED) {
527
G_warning(_("Layer %d - unable to copy table"), fields[i]);
530
Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
531
IFi->key, OFi->database, OFi->driver);
536
Vect_close(&(In[0]));
167
if (!flag.table->answer && native) {
168
copy_tabs(&(In[0]), &Out,
169
nfields, fields, ncats, cats);
172
/* print info about skipped features & close input maps */
173
for (iopt = 0; iopt < 2; iopt++) {
174
if (nskipped[iopt] > 0) {
175
G_warning(_("%d features from <%s> without category skipped"),
176
nskipped[iopt], Vect_get_full_name(&(In[iopt])));
178
Vect_close(&(In[iopt]));
538
181
Vect_build(&Out);
539
182
Vect_close(&Out);
542
G_warning(_("%d features without category skipped"), nskipped);
545
184
G_done_msg(_("%d features written to output."), Vect_get_num_lines(&Out));
547
186
exit(EXIT_SUCCESS);