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

« back to all changes in this revision

Viewing changes to vector/v.split/main.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
1
/***************************************************************
3
2
 *
4
3
 * MODULE:       v.split
5
4
 * 
6
5
 * AUTHOR(S):    Radim Blazek
7
 
 *               
 
6
 *               OGR support by Martin Landa <landa.martin gmail.com>
 
7
 *               update for GRASS 7 by Markus Metz
 
8
 *
8
9
 * PURPOSE:      Split lines to segments
9
10
 *               
10
 
 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
 
11
 * COPYRIGHT:    (C) 2001-2014 by the GRASS Development Team
11
12
 *
12
 
 *               This program is free software under the 
13
 
 *               GNU General Public License (>=v2). 
14
 
 *               Read the file COPYING that comes with GRASS
15
 
 *               for details.
 
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
16
 *
17
17
 **************************************************************/
 
18
 
18
19
#include <stdlib.h>
19
20
#include <math.h>
 
21
#include <string.h>
 
22
 
20
23
#include <grass/gis.h>
21
 
#include <grass/Vect.h>
 
24
#include <grass/vector.h>
22
25
#include <grass/glocale.h>
23
26
 
 
27
#define FROM_KILOMETERS  1000.0
 
28
#define FROM_FEET        0.3048
 
29
#define FROM_SFEET       1200.0 / 3937.0
 
30
#define FROM_MILES       1609.344
 
31
#define FROM_NAUTMILES   1852.0
 
32
 
 
33
 
24
34
int main(int argc, char *argv[])
25
35
{
26
36
    struct GModule *module;
27
 
    struct Option *in_opt, *out_opt, *length_opt, *vertices_opt;
28
 
 
29
 
    /* struct Option *layer_opt; */
 
37
    struct Option *in_opt, *layer_opt, *out_opt, *length_opt,
 
38
                  *units_opt, *vertices_opt;
 
39
    struct Flag *nosplit_flag;
 
40
    
30
41
    struct Map_info In, Out;
31
 
    struct line_pnts *Points, *Points2;
 
42
    struct line_pnts *Points, *Points2, *Points3;
32
43
    struct line_cats *Cats;
33
44
 
34
 
    /* int    layer; */
35
 
    int line, nlines;
 
45
    int line, nlines, layer, nosplit;
36
46
    double length = -1;
37
47
    int vertices = 0;
 
48
    double (*line_length) ();
 
49
    int geodesic = 0;
38
50
 
39
51
    G_gisinit(argv[0]);
40
52
 
41
53
    module = G_define_module();
42
 
    module->keywords = _("vector, geometry");
43
 
    module->description = _("Split lines to shorter segments.");
44
 
 
 
54
    G_add_keyword(_("vector"));
 
55
    G_add_keyword(_("geometry"));
 
56
    G_add_keyword(_("densification"));
 
57
    G_add_keyword(_("node"));
 
58
    G_add_keyword(_("segment"));
 
59
    G_add_keyword(_("vertex"));
 
60
    module->description = _("Splits vector lines to shorter segments.");
 
61
    
45
62
    in_opt = G_define_standard_option(G_OPT_V_INPUT);
 
63
 
 
64
    layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
 
65
 
46
66
    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
47
 
    /* layer_opt = G_define_standard_option(G_OPT_V_FIELD); */
48
 
 
 
67
    
49
68
    length_opt = G_define_option();
50
69
    length_opt->key = "length";
51
70
    length_opt->type = TYPE_DOUBLE;
53
72
    length_opt->multiple = NO;
54
73
    length_opt->description = _("Maximum segment length");
55
74
 
 
75
    units_opt = G_define_option();
 
76
    units_opt->key = "units";
 
77
    units_opt->type = TYPE_STRING;
 
78
    units_opt->required = NO;
 
79
    units_opt->multiple = NO;
 
80
    units_opt->options = "map,meters,kilometers,feet,surveyfeet,miles,nautmiles";
 
81
    units_opt->answer = "map";
 
82
    units_opt->description = _("Length units");
 
83
    
56
84
    vertices_opt = G_define_option();
57
85
    vertices_opt->key = "vertices";
58
86
    vertices_opt->type = TYPE_INTEGER;
60
88
    vertices_opt->multiple = NO;
61
89
    vertices_opt->description = _("Maximum number of vertices in segment");
62
90
 
 
91
    nosplit_flag = G_define_flag();
 
92
    nosplit_flag->key = 'n';
 
93
    nosplit_flag->label = _("Add new vertices, but do not split");
 
94
    nosplit_flag->description = _("Applies only to 'length' option");
 
95
    
63
96
    if (G_parser(argc, argv))
64
97
        exit(EXIT_FAILURE);
65
 
 
66
 
    /* layer = atoi ( layer_opt->answer ); */
67
 
 
 
98
    
68
99
    if ((length_opt->answer && vertices_opt->answer) ||
69
100
        !(length_opt->answer || vertices_opt->answer))
70
 
        G_fatal_error("Use either length or vertices");
 
101
        G_fatal_error(_("Use either length or vertices"));
 
102
 
 
103
    line_length = NULL;
71
104
 
72
105
    if (length_opt->answer) {
73
106
        length = atof(length_opt->answer);
74
107
        if (length <= 0)
75
 
            G_fatal_error("Length must be positive but is %g", length);
 
108
            G_fatal_error(_("Length must be positive but is %g"), length);
 
109
 
 
110
        /* convert length to meters */
 
111
        if (strcmp(units_opt->answer, "meters") == 0)
 
112
            /* do nothing */ ;
 
113
        else if (strcmp(units_opt->answer, "kilometers") == 0)
 
114
            length *= FROM_KILOMETERS;
 
115
        else if (strcmp(units_opt->answer, "feet") == 0)
 
116
            length *= FROM_FEET;
 
117
        else if (strcmp(units_opt->answer, "surveyfeet") == 0)
 
118
            length *= FROM_SFEET;
 
119
        else if (strcmp(units_opt->answer, "miles") == 0)
 
120
            length *= FROM_MILES;
 
121
        else if (strcmp(units_opt->answer, "nautmiles") == 0)
 
122
            length *= FROM_NAUTMILES;
 
123
        else if (strcmp(units_opt->answer, "map") != 0)
 
124
            G_fatal_error(_("Unknown unit %s"), units_opt->answer); 
 
125
 
 
126
        /* set line length function */
 
127
        if (G_projection() == PROJECTION_LL) {
 
128
            if (strcmp(units_opt->answer, "map") == 0)
 
129
                line_length = Vect_line_length;
 
130
            else {
 
131
                line_length = Vect_line_geodesic_length;
 
132
                geodesic = 1;
 
133
            }
 
134
        }
 
135
        else {
 
136
            double factor;
 
137
            
 
138
            line_length = Vect_line_length;
 
139
            
 
140
            /* convert length to map units */
 
141
            if ((factor = G_database_units_to_meters_factor()) == 0)
 
142
                G_fatal_error(_("Can not get projection units"));
 
143
            else if (strcmp(units_opt->answer, "map") != 0) {
 
144
                /* meters to units */
 
145
                length = length / factor;
 
146
            }
 
147
        }
 
148
        if (strcmp(units_opt->answer, "map") == 0)
 
149
            G_verbose_message(_("Length in map units: %g"), length);
 
150
        else
 
151
            G_verbose_message(_("Length in meters: %g"), length);
76
152
    }
77
153
 
78
154
    if (vertices_opt->answer) {
79
155
        vertices = atoi(vertices_opt->answer);
80
156
        if (vertices < 2)
81
 
            G_fatal_error("Number of vertices must be at least 2");
 
157
            G_fatal_error(_("Number of vertices must be at least 2"));
82
158
    }
83
 
 
 
159
    nosplit = nosplit_flag->answer;
 
160
    
84
161
    Vect_set_open_level(2);
85
 
    Vect_open_old(&In, in_opt->answer, "");
86
 
    Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In));
 
162
 
 
163
    if (Vect_open_old2(&In, in_opt->answer, "", layer_opt->answer) < 0)
 
164
        G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);
 
165
 
 
166
    layer = Vect_get_field_number(&In, layer_opt->answer);
 
167
    
 
168
    if (Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In)) < 0)
 
169
        G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
 
170
    
87
171
    Vect_copy_head_data(&In, &Out);
88
172
    Vect_hist_copy(&In, &Out);
89
173
    Vect_hist_command(&Out);
90
 
    Vect_copy_tables(&In, &Out, -1);
91
 
 
 
174
    Vect_copy_tables(&In, &Out, layer);
 
175
    
92
176
    Points = Vect_new_line_struct();
93
177
    Points2 = Vect_new_line_struct();
 
178
    Points3 = Vect_new_line_struct();
94
179
    Cats = Vect_new_cats_struct();
95
180
 
96
181
    nlines = Vect_get_num_lines(&In);
105
190
 
106
191
        ltype = Vect_read_line(&In, Points, Cats, line);
107
192
 
 
193
        if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
 
194
          continue;
 
195
 
108
196
        if (ltype & GV_LINES) {
109
197
            if (length > 0) {
110
198
                double l, from, to, step;
111
199
 
112
 
                l = Vect_line_length(Points);
 
200
                l = line_length(Points);
113
201
 
114
202
                if (l <= length) {
115
203
                    Vect_write_line(&Out, ltype, Points, Cats);
116
204
                }
117
205
                else {
118
 
                    int n, i;
 
206
                    long n, i;
 
207
 
 
208
                    G_debug(3, "l: %f, length: %f", l, length);
119
209
 
120
210
                    n = ceil(l / length);
 
211
                    if (geodesic)
 
212
                        l = Vect_line_length(Points);
 
213
 
121
214
                    step = l / n;
122
215
                    from = 0.;
 
216
                    
 
217
                    G_debug(3, "n: %ld, step: %f", n, step);
 
218
                    
 
219
                    if (nosplit)
 
220
                        Vect_reset_line(Points3);
123
221
 
124
222
                    for (i = 0; i < n; i++) {
125
223
                        int ret;
134
232
 
135
233
                        ret = Vect_line_segment(Points, from, to, Points2);
136
234
                        if (ret == 0) {
137
 
                            G_warning
138
 
                                ("Cannot make line segment: %f - %f (line length = %f)",
139
 
                                 from, to, l);
 
235
                            G_warning(_("Unable to make line segment: %f - %f (line length = %f)"),
 
236
                                      from, to, l);
140
237
                            continue;
141
238
                        }
142
239
 
155
252
                                Points->z[Points->n_points - 1];
156
253
                        }
157
254
 
158
 
                        Vect_write_line(&Out, ltype, Points2, Cats);
 
255
                        if (nosplit) {
 
256
                            if (Points3->n_points > 0)
 
257
                                Points3->n_points--;
 
258
                            Vect_append_points(Points3, Points2, GV_FORWARD);
 
259
                        }
 
260
                        else
 
261
                            Vect_write_line(&Out, ltype, Points2, Cats);
159
262
 
160
263
                        /* last point */
161
264
                        x = Points2->x[Points2->n_points - 1];
164
267
 
165
268
                        from += step;
166
269
                    }
 
270
                    if (nosplit)
 
271
                        Vect_write_line(&Out, ltype, Points3, Cats);
167
272
                }
168
273
            }
169
274
            else {
170
275
                int start = 0;  /* number of coordinates written */
171
276
 
172
277
                while (start < Points->n_points - 1) {
173
 
                    int i, v;
 
278
                    int i, v = 0;
174
279
 
175
280
                    Vect_reset_line(Points2);
176
281
                    for (i = 0; i < vertices; i++) {
196
301
    Vect_close(&In);
197
302
    Vect_build(&Out);
198
303
    Vect_close(&Out);
199
 
 
200
 
    exit(0);
 
304
    
 
305
    exit(EXIT_SUCCESS);
201
306
}