GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
utils.c
Go to the documentation of this file.
1 /*!
2  \file vector/neta/utils.c
3 
4  \brief Network Analysis library - utils
5 
6  Utils subroutines.
7 
8  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
9 
10  This program is free software under the GNU General Public License
11  (>=v2). Read the file COPYING that comes with GRASS for details.
12 
13  \author Daniel Bundala (Google Summer of Code 2009)
14  */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <grass/gis.h>
19 #include <grass/vector.h>
20 #include <grass/glocale.h>
21 #include <grass/dbmi.h>
22 #include <grass/neta.h>
23 
24 /*!
25  \brief Writes point
26 
27  Writes GV_POINT to Out at the position of the node in <em>In</em>.
28 
29  \param In pointer to Map_info structure (input vector map)
30  \param[in,out] Out pointer to Map_info structure (output vector map)
31  \param node node id
32  \param Cats pointer to line_cats structures
33  */
34 void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
35  struct line_cats *Cats)
36 {
37  static struct line_pnts *Points;
38  double x, y, z;
39 
40  Points = Vect_new_line_struct();
41  Vect_get_node_coor(In, node, &x, &y, &z);
42  Vect_reset_line(Points);
43  Vect_append_point(Points, x, y, z);
44  Vect_write_line(Out, GV_POINT, Points, Cats);
46 }
47 
48 /* Returns the list of all points with the given category and field */
49 /*void NetA_get_points_by_category(struct Map_info *In, int field, int cat,
50  * struct ilist *point_list)
51  * {
52  * int i, nlines;
53  * struct line_cats *Cats;
54  * Cats = Vect_new_cats_struct();
55  * Vect_get_num_lines(In);
56  * for(i=1;i<=nlines;i++){
57  * int type = Vect_read_line(In, NULL, Cats, i);
58  * if(type!=GV_POINT)continue;
59  * }
60  *
61  * Vect_destroy_cats_struct(Cats);
62  * }
63  */
64 
65 /*!
66  \brief Finds node
67 
68  Find the node corresponding to each point in the point_list
69 
70  \param In pointer to Map_info structure
71  \param point_list list of points (their ids)
72  */
73 void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
74 {
75  int i, node;
76  struct line_pnts *Points = Vect_new_line_struct();
77 
78  for (i = 0; i < point_list->n_values; i++) {
79  /* Vect_get_line_nodes(In, point_list->value[i], &node, NULL); */
80  node =
81  Vect_find_node(In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
82  point_list->value[i] = node;
83  }
85 }
86 
87 /*!
88  \brief Get node cost
89 
90  For each node in the map, finds the category of the point on it (if
91  there is any) and stores the value associated with this category in
92  the array node_costs. If there is no point with a category,
93  node_costs=0.
94 
95  node_costs are multiplied by the graph's cost multiplier and
96  truncated to integers (as is done in Vect_net_build_graph)
97 
98  \param In pointer to Map_info structure
99  \param layer layer number
100  \param column name of column
101  \param[out] node_costs list of node costs
102 
103  \returns 1 on success
104  \return 0 on failure
105  */
106 int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
107  int *node_costs)
108 {
109  int i, nlines, nnodes;
110  dbCatValArray vals;
111  struct line_cats *Cats;
112  struct line_pnts *Points;
113 
114  dbDriver *driver;
115  struct field_info *Fi;
116 
117  Fi = Vect_get_field(In, layer);
119  if (driver == NULL)
120  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
121  Fi->database, Fi->driver);
122 
123  nlines = Vect_get_num_lines(In);
124  nnodes = Vect_get_num_nodes(In);
125  Cats = Vect_new_cats_struct();
126  Points = Vect_new_line_struct();
127  for (i = 1; i <= nnodes; i++)
128  node_costs[i] = 0;
129 
130  db_CatValArray_init(&vals);
131 
132  if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL,
133  &vals) == -1)
134  return 0;
135  for (i = 1; i <= nlines; i++) {
136  int type = Vect_read_line(In, Points, Cats, i);
137 
138  if (type == GV_POINT) {
139  int node, cat;
140  double value;
141 
142  if (!Vect_cat_get(Cats, layer, &cat))
143  continue;
144  Vect_get_line_nodes(In, i, &node, NULL);
145  if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK) {
146  if (value < 0)
147  node_costs[node] = -1;
148  else
149  node_costs[node] = value * In->dgraph.cost_multip;
150  }
151  }
152  }
153 
155  db_CatValArray_free(&vals);
157  return 1;
158 }
159 
160 /*!
161  \brief Get list of nodes from varray
162 
163  Returns the list of all nodes on features selected by varray.
164  nodes_to_features contains the index of a feature adjacent to each
165  node or -1 if no such feature specified by varray
166  exists. Nodes_to_features might be NULL, in which case it is left
167  unitialised. Nodes_to_features will be wrong if several lines connect
168  to the same node.
169 
170  \param map pointer to Map_info structure
171  \param varray pointer to varray structure
172  \param[out] nodes list of node ids
173  \param[out] nodes_to_features maps nodes to features
174  */
175 void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray,
176  struct ilist *nodes, int *nodes_to_features)
177 {
178  int nlines, nnodes, i;
179  struct line_pnts *Points = Vect_new_line_struct();
180 
181  nlines = Vect_get_num_lines(map);
182  nnodes = Vect_get_num_nodes(map);
183  if (nodes_to_features)
184  for (i = 1; i <= nnodes; i++)
185  nodes_to_features[i] = -1;
186 
187  for (i = 1; i <= nlines; i++) {
188  if (varray->c[i]) {
189  int type = Vect_read_line(map, Points, NULL, i);
190 
191  if (type == GV_POINT) {
192  int node;
193 
194  node = Vect_find_node(map, Points->x[0], Points->y[0],
195  Points->z[0], 0, 0);
196  if (node) {
197  Vect_list_append(nodes, node);
198  if (nodes_to_features)
199  nodes_to_features[node] = i;
200  }
201  else
202  G_warning(_("Point %d is not connected!"), i);
203  }
204  else {
205  int node1, node2;
206 
207  Vect_get_line_nodes(map, i, &node1, &node2);
208  Vect_list_append(nodes, node1);
209  Vect_list_append(nodes, node2);
210  if (nodes_to_features)
211  nodes_to_features[node1] = nodes_to_features[node2] = i;
212  }
213  }
214  }
215  Vect_destroy_line_struct(Points);
216 }
217 
218 /*!
219  \brief Initialize varray
220 
221  \param In pointer to Map_info structure
222  \param layer layer number
223  \param mask_type ?
224  \param where where statement
225  \param cat ?
226  \param[out] pointer to varray structure
227 
228  \return number of items set
229  \return -1 on error
230  */
231 int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
232  char *where, char *cat, struct varray **varray)
233 {
234  int n, ni;
235 
236  if (layer < 1)
237  G_fatal_error(_("'%s' must be > 0"), "layer");
238 
239  n = Vect_get_num_lines(In);
240  *varray = Vect_new_varray(n);
241  ni = 0;
242 
243  /* parse filter option and select appropriate lines */
244  if (where) {
245  if (cat)
246  G_warning(_("'where' and 'cats' parameters were supplied, cat will "
247  "be ignored"));
248  ni = Vect_set_varray_from_db(In, layer, where, mask_type, 1, *varray);
249  if (ni == -1) {
250  G_warning(_("Unable to load data from database"));
251  }
252  return ni;
253  }
254  else if (cat) {
255  ni = Vect_set_varray_from_cat_string(In, layer, cat, mask_type, 1,
256  *varray);
257  if (ni == -1) {
258  G_warning(_("Problem loading category values"));
259  }
260  return ni;
261  }
262  else { /* all features of given layer */
263  int i, cat;
264  int ltype; /* line type */
265  struct line_cats *Cats;
266 
267  Cats = Vect_new_cats_struct();
268 
269  for (i = 1; i <= n; i++) {
270  ltype = Vect_read_line(In, NULL, Cats, i);
271 
272  if (!(ltype & mask_type))
273  continue; /* is not specified type */
274 
275  if (Vect_cat_get(Cats, layer, &cat)) {
276  (*varray)->c[i] = 1;
277  ni++;
278  }
279  }
281 
282  return ni;
283  }
284 }
#define NULL
Definition: ccmath.h:32
#define DB_OK
Definition: dbmi.h:71
void db_CatValArray_free(dbCatValArray *)
Free allocated dbCatValArray.
Definition: value.c:373
void db_CatValArray_init(dbCatValArray *)
Initialize dbCatValArray.
Definition: value.c:361
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition: db.c:28
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition: db.c:61
int db_select_CatValArray(dbDriver *, const char *, const char *, const char *, const char *, dbCatValArray *)
Select pairs key/value to array, values are sorted by key (must be integer)
int db_CatValArray_get_value_double(dbCatValArray *, int, double *)
Find value (double) by key.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition: line.c:77
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition: level_two.c:303
int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition: level_two.c:274
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:75
int Vect_set_varray_from_db(struct Map_info *, int, const char *, int, int, struct varray *)
Set values in 'varray' to 'value' from DB (where statement)
Definition: array.c:242
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
struct varray * Vect_new_varray(int)
Create new struct varray and allocate space for given number of items.
Definition: array.c:39
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
struct field_info * Vect_get_field(struct Map_info *, int)
Get information about link to database (by layer number)
Definition: field.c:515
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
plus_t Vect_get_num_nodes(struct Map_info *)
Get number of nodes in vector map.
Definition: level_two.c:34
int Vect_set_varray_from_cat_string(struct Map_info *, int, const char *, int, int, struct varray *)
Set values in 'varray' to 'value' from category string.
Definition: array.c:79
int Vect_find_node(struct Map_info *, double, double, double, double, int)
Find the nearest node.
void Vect_reset_line(struct line_pnts *)
Reset line.
Definition: line.c:129
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition: line.c:148
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:183
const struct driver * driver
Definition: driver/init.c:25
#define _(str)
Definition: glocale.h:10
int cost_multip
Edge and node costs multiplicator.
Definition: dig_structs.h:1234
Vector map info.
Definition: dig_structs.h:1243
struct Graph_info dgraph
Graph info (built for network analysis)
Definition: dig_structs.h:1383
Definition: driver.h:21
Layer (old: field) information.
Definition: dig_structs.h:131
char * table
Name of DB table.
Definition: dig_structs.h:151
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Definition: dig_structs.h:143
char * database
Definition: dig_structs.h:147
char * key
Name of key column (usually 'cat')
Definition: dig_structs.h:155
List of integers.
Definition: gis.h:706
int n_values
Number of values in the list.
Definition: gis.h:714
int * value
Array of values.
Definition: gis.h:710
Feature category info.
Definition: dig_structs.h:1677
int * cat
Array of categories.
Definition: dig_structs.h:1685
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
double * y
Array of Y coordinates.
Definition: dig_structs.h:1659
double * x
Array of X coordinates.
Definition: dig_structs.h:1655
double * z
Array of Z coordinates.
Definition: dig_structs.h:1663
Vector array.
Definition: dig_structs.h:1751
int * c
Array.
Definition: dig_structs.h:1762
void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
Finds node.
Definition: utils.c:73
void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node, struct line_cats *Cats)
Writes point.
Definition: utils.c:34
void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray, struct ilist *nodes, int *nodes_to_features)
Get list of nodes from varray.
Definition: utils.c:175
int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type, char *where, char *cat, struct varray **varray)
Initialize varray.
Definition: utils.c:231
int NetA_get_node_costs(struct Map_info *In, int layer, char *column, int *node_costs)
Get node cost.
Definition: utils.c:106
#define x