source: grass/trunk/vector/v.select/main.c

Last change on this file was 74205, checked in by mmetz, 5 years ago

v.select: free memory before building topology for output vector

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id
  • Property svn:mime-type set to text/x-csrc
File size: 6.3 KB
Line 
1
2/****************************************************************************
3 *
4 * MODULE: v.select
5 * AUTHOR(S): Radim Blazek <radim.blazek gmail.com> (original contributor)
6 * Glynn Clements <glynn gclements.plus.com>
7 * Markus Neteler <neteler itc.it>
8 * Martin Landa <landa.martin gmail.com> (GEOS support)
9 * Huidae Cho <grass4u gmail.com> (reverse flag fix)
10 * PURPOSE: Select features from one map by features in another map.
11 * COPYRIGHT: (C) 2003-2017, 2019 by the GRASS Development Team
12 *
13 * This program is free software under the GNU General
14 * Public License (>=v2). Read the file COPYING that
15 * comes with GRASS for details.
16 *
17 *****************************************************************************/
18
19#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
22
23#include <grass/gis.h>
24#include <grass/vector.h>
25#include <grass/glocale.h>
26
27#include "proto.h"
28
29int main(int argc, char *argv[])
30{
31 int iopt;
32 int operator;
33 int nskipped[2], native, nfound;
34 int itype[2], ifield[2];
35
36 int *ALines; /* List of lines: 0 do not output, 1 - write to output */
37 int *AAreas; /* List of areas: 0 do not output, 1 - write area boundaries to output */
38 int **cats, *ncats, *fields, nfields;
39
40 struct GModule *module;
41 struct GParm parm;
42 struct GFlag flag;
43 struct Map_info In[2], Out;
44 struct field_info *IFi;
45 int nlines, nareas;
46
47 G_gisinit(argv[0]);
48
49 module = G_define_module();
50 G_add_keyword(_("vector"));
51 G_add_keyword(_("geometry"));
52 G_add_keyword(_("spatial query"));
53 module->description =
54 _("Selects features from vector map (A) by features from other vector map (B).");
55
56 parse_options(&parm, &flag);
57
58 if (G_parser(argc, argv))
59 exit(EXIT_FAILURE);
60
61 if (parm.operator->answer[0] == 'e')
62 operator = OP_EQUALS;
63 else if (parm.operator->answer[0] == 'd') {
64 /* operator = OP_DISJOINT; */
65 operator = OP_INTERSECTS;
66 flag.reverse->answer = YES;
67 }
68 else if (parm.operator->answer[0] == 'i')
69 operator = OP_INTERSECTS;
70 else if (parm.operator->answer[0] == 't')
71 operator = OP_TOUCHES;
72 else if (parm.operator->answer[0] == 'c' && parm.operator->answer[1] == 'r')
73 operator = OP_CROSSES;
74 else if (parm.operator->answer[0] == 'w')
75 operator = OP_WITHIN;
76 else if (parm.operator->answer[0] == 'c' && parm.operator->answer[1] == 'o')
77 operator = OP_CONTAINS;
78 else if (parm.operator->answer[0] == 'o') {
79 if (strcmp(parm.operator->answer, "overlaps") == 0)
80 operator = OP_OVERLAPS;
81 else
82 operator = OP_OVERLAP;
83 }
84 else if (parm.operator->answer[0] == 'r')
85 operator = OP_RELATE;
86 else
87 G_fatal_error(_("Unknown operator '%s'"), parm.operator->answer);
88
89#ifdef HAVE_GEOS
90 if (operator == OP_RELATE && !parm.relate->answer) {
91 G_fatal_error(_("Required parameter <%s> not set"),
92 parm.relate->key);
93 }
94#else
95 if (operator != OP_OVERLAP) {
96 G_warning(_("Operator can only be 'overlap'"));
97 operator = OP_OVERLAP;
98 }
99#endif
100 for (iopt = 0; iopt < 2; iopt++) {
101 itype[iopt] = Vect_option_to_types(parm.type[iopt]);
102
103 Vect_check_input_output_name(parm.input[iopt]->answer, parm.output->answer,
104 G_FATAL_EXIT);
105
106 Vect_set_open_level(2);
107
108 if (Vect_open_old2(&(In[iopt]), parm.input[iopt]->answer, "",
109 parm.field[iopt]->answer) < 0)
110 G_fatal_error(_("Unable to open vector map <%s>"),
111 parm.input[iopt]->answer);
112
113 ifield[iopt] = Vect_get_field_number(&(In[iopt]), parm.field[iopt]->answer);
114 }
115
116 /* Alloc space for input lines array */
117 nlines = Vect_get_num_lines(&(In[0]));
118 nareas = Vect_get_num_areas(&(In[0]));
119
120 ALines = (int *)G_calloc(nlines + 1, sizeof(int));
121 AAreas = (int *)G_calloc(nareas + 1, sizeof(int));
122
123 /* Read field info */
124 IFi = Vect_get_field(&(In[0]), ifield[0]);
125
126 /* Select features */
127#ifdef HAVE_GEOS
128 nfound = select_lines(&(In[0]), itype[0], ifield[0],
129 &(In[1]), itype[1], ifield[1],
130 flag.cat->answer ? 1 : 0, operator,
131 parm.relate->answer,
132 ALines, AAreas, nskipped);
133#else
134 nfound = select_lines(&(In[0]), itype[0], ifield[0],
135 &(In[1]), itype[1], ifield[1],
136 flag.cat->answer ? 1 : 0, operator,
137 NULL,
138 ALines, AAreas, nskipped);
139#endif
140
141#ifdef HAVE_GEOS
142 finishGEOS();
143#endif
144
145 if (!flag.reverse->answer) {
146 G_free(AAreas);
147 AAreas = NULL;
148 }
149
150
151 if ((!flag.reverse->answer && nfound > 0) ||
152 (flag.reverse->answer && nlines + nareas - nfound > 0)) {
153 /* Open output */
154 if (Vect_open_new(&Out, parm.output->answer, Vect_is_3d(&(In[0]))) < 0)
155 G_fatal_error(_("Unable to create vector map <%s>"),
156 parm.output->answer);
157
158 Vect_set_map_name(&Out, _("Output from v.select"));
159 Vect_set_person(&Out, G_whoami());
160 Vect_copy_head_data(&(In[0]), &Out);
161 Vect_hist_copy(&(In[0]), &Out);
162 Vect_hist_command(&Out);
163
164 native = Vect_maptype(&Out) == GV_FORMAT_NATIVE;
165
166 nfields = Vect_cidx_get_num_fields(&(In[0]));
167 cats = (int **)G_malloc(nfields * sizeof(int *));
168 ncats = (int *)G_malloc(nfields * sizeof(int));
169 fields = (int *)G_malloc(nfields * sizeof(int));
170
171 /* Write lines */
172 if (!flag.table->answer && !native) {
173 /* Copy attributes for OGR output */
174 Vect_copy_map_dblinks(&(In[0]), &Out, TRUE);
175 }
176
177 write_lines(&(In[0]), IFi, ALines, AAreas,
178 &Out, flag.table->answer ? 1 : 0, flag.reverse->answer ? 1 : 0,
179 nfields, fields, ncats, cats);
180
181 /* Copy tables */
182 if (!flag.table->answer && native) {
183 copy_tabs(&(In[0]), &Out,
184 nfields, fields, ncats, cats);
185 }
186
187 /* print info about skipped features & close input maps */
188 for (iopt = 0; iopt < 2; iopt++) {
189 if (nskipped[iopt] > 0) {
190 G_warning(_("%d features from <%s> without category skipped"),
191 nskipped[iopt], Vect_get_full_name(&(In[iopt])));
192 }
193 Vect_set_release_support(&In[iopt]);
194 Vect_close(&(In[iopt]));
195 }
196
197 Vect_build(&Out);
198 nfound = Vect_get_num_lines(&Out);
199 Vect_set_release_support(&Out);
200 Vect_close(&Out);
201
202 G_done_msg(_("%d features written to output."), nfound);
203 }
204 else {
205 Vect_set_release_support(&In[0]);
206 Vect_set_release_support(&In[1]);
207 Vect_close(&In[0]);
208 Vect_close(&In[1]);
209 G_done_msg(_("No features found !"));
210 }
211
212 exit(EXIT_SUCCESS);
213}
Note: See TracBrowser for help on using the repository browser.