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