1 /***************************************************************
2  *
3  * MODULE:       v.type
4  *
5  * AUTHOR(S):    Radim Blazek
6  *               OGR support by Martin Landa <landa.martin gmail.com>
7  *
8  * PURPOSE:      Feature type manipulations
9  *
10  * COPYRIGHT:    (C) 2001-2014 by the GRASS Development Team
11  *
12  *               This program is free software under the GNU General
13  *               Public License (>=v2).  Read the file COPYING that
14  *               comes with GRASS for details.
15  *
16  **************************************************************/
17 
18 #include <string.h>
19 #include <stdlib.h>
20 #include <grass/gis.h>
21 #include <grass/vector.h>
22 #include <grass/glocale.h>
23 
main(int argc,char * argv[])24 int main(int argc, char *argv[])
25 {
26     struct Map_info In, Out;
27     static struct line_pnts *Points;
28     struct line_cats *Cats;
29     int type, field;
30     struct GModule *module;
31 
32     struct Option *in_opt, *out_opt, *to_opt, *from_opt, *field_opt;
33     int from_type, to_type;
34 
35     G_gisinit(argv[0]);
36 
37     module = G_define_module();
38     G_add_keyword(_("vector"));
39     G_add_keyword(_("geometry"));
40     G_add_keyword(_("editing"));
41     G_add_keyword(_("area"));
42     G_add_keyword(_("line"));
43     G_add_keyword(_("point"));
44     module->description = _("Changes type of vector features.");
45 
46     in_opt = G_define_standard_option(G_OPT_V_INPUT);
47 
48     field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
49 
50     out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
51 
52     from_opt = G_define_standard_option(G_OPT_V_TYPE);
53     from_opt->key = "from_type";
54     from_opt->options = "point,line,boundary,centroid,face,kernel";
55     from_opt->required = YES;
56     from_opt->multiple = NO;
57     from_opt->description = _("Feature type to convert from");
58     from_opt->answer = "line";
59 
60     to_opt = G_define_standard_option(G_OPT_V_TYPE);
61     to_opt->key = "to_type";
62     to_opt->options = "point,line,boundary,centroid,face,kernel";
63     to_opt->required = YES;
64     to_opt->multiple = NO;
65     to_opt->description = _("Feature type to convert to");
66     to_opt->answer = "boundary";
67 
68     if (G_parser(argc, argv))
69 	exit(EXIT_FAILURE);
70 
71     Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT);
72 
73     switch (from_opt->answer[0]) {
74     case 'p':
75 	from_type = GV_POINT;
76 	break;
77     case 'l':
78 	from_type = GV_LINE;
79 	break;
80     case 'b':
81 	from_type = GV_BOUNDARY;
82 	break;
83     case 'c':
84 	from_type = GV_CENTROID;
85 	break;
86     case 'f':
87 	from_type = GV_FACE;
88 	break;
89     case 'k':
90 	from_type = GV_KERNEL;
91 	break;
92     }
93     switch (to_opt->answer[0]) {
94     case 'p':
95 	to_type = GV_POINT;
96 	break;
97     case 'l':
98 	to_type = GV_LINE;
99 	break;
100     case 'b':
101 	to_type = GV_BOUNDARY;
102 	break;
103     case 'c':
104 	to_type = GV_CENTROID;
105 	break;
106     case 'f':
107 	to_type = GV_FACE;
108 	break;
109     case 'k':
110 	to_type = GV_KERNEL;
111 	break;
112     }
113     /* check type compatibility */
114     if (((from_type & (GV_POINT | GV_CENTROID | GV_KERNEL)) &&
115 	 (to_type & (GV_LINE | GV_BOUNDARY | GV_FACE))
116 	) || ((from_type & (GV_LINE | GV_BOUNDARY | GV_FACE)) &&
117 	      (to_type & (GV_POINT | GV_CENTROID | GV_KERNEL))
118 	)
119 	)
120 	G_fatal_error(_("Incompatible types"));
121 
122     Vect_check_input_output_name(in_opt->answer, out_opt->answer,
123 				 G_FATAL_EXIT);
124 
125     Points = Vect_new_line_struct();
126     Cats = Vect_new_cats_struct();
127 
128     /* open input vector */
129     Vect_set_open_level(1);
130     if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < 0)
131 	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);
132 
133     field = Vect_get_field_number(&In, field_opt->answer);
134 
135     if (0 > Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In))) {
136 	Vect_close(&In);
137 	exit(EXIT_FAILURE);
138     }
139 
140     Vect_copy_head_data(&In, &Out);
141     Vect_hist_copy(&In, &Out);
142     Vect_hist_command(&Out);
143 
144     while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
145 	if (type == from_type)
146 	    type = to_type;
147 
148 	if (field != -1 && !Vect_cat_get(Cats, field, NULL))
149 	    continue;
150 
151 	Vect_write_line(&Out, type, Points, Cats);
152     }
153 
154     if (Vect_copy_tables(&In, &Out, 0))
155         G_warning(_("Failed to copy attribute table to output map"));
156 
157     Vect_build(&Out);
158     Vect_close(&Out);
159     Vect_close(&In);
160 
161     exit(EXIT_SUCCESS);
162 }
163