2
1
/***************************************************************
6
5
* AUTHOR(S): Radim Blazek
6
* OGR support by Martin Landa <landa.martin gmail.com>
7
* update for GRASS 7 by Markus Metz
8
9
* PURPOSE: Split lines to segments
10
* COPYRIGHT: (C) 2001 by the GRASS Development Team
11
* COPYRIGHT: (C) 2001-2014 by the GRASS Development Team
12
* This program is free software under the
13
* GNU General Public License (>=v2).
14
* Read the file COPYING that comes with GRASS
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.
17
17
**************************************************************/
18
19
#include <stdlib.h>
20
23
#include <grass/gis.h>
21
#include <grass/Vect.h>
24
#include <grass/vector.h>
22
25
#include <grass/glocale.h>
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
24
34
int main(int argc, char *argv[])
26
36
struct GModule *module;
27
struct Option *in_opt, *out_opt, *length_opt, *vertices_opt;
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;
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;
45
int line, nlines, layer, nosplit;
36
46
double length = -1;
48
double (*line_length) ();
39
51
G_gisinit(argv[0]);
41
53
module = G_define_module();
42
module->keywords = _("vector, geometry");
43
module->description = _("Split lines to shorter segments.");
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.");
45
62
in_opt = G_define_standard_option(G_OPT_V_INPUT);
64
layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
46
66
out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
47
/* layer_opt = G_define_standard_option(G_OPT_V_FIELD); */
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");
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");
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");
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");
63
96
if (G_parser(argc, argv))
64
97
exit(EXIT_FAILURE);
66
/* layer = atoi ( layer_opt->answer ); */
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"));
72
105
if (length_opt->answer) {
73
106
length = atof(length_opt->answer);
75
G_fatal_error("Length must be positive but is %g", length);
108
G_fatal_error(_("Length must be positive but is %g"), length);
110
/* convert length to meters */
111
if (strcmp(units_opt->answer, "meters") == 0)
113
else if (strcmp(units_opt->answer, "kilometers") == 0)
114
length *= FROM_KILOMETERS;
115
else if (strcmp(units_opt->answer, "feet") == 0)
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);
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;
131
line_length = Vect_line_geodesic_length;
138
line_length = Vect_line_length;
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;
148
if (strcmp(units_opt->answer, "map") == 0)
149
G_verbose_message(_("Length in map units: %g"), length);
151
G_verbose_message(_("Length in meters: %g"), length);
78
154
if (vertices_opt->answer) {
79
155
vertices = atoi(vertices_opt->answer);
81
G_fatal_error("Number of vertices must be at least 2");
157
G_fatal_error(_("Number of vertices must be at least 2"));
159
nosplit = nosplit_flag->answer;
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));
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);
166
layer = Vect_get_field_number(&In, layer_opt->answer);
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);
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);
174
Vect_copy_tables(&In, &Out, layer);
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();
96
181
nlines = Vect_get_num_lines(&In);
106
191
ltype = Vect_read_line(&In, Points, Cats, line);
193
if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
108
196
if (ltype & GV_LINES) {
109
197
if (length > 0) {
110
198
double l, from, to, step;
112
l = Vect_line_length(Points);
200
l = line_length(Points);
114
202
if (l <= length) {
115
203
Vect_write_line(&Out, ltype, Points, Cats);
208
G_debug(3, "l: %f, length: %f", l, length);
120
210
n = ceil(l / length);
212
l = Vect_line_length(Points);
217
G_debug(3, "n: %ld, step: %f", n, step);
220
Vect_reset_line(Points3);
124
222
for (i = 0; i < n; i++) {