1
2 /****************************************************************
3 *
4 * MODULE: v.hull
5 *
6 * AUTHOR(S): Andrea Aime <aaime@libero.it>
7 * Updated 19 Dec 2003, Markus Neteler to 5.7
8 * Last updated 16 jan 2007, Benjamin Ducke to support 3D hull creation
9 * OGR support by Martin Landa <landa.martin gmail.com> (2009)
10 *
11 * PURPOSE: Creates the convex hull surrounding a vector points.
12 *
13 * COPYRIGHT: (C) 2001-2010 by the GRASS Development Team
14 *
15 * This program is free software under the GNU General
16 * Public License (>=v2). Read the file COPYING that
17 * comes with GRASS for details.
18 *
19 ****************************************************************/
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <assert.h>
24
25 #include <grass/gis.h>
26 #include <grass/vector.h>
27 #include <grass/glocale.h>
28
29 #include "hull.h"
30
main(int argc,char ** argv)31 int main(int argc, char **argv)
32 {
33 struct GModule *module;
34 struct Option *input, *output, *field, *cats_opt, *where_opt;
35 struct Flag *region_flag, *flat;
36 struct Cell_head window;
37 int layer;
38 struct cat_list *cat_list = NULL;
39
40 char *sitefile;
41
42 struct Map_info Map;
43 struct Point *points; /* point loaded from site file */
44 int *hull; /* index of points located on the convex hull */
45 int numSitePoints, numHullPoints;
46
47 int MODE2D;
48
49 G_gisinit(argv[0]);
50
51 module = G_define_module();
52 G_add_keyword(_("vector"));
53 G_add_keyword(_("geometry"));
54 G_add_keyword(_("3D"));
55 module->description =
56 _("Produces a 2D/3D convex hull for a given vector map.");
57
58 input = G_define_standard_option(G_OPT_V_INPUT);
59
60 field = G_define_standard_option(G_OPT_V_FIELD_ALL);
61
62 output = G_define_standard_option(G_OPT_V_OUTPUT);
63
64 cats_opt = G_define_standard_option(G_OPT_V_CATS);
65
66 where_opt = G_define_standard_option(G_OPT_DB_WHERE);
67
68 region_flag = G_define_flag();
69 region_flag->key = 'r';
70 region_flag->description = _("Limit to current region");
71
72 flat = G_define_flag();
73 flat->key = 'f';
74 flat->description =
75 _("Create a 'flat' 2D hull even if the input is 3D points");
76
77 if (G_parser(argc, argv))
78 exit(EXIT_FAILURE);
79
80 sitefile = input->answer;
81
82 Vect_check_input_output_name(input->answer, output->answer,
83 G_FATAL_EXIT);
84
85 Vect_set_open_level(1);
86 if (Vect_open_old2(&Map, sitefile, "", field->answer) < 0)
87 G_fatal_error(_("Unable to open vector map <%s>"), sitefile);
88
89 layer = Vect_get_field_number(&Map, field->answer);
90
91 if (layer > 0)
92 cat_list = Vect_cats_set_constraint(&Map, layer, where_opt->answer,
93 cats_opt->answer);
94
95 /* load site coordinates */
96 G_get_window(&window);
97 numSitePoints = loadSiteCoordinates(&Map, &points, region_flag->answer, &window,
98 layer, cat_list);
99 if (numSitePoints < 0)
100 G_fatal_error(_("Error loading vector points from <%s>"), sitefile);
101
102 if (numSitePoints < 3)
103 G_fatal_error(_("Convex hull calculation requires at least three points (%d found)"), numSitePoints);
104
105 G_verbose_message(_("%d points read from vector map <%s>"), numSitePoints, sitefile);
106
107 /* create a 2D or a 3D hull? */
108 MODE2D = 1;
109 if (Vect_is_3d(&Map)) {
110 MODE2D = 0;
111 }
112 if (flat->answer) {
113 MODE2D = 1;
114 }
115
116 /* close input vector */
117 Vect_close(&Map);
118
119 /* create output vector map */
120 if (0 > Vect_open_new(&Map, output->answer, MODE2D ? WITHOUT_Z : WITH_Z)) {
121 G_fatal_error(_("Unable to create vector map <%s>"), output->answer);
122 }
123
124 Vect_hist_command(&Map);
125
126 if (MODE2D) {
127 /* compute convex hull */
128 numHullPoints = convexHull(points, numSitePoints, &hull);
129
130 /* output vector map */
131 outputHull(&Map, points, hull, numHullPoints);
132 }
133 else {
134 /* this does everything for the 3D hull including vector map creation */
135 convexHull3d(points, numSitePoints, &Map);
136 }
137
138 /* clean up and bye bye */
139 Vect_build(&Map);
140 Vect_close(&Map);
141
142 exit(EXIT_SUCCESS);
143 }
144