GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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);
118  if (Fi == NULL)
119  G_fatal_error(_("Database connection not defined for layer %d"), layer);
120 
122  if (driver == NULL)
123  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
124  Fi->database, Fi->driver);
125 
126  nlines = Vect_get_num_lines(In);
127  nnodes = Vect_get_num_nodes(In);
128  for (i = 1; i <= nnodes; i++)
129  node_costs[i] = 0;
130 
131  db_CatValArray_init(&vals);
132  int nvals =
133  db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals);
134 
137 
138  if (nvals == -1)
139  return 0;
140 
141  Cats = Vect_new_cats_struct();
142  Points = Vect_new_line_struct();
143  for (i = 1; i <= nlines; i++) {
144  int type = Vect_read_line(In, Points, Cats, i);
145 
146  if (type == GV_POINT) {
147  int node, cat;
148  double value;
149 
150  if (!Vect_cat_get(Cats, layer, &cat))
151  continue;
152  Vect_get_line_nodes(In, i, &node, NULL);
153  if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK) {
154  if (value < 0)
155  node_costs[node] = -1;
156  else
157  node_costs[node] = value * In->dgraph.cost_multip;
158  }
159  }
160  }
161 
163  Vect_destroy_line_struct(Points);
164  db_CatValArray_free(&vals);
165  return 1;
166 }
167 
168 /*!
169  \brief Get list of nodes from varray
170 
171  Returns the list of all nodes on features selected by varray.
172  nodes_to_features contains the index of a feature adjacent to each
173  node or -1 if no such feature specified by varray
174  exists. Nodes_to_features might be NULL, in which case it is left
175  unitialised. Nodes_to_features will be wrong if several lines connect
176  to the same node.
177 
178  \param map pointer to Map_info structure
179  \param varray pointer to varray structure
180  \param[out] nodes list of node ids
181  \param[out] nodes_to_features maps nodes to features
182  */
183 void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray,
184  struct ilist *nodes, int *nodes_to_features)
185 {
186  int nlines, nnodes, i;
187  struct line_pnts *Points = Vect_new_line_struct();
188 
189  nlines = Vect_get_num_lines(map);
190  nnodes = Vect_get_num_nodes(map);
191  if (nodes_to_features)
192  for (i = 1; i <= nnodes; i++)
193  nodes_to_features[i] = -1;
194 
195  for (i = 1; i <= nlines; i++) {
196  if (varray->c[i]) {
197  int type = Vect_read_line(map, Points, NULL, i);
198 
199  if (type == GV_POINT) {
200  int node;
201 
202  node = Vect_find_node(map, Points->x[0], Points->y[0],
203  Points->z[0], 0, 0);
204  if (node) {
205  Vect_list_append(nodes, node);
206  if (nodes_to_features)
207  nodes_to_features[node] = i;
208  }
209  else
210  G_warning(_("Point %d is not connected!"), i);
211  }
212  else {
213  int node1, node2;
214 
215  Vect_get_line_nodes(map, i, &node1, &node2);
216  Vect_list_append(nodes, node1);
217  Vect_list_append(nodes, node2);
218  if (nodes_to_features)
219  nodes_to_features[node1] = nodes_to_features[node2] = i;
220  }
221  }
222  }
223  Vect_destroy_line_struct(Points);
224 }
225 
226 /*!
227  \brief Initialize varray
228 
229  \param In pointer to Map_info structure
230  \param layer layer number
231  \param mask_type ?
232  \param where where statement
233  \param cat ?
234  \param[out] pointer to varray structure
235 
236  \return number of items set
237  \return -1 on error
238  */
239 int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
240  char *where, char *cat, struct varray **varray)
241 {
242  int n, ni;
243 
244  if (layer < 1)
245  G_fatal_error(_("'%s' must be > 0"), "layer");
246 
247  n = Vect_get_num_lines(In);
248  *varray = Vect_new_varray(n);
249  ni = 0;
250 
251  /* parse filter option and select appropriate lines */
252  if (where) {
253  if (cat)
254  G_warning(_("'where' and 'cats' parameters were supplied, cat will "
255  "be ignored"));
256  ni = Vect_set_varray_from_db(In, layer, where, mask_type, 1, *varray);
257  if (ni == -1) {
258  G_warning(_("Unable to load data from database"));
259  }
260  return ni;
261  }
262  else if (cat) {
263  ni = Vect_set_varray_from_cat_string(In, layer, cat, mask_type, 1,
264  *varray);
265  if (ni == -1) {
266  G_warning(_("Problem loading category values"));
267  }
268  return ni;
269  }
270  else { /* all features of given layer */
271  int i, cat;
272  int ltype; /* line type */
273  struct line_cats *Cats;
274 
275  Cats = Vect_new_cats_struct();
276 
277  for (i = 1; i <= n; i++) {
278  ltype = Vect_read_line(In, NULL, Cats, i);
279 
280  if (!(ltype & mask_type))
281  continue; /* is not specified type */
282 
283  if (Vect_cat_get(Cats, layer, &cat)) {
284  (*varray)->c[i] = 1;
285  ni++;
286  }
287  }
289 
290  return ni;
291  }
292 }
#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
void Vect_destroy_field_info(struct field_info *)
Free a struct field_info and all memory associated with it.
Definition: field.c:633
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:709
int n_values
Number of values in the list.
Definition: gis.h:717
int * value
Array of values.
Definition: gis.h:713
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:183
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:239
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